D3.js的Force(力导向)布局是一种基于物理模拟的算法,用于可视化复杂网络关系,它通过模拟电荷排斥力(节点间斥力)、弹簧力(连接边拉力)和碰撞检测(防止重叠),自动计算节点的位置,生成美观且易于理解的网络图。
物理模拟
算法流程
以下是一个力导向图的代码示例:
// 1. 创建SVG画布 const width = 800, height = 600; const svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); // 2. 定义数据 const nodes = [{id: "A"}, {id: "B"}, {id: "C"}]; const links = [{source: "A", target: "B"}, {source: "B", target: "C"}]; // 3. 初始化力模拟 const simulation = d3.forceSimulation(nodes) .force("link", d3.forceLink(links).id(d => d.id)) .force("charge", d3.forceManyBody().strength(-100)) .force("center", d3.forceCenter(width/2, height/2)); // 4. 绘制节点和边 const linkElements = svg.append("g") .selectAll("line") .data(links) .join("line") .attr("stroke", "#999"); const nodeElements = svg.append("g") .selectAll("circle") .data(nodes) .join("circle") .attr("r", 10) .attr("fill", "#69b3a2") .call(d3.drag() // 支持拖拽交互 .on("start", dragStart) .on("drag", dragging) .on("end", dragEnd)); // 5. 实时更新位置 simulation.on("tick", () => { linkElements .attr("x1", d => d.source.x) .attr("y1", d => d.source.y) .attr("x2", d => d.target.x) .attr("y2", d => d.target.y); nodeElements .attr("cx", d => d.x) .attr("cy", d => d.y); });
调整力参数
strength()
:控制排斥力或吸引力强度。 distance()
:设置边的理想长度。 alphaDecay()
:调节迭代速度(默认0.0228)。simulation.force("charge") .strength(-200) // 增强节点斥力 simulation.force("link") .distance(100) // 边长度调整为100像素
样式与交互
d3.zoom()
支持画布交互。性能优化
Web Workers
分离计算与渲染线程。 simulation.stop()
节省资源。节点重叠如何解决?
.force("collide", d3.forceCollide().radius(20))
如何固定节点位置?
node.fx = 100; // 固定X坐标 node.fy = 200; // 固定Y坐标 simulation.alpha(1).restart(); // 重启模拟
数据动态更新方法?
simulation.nodes(newNodes).force("link").links(newLinks)
,并重启模拟。引用说明 参考自: