D3js之初窥

1,845 阅读3分钟

最近在做一个项目, 图表是一个比较重要的功能, 但是之前并没有接触过可视化相关的东西, 当然不可能自己造一个轮子. 社区里有很多优秀的图表库: echarts, g6, highcharts, chartjs以及d3等等. 首先我们的项目重点并不在数据呈现, 也就是highcharts和chartjs首先被排除了. 其次我每太研究过canvas, 加上我们的项目比较紧, 最终确定了使用d3.

d3的文档不算太友好 这里推荐devdocs, 搜索关键字什么的还是很方便的. d3目前的情况是v3和v4都有很多人使用, 并且官网的例子还以v3为主, 所以选3还是4也是一个令人头疼的问题. 最终秉承这喜新厌旧的原则, 我还是选择了v4.

d3和svg

可缩放矢量图形(Scalable Vector Graphics,SVG),是一种用来描述二维矢量图形的XML 标记语言。 简单地说,SVG面向图形,HTML面向文本.

总之, 我们只需要知道svg画出的图形可以直接在页面内显示就行了. 更重要的是, 不同于canvas每个变动都需要rerender, svg是基于dom的, 可以添加事件 js的动画函数也会对其生效, 对于新手可能更加友好一点,.

d3是基于svg的(v4添加了canvas支持), 所以d3有很多针对svg的操作append, attr等等, 相当一部分与svg原生方法类似.

那么, 既然svg就可以画出图表, 要d3做什么呢? d3 当然是简化svg创建图表各种繁琐的事情, 比如力导向图的碰撞检测之类.

一个简单的图表

效果如下:

image

代码如下(直接在jsbin等内可以直接运行):

var width = 300;  //画布的宽度
var height = 300;   //画布的高度

var svg = d3.select("body")     //选择文档中的body元素
    .append("svg")          //添加一个svg元素
    .attr("width", width)       //设定宽度
    .attr("height", height);    //设定高度
    
var dataset = [ 250 , 210 , 170 , 130 , 90 ];  //数据(表示矩形的宽度)

var rectHeight = 25;   //每个矩形所占的像素高度(包括空白)

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x",20)
    .attr("y",function(d,i){
         return i * rectHeight;
    })
    .attr("width",function(d){
         return d;
    })
    .attr("height",rectHeight-2)
    .attr("fill","steelblue");

作为入门示例我们不需要懂得每个方法的含义, 其实也没办法一一理解, 毕竟d3的方法实在太多了. 这么简单的图表, 无论是svg还是canvas都可以很简单的不借助任何库完成, 但是涉及到一系列强交互, 比如拖动, 力, 放大缩小, 转动视角, 编辑等等, 我相信d3还是最好的选择.

最后几句

其实选择d3的还有一个很重要的原因, 就是他与react能更好的结合, 相对于canvas类图表, 无论你代码操作粒度再细, 放在react组件里的无非就是一个canvas元素. 而svg作为dom呈现在jsx里的可操作性应该是更强的. 以后有机会的话希望能总结出一篇来.

image