前言
在大数据蓬勃发展的今天,又恰逢百年不遇的新冠疫情,数据可视化又一次出现在风口浪尖,最近项目中也经常要做各种数据可视化,现在国内的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试着做出自己的效果了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。