D3 的全称是Data-Driven Documents,即数据驱动文档,用来做数据可视化。
选择集数据绑定以及动态绑定class
insert()
在选择集前面插入元素
append()
在选择集末尾插入元素
select()
选择所有指定元素的第一个
selectAll()
选择指定全部元素
datum()
绑定一个数据到选择集上
data()
绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定
update()
、enter()
、exit()
是 D3 中三个非常重要的概念,它处理的是当选择集和数据的数量关系不确定的情况。
update()
:对应的元素正好满足( 绑定数据数量 = 对应元素),直接操作即可,后面直接跟text()
,style()
等操作。
enter()
对应的元素不足( 绑定数据数量 > 对应元素 ),需要添加元素,使之与绑定数据的数量相等。后面通常先跟append()
操作。
exit()
对应的元素过多( 绑定数据数量 < 对应元素 ),需要删除元素,使之与绑定数据的数量相等。后面通常要跟remove()
操作。
const bindData = (root, data, tag) => (
root.append('g')
.selectAll(tag)
.data(data)
.enter()
.append(tag)
);
上述这段代码起到了绑定数据的作用,将data
绑定到root
上的所有tag
元素上,当tag
不足时添加tag
使tag
的数量与绑定data
的数量相等。
举个例子:
export const d3Connections = (svg, connections) => {
return bindData(svg, connections, 'path')
.attr('class', 'mindmap-connection');
};
将connections
绑定到svg
的path
元素上,使用mindmap-connection
覆盖原有的class
属性。这里svg
是画布,path
是svg
中的路径属性,用来绘制图形,connections
是连接的集合,并将class
绑定为mindmap-connection
对连接进行渲染。
节点拖动
export const d3Drag = (simulation, svg, nodes) => {
const dragStart = (node) => {
if (!event.active) {
simulation.alphaTarget(0.2).restart();
}
node.fx = node.x;
node.fy = node.y;
};
const dragged = (node) => {
node.fx = event.x;
node.fy = event.y;
};
const dragEnd = () => {
if (!event.active) {
simulation.alphaTarget(0);
}
};
return drag()
.on('start', dragStart)
.on('drag', dragged)
.on('end', dragEnd);
};
simulation
是绘图的模拟器,svg
是画布,nodes
是所有的节点,在之后可直接使用(node) => {}
表示对nodes
中每一个元素进行操作。
上述代码表示了拖动节点的三个过程:开始拖动、拖动、结束拖动。
node.x
与node.y
是节点当前的横纵坐标,node.fx
与node.fy
是节点固定的横纵坐标,这两个属性可以让节点固定在一个位置,即在其他节点拖动的时候位置不会改变。每次tick
结束后,节点的 node.x
会被重新设置为 node.fx
, node.y
会被重新替换为 node.fy
。这里on()
用于交互,当监听到start
事件就调用dragStart
函数,当监听到drag
事件就调用dragged
函数,当监听到end
事件就调用dragEnd
函数。