前言

在大数据蓬勃发展的今天,又恰逢百年不遇的新冠疫情,数据可视化又一次出现在风口浪尖,最近项目中也经常要做各种数据可视化,现在国内的echarts发展迅速,但是傻瓜式的操作总是伴随着一些死板,并且感觉失去了很多coding的乐趣,早期项目中曾运用过d3做过一些树图,力导向图等,看了下官网目前最新都更新到了V5了,真是落伍太多了,但是基于之前的经验,也考虑重新系统梳理下d3的知识,还是先从V3入门,最后再做对比升级。总之,一图胜似千言,可视化必须认真搞起来了。

svg基础

首先了解下svg的基础,只需要知道几个基本图形对d3就足够了。

svg画布

<svg width=”500” height=”500”></svg>

line

<line x1="10" y1="10" x2="140" y2="140" stroke="black"></line>
- circle
```
<circle cx="100" cy="100" fill="blue" r="50" stroke="red" stroke-width="5"></circle>
```

g

g是group的意思,可以同时给多个svg元素添加相同的属性

<g fill="blue" stroke="red" stroke-width="5">
  <circle cx="100" cy="100" r="50"></circle>
  <circle cx="200" cy="200" r="50" ></circle>
</g>

开始d3

最简单的使用:

var p = d3.select('body').append('p').text('Our First Paragraph using D3!');
p.style({'font-size': '28px', 'color': 'blue'});

选择body元素插入p元素然后插入文字,最后style修改样式。这和jquery的用法的链式调用是相似的,基本没有门槛,直接上手就可以用了。

数据绑定

d3是用来对数据进行渲染可视化展现的,我们用一个简单的数组来展示。

const data_values = [10, 20, 30, 40, 50];
var p1 = d3.selectAll("p").data(data_values).enter().append("p").text("hello world");
p1.style({"font-size":"20px", 'color': 'blue'});

结果就是展示出五行文字‘hello world’。


这里关键的api是:

  • .data(data_values)

    读取数据,并赋给前面选择的元素,这里有五个数组就执行了五次。

  • .enter()

    enter可以说是d3魔法的精髓了,意思是根据前面的数据在父元素上增加占位符元素,具体如何增加就是后面的append操作了,也可以是insert等。

数据展示

上一节,虽然对应五个数据渲染出了五行数据,但是text()函数给的是固定文字,我们的数据并没有展示出来,需要在其中调用一个函数,每次调用数据时候可以获取其值展示出来:

var p = d3.selectAll("p").data(data_values).enter().append("p").text(function(value){ return value; });
p.style({"font-size":"20px","font-family":"arial"});

展示结果如下:

绘制SVG

上面演示了操控普通的html元素,下面就结合前面的svg基础正式用d3绘制svg了。
首先我们先创建一个宽450px高400px的svg元素:

var svg = d3.select('body').append('svg').attr({'width':450,'height':400});

attr()函数是用来设置元素属性的,跟style要区分开。
然后在svg画布上添加一个circle元素。

  svg.append('circle').attr({r: 30, cx: 50, cy: 50, fill: 'red'});

可以看到d3创建一个svg元素非常的容易。

柱状图

说到数据可视化,柱状图可以说是应用最广泛的了,每一条bar其实就是一个rect元素。我们先用d3来绘制一个bar。

  svg.append('rect').attr({x: 30, y: 30, width: 30, height:100});

这样就绘制了一个起点在(30, 30),宽30,高30的rect元素:

加个颜色:

  var bar = svg.append('rect').attr({x: 30, y: 30, width: 30, height:100});
  bar.attr('fill', 'blue');

然后像之前一样做数据绑定,渲染多个bar:

var bars = svg.selectAll("rect").data(data_values).enter().append("rect").attr("width", 25).attr("height", function(d){ return d; });

结果是这样的:

五个数据渲染出来了相应高度的bar,但是他们都重叠在一起了,因为x坐标是一样的,所以我们根据当前数据值的序号来计算x值:

bars.attr('x', function(d, i) {
    return i * 30;
});

每个bar的x坐标间隔30px,因为宽是25px,因此间距就是5px:

高度太小了,不是很好看,我们可以改变高度,都乘以5:

.attr('height', function(d) {
    return d * 5;
});

但是svg的坐标系y轴跟我们通常的习惯是相反的,因此我们再计算下y轴便宜转换为我们习惯的坐标,用容器高度减去bar的高度即可:

bars.attr('y', function(d) {
  return 400 - d * 5;
});

看起来舒服多了,再给个好看的颜色:

bars.attr('fill', 'steelblue');

这样一个最简单的柱状图就完成了,我们还可以利用d3的其他一些有趣的api来做一些可视化的重点展示,比如标识出最高值与最低值:

var max = d3.max(data_values);
var min = d3.min(data_values);
bars.filter(function(d) {
  return d === max;
}).attr('fill', 'green');
bars.filter(function(d) {
  return d === min;
}).attr('fill', 'red');

利用filter函数可以轻松的过滤出你要的选择项,进行个性化展示。

结束

这节简单介绍了d3的入门基础知识,知道了这些就可以直接看官方demo试着做出自己的效果了。


Alee
291 声望8 粉丝

既然路走偏了,那就重新开始吧。


引用和评论

0 条评论