在数据可视化领域,D3.js 是最强大的JavaScript库之一,本文将详细讲解如何使用D3.js v4版本创建交互式力导向图,帮助开发者快速实现网络关系可视化。
引入D3.js v4核心库
<script src="https://d3js.org/d3.v4.min.js"></script>
创建SVG容器
const width = 800; const height = 600; const svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height);
步骤1:初始化力模拟器
const simulation = d3.forceSimulation() .force("link", d3.forceLink().id(d => d.id)) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width/2, height/2));
步骤2:准备示例数据
const dataset = { nodes: [ { id: "A", group: 1 }, { id: "B", group: 1 }, { id: "C", group: 2 } ], links: [ { source: "A", target: "B" }, { source: "B", target: "C" } ] };
绘制连接线
const links = svg.append("g") .selectAll("line") .data(dataset.links) .enter().append("line") .attr("stroke-width", 2) .attr("stroke", "#999");
创建节点
const nodes = svg.append("g") .selectAll("circle") .data(dataset.nodes) .enter().append("circle") .attr("r", 8) .attr("fill", d => d3.schemeCategory10[d.group]);
添加交互功能
nodes.call(d3.drag() .on("start", dragStarted) .on("drag", dragged) .on("end", dragEnded));
实现节点自动布局
simulation .nodes(dataset.nodes) .on("tick", ticked); simulation.force("link") .links(dataset.links); function ticked() { links .attr("x1", d => d.source.x) .attr("y1", d => d.source.y) .attr("x2", d => d.target.x) .attr("y2", d => d.target.y); nodes .attr("cx", d => d.x) .attr("cy", d => d.y); }
节点颜色映射
使用比例尺实现动态颜色分配:
const colorScale = d3.scaleOrdinal(d3.schemeCategory10); nodes.attr("fill", d => colorScale(d.group));
动态数据更新
通过update模式实现数据刷新:
function updateData(newData) { // 更新节点 nodes = nodes.data(newData.nodes); nodes.exit().remove(); nodes = nodes.enter().append("circle").merge(nodes); // 更新力模拟 simulation.nodes(newData.nodes); simulation.alpha(0.3).restart(); }
Q1:如何固定节点位置?
d3.select(node).datum().fx = d.x; d3.select(node).datum().fy = d.y;
Q2:如何优化性能?
.force("collide", d3.forceCollide().radius(20))
simulation.alphaDecay(0.05);
本文代码实现参考自: