D3 力导向布局模块
force 模块实现了用以模拟粒子物理运动的 velocity Verlet 数值积分器。用该模块为一组 nodes 创建一个 simulation 仿真,并组合需要的 forces 力模型。然后监听 tick 事件(一个 node 布局计算的迭代称为一个 tick)来不断更新图形系统。
需要提供的数据是 nodes
和 links
,结点数组每个元素标识一个结点,包含结点的唯一 id,结点类别等信息;连接数组每个元素使用 source
和 target
描述每一条连接两个结点的信息,还可能包括连接强度等信息。
创建一个简单力导向图参考:Force-Directed Graph
js
// 核心代码
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.on("tick", () => {
// update node and link positions
})
- 输入节点数组,并为每个节点分配一个随机的
(x, y)
位置 - 遍历每个节点并应用
.force()
中指定的一系列力- Attractive forces 吸引力将节点拉在一起,如两个结点之间的连接产生的力
- Negative forces 排斥力将节点推开以避免它们坍缩,如负电荷和碰撞力
- 所有这些力共同使节点位置稍微微移,并且在每个 tick 都会进行一次计算,更新每个结点的
(x, y)
位置,监听tick
事件或在模拟结束触发的事件end
,并在回调函数中进行更新它们的布局位置.on('tick', () => ...)
或.on('end', () => ...)
- 运行预设次数的 tick 之后,将节点推到其「最佳」位置