d3简单来说就是画图的工具,当被问到d3与其他图形可视化工具有什么不同时,我会脱口而出d3是数据驱动的,但是d3数据驱动的表现以及数据驱动带来的优势又是什么?在查阅相关资料后,做了一些总结。
首先得提到一个数据驱动编程的概念,在《Unix编程艺术》中,作者在介绍Unix设计原则时提到其中一条:把知识叠入数据以求逻辑质朴而健壮。其核心出发点时相对于程序逻辑,人类更擅长处理数据,换句话说就是数据比程序逻辑更容易驾驭,所以我们应该尽可能将设计的复杂度从程序代码转移至数据。
然而web前端,尤其是在图像处理领域,长期以来人们的关注点集中在图形渲染API,开发者只需要将数据按照接口的参数格式要求输入,就能得到整个设计好样式的图形。这样对于一些常见的交互逻辑少的图形无疑是可以的,但是对于独特的构造复杂且交互逻辑多的图形就很难去实现。那么d3是如何做的?
d3 是一个 JavaScript 函数库,并不需要通常所说的“安装”。它只有一个文件,在 HTML 中引用即可。d3不注重对图形呈现接口的封装,而是使用web标准的HTML, SVG和CSS来处理表现层。这意味着如果哪一天浏览器支持了新的图形渲染特性,那么你就可以立即用上,而不需要在代码层有什么特殊的修改。d3将重点放在了数据与图形之间的绑定上。数据一般是json格式的对象,也可以是xml;而图形不仅包括SVG对象,也可以是html对象,或者其他浏览器所支持的图形对象。而将数据与DOM节点之间的绑定就是其数据驱动的体现:在生成或更改图形时,就可以很方便的根据数据进行操作,并且当数据更改后,也能简单的更改图形。
简单举个d3画矩形图的例子:
首先是引入d3文件,这样我们才能在下面的代码中使用d3的语法;其次我们需要准备一块画布,在画布内去画图形,画布通常是“svg”标签,上图中名为svg的常量就是我们设置了宽高的画布,最后就是在画布中作画,因为要画矩形图,所以选择画布中所有的rect标签(关于标签数量问题下面会有更详细的说明),通过.data()绑定数据,然后依次增加图形的属性,一步一步地生成图片。其中function(d,i)是d3中固有的方法,参数d代表数据数组中的值,i代表数据的序列(从0开始排序)。这就是画一个简单的矩形图的大致方法,具体成品如下。
比例尺
可能你已经注意到上文中linear,其实它就是d3中所说的比例尺:把一组输入域映射到输出域的函数。映射的就是两个数据集之间元素相互对应的关系。d3中有各种比例尺函数,有连续的,有非连续的。常用的有d3.scaleLinear()线性比例尺、d3.scaleBand() 和 d3.scaleOrdinal()序数比例尺、d3.scaleQuantize()量化比例、d3.scaleTime()时间比例尺和颜色比例尺等,详细的介绍可以参照https://segmentfault.com/a/1190000011006780。
enter、exit、update概念
上文中我们选取画布中的rect元素来绑定数组,问题是我们创建了画布后里面什么东西都没有,它又是如何抓到数目与数据个数一致的rect元素的呢?其实我们可以看到在绑定数据后调用了.enter()函数,而在d3中为了解决元素与数据的数量不一致,专门有enter、exit、update的概念。 元素少于数据,是enter部分,表示即将进入的元素,即缺少的元素,用于添加;元素多于数据,是exit部分,表示即将退出的元素,用于删除;元素与数据一一对应,是 update 部分,表示已经存在的元素,用于更新。
谈一谈d3的优势:
(1)数据能够与 DOM 绑定在一起
D3 能够将数据与 DOM 绑定在一起,使得数据与图形成为一个整体,即图形中有数据、数据中有图形。那么在生成图形或更改图形时,就可以方便地根据数据进行操作,并且,当数据更改之后,也能简单地更改图形。
(2)数据转换和绘制是独立的
将数据变成图表,需要不少数学算法。很多可视化库的做法是:
提供一个函数 drawPie() ,输入数据,直接绘制出饼状图。
但 D3 的做法是:
提供一个函数 computePie(),可将数据转换成饼状图的数据,然后开发者可使用自己喜欢的方式来绘制饼状图。
虽然看起来 D3 使得问题变得麻烦了,但是在图表要求比较复杂的时候,直接绘制的饼状图往往达不到要求,细微的部分没有办法更改。而 D3 将两者分离开来,就极大地提高了自由度,以至于开发者甚至可以使用其他的图形库来显示 D3 计算的数据。
(3)代码简洁
JQuery 是网页开发中很常用的库,其中使用了链式语法,被很多人喜爱。D3 也采用了这一语法,能够一个函数套一个函数,使得代码很简洁。
(4)大量布局
饼状图、树形图、打包图、矩阵树图等等,D3 将大量复杂的算法封装成一个一个”布局“,用于转换数据。能够适用于各种图表的制作。
(5)基于SVG,缩放不会损失精度
SVG,是可缩放的矢量图形。D3 的绘制大部分是在 SVG 上绘制的,并且提供了大量的图形生成器,使得在 SVG 上生成图形变得简单。
另外,由于 SVG 是矢量图,放大缩小不会有精度损失
参考资料: