布局(Layout)可以看成是D3对图形元素的一种排布方式,在绘制柱状图时,是在横平竖直的直角坐标系下,确定矩形的左上角坐标,就可以画出随着高度变化的一系列柱子,以体现数据值的差异,而如果要画饼图呢,有一列数据[30,10,6],映射到饼图的不同楔形里,是一个个手动计算角度和初始位置么?根据图形语法,只需要将坐标系变成极坐标,一系列数据很容易对应为角度。布局和比例尺一样,也属于一种映射,能够将我们提供的数据重新映射/变换成新格式,以便于在某些更特定的图表中的使用。
饼图布局
在v3.x版本中,d3的布局在d3.layout接口下,通过d3.layout.pie()
创建一个饼状图布局,而到v5x及最新的v6之后,是d3.pie()
,不再使用d3.layout系列,在控制台输入d3.layout
是undefined。在使用饼图布局后,不需要把SVG整个画布的坐标系转成极坐标系,而是将系列数据做转换。
对于一个数组dataset = [76,37,90,60,50]
,通过arcs=d3.pie()(dataset)
转换成适合生成饼图的格式,在套上前几篇都用过的生成svg和添加形状的框架,一个饼图就诞生了。传入arcs绘制每个楔形用的是SVG的<path>
标签。
绘制饼图的具体代码如下:
1 | var dataset = [76,37,90,60,50]; //要绘制的数据 |
直接使用d3.pie()(dataset)
得到的数据序列arcs绘制的饼图是经过排序的,饼图效果是从12点钟开始第一个楔形,顺时针从大到小排列,从上图也可看出,数据的索引没变,arcs[0]
还是76,但起始角度为0的数据是90,因此可以重写一下pie函数pie = d3.pie().sort(null)
,会按照数据的顺序排列饼图的每个楔形。实际中使用排序还是没排序的效果根据需求选择。innerRadius设置为0是饼图,当其大于0可以得到环状图。outerRadius可以理解为整个图表的半径,因为生成的SVG是[600,500]像素,因此把outerRadius设置为高度的一半,绘制的饼图效果较好。
饼图还有两个实用的参数是cornerRadius和padAngle,
- cornerRadius:应用在
d3.arc()
上,设置每个楔形弧段边缘的圆角效果,类似于<rect>
标签的rx属性,rx用来绘制圆角矩形; - padAngle:应用在
d3.pie()
上,设置每个楔形排列的间隔;
调整这三个参数生成的“饼图”效果如下:
堆叠布局
用d3.stack()
将数据变成适合堆叠图的数据格式。
1 | //初始数据 |
基于这一格式的数据就可以绘制堆叠柱状图以及垂直的堆叠条形图。
直方图
将序列数据处理为适合直方图的形式用d3.bin()
。
1 | var data=[5.1, 4.9, 8.6, 6.2, 5.1, 7.1, 6.7, 6.1, 5, 5, 5.2, 7.9, 10.5, 5.9, 5.5, 5.6, 6.5, 7.7, 5.7, 6.5, 6.1, 5, 5, 5.2, 7.9,6.7]; |
力导向图
力导向(force-directed)图布局效果通过d3.forceSimulation(nodes).force()
实现,将输入的节点表和关系表转换为带坐标点方便SVG里绘制circle
和line
的数据。
1 | var data={"nodes":[{"id":"a","group":1},{"id":"b","group":1},{"id":"c","group":2}, |
弦图
弦图(Chord Diagram)用于表示一组元素之间的联系。输入的数据仍然是节点表nodes和节点间关系表links,弦图将数据节点环状分布,内部通过弦连接,弦的宽度反应连接的强度(values)。数据需要转换为一个NxN的矩阵,矩阵中的a、b、c等在弦图的外圆上用相互分隔的几段弧来表示,对应节点。节点的长度为该元素所在行的总和。
在d3中通过d3.chordDirected()(matrix)
得到需要的数据,具体代码如下,因为还需要绘制节点的排布效果,因此会调用d3.arc()
。
1 | var data={"nodes":[{"id":"a","group":1},{"id":"b","group":1},{"id":"c","group":2}, |
分层树图
要绘制思维导图等分层的树图,在d3中使用的是d3.hierarchy(data)
转换为层级数据,再通过d3.tree()(data)
建立树的节点,用svg里的<circle>
绘制节点,用<path>
绘制边,从而有流线的效果。一个绘制示例如下:
1 | var data={"name":"a","children":[{"name":"b","children":[{"name":"c","value":710}]}, |
总结
布局实现的是数据的变换,从序列数据或二维数据变换为方便绘制一些主题图的数据,例如变成饼图的每个楔形、变成直方图的分箱统计、力导向图的坐标点和连接线等。在d3的v3.x版本里,饼图、直方图等数据转换函数汇总在layout下。通过d3.layout.pie()
使用,而v5.x之后的版本没有了layout的集合,而是使用d3.pie()(data)
。本篇笔记学习和实践了饼图、堆叠柱图、直方图、力导向图、弦图及层级树图的绘制。还可以深入学习的有树状图(d3.treemap()
)、径向堆叠柱状图、汇聚气泡图(d3.pack()
)、桑吉图( d3.sankey()
)等等。