利用 D3 力導向版型 (Force Layout) ,或稱重力場版型,繪製力導向圖: (適用 v4.x / v5.x 版本)
var width = 300; var height = 300; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var nodes = [ { name: "A" }, { name: "B" }, { name: "C" }, { name: "D" }, { name: "E" }, { name: "F" } ]; var links = [ { source: 0, target: 1 }, { source: 0, target: 2 }, { source: 0, target: 3 }, { source: 1, target: 4 }, { source: 1, target: 5 } ]; var simulation = d3.forceSimulation() .force("charge", d3.forceManyBody().strength(-200)) .force("center", d3.forceCenter(width / 2, height / 2)) .nodes(nodes) .force("link", d3.forceLink(links).distance(70)) .on("tick", ticked); var color = d3.scaleOrdinal(d3.schemeCategory10); var lines = svg.append("g").selectAll(".force-line") .data(links) .enter() .append("line") .attr("class", "force-line") .attr("stroke", "#999") .attr("stroke-width", "1px"); var nodeGroups = svg.append("g").selectAll(".force-node") .data(nodes) .enter() .append("g") .attr("class", "force-node"); var circles = nodeGroups.append("circle") .attr("class", "force-circle") .attr("r", 15) .style("fill", function(d, i) { return color(i); }); var texts = nodeGroups.append("text") .attr("class", "force-text") .attr("dy", ".33em") .attr("text-anchor", "middle") .style("fill", "#eee") .text(function(d) { return d.name; }); function ticked() { lines.attr("x1", function (d) { return d.source.x; } ) .attr("y1", function (d) { return d.source.y; } ) .attr("x2", function (d) { return d.target.x; } ) .attr("y2", function (d) { return d.target.y; } ); nodeGroups.attr("transform", function (d) {return "translate(" + d.x + ", " + d.y + ")";}); }
執行結果:
D3 v4.x / v5.x 之後的版本,每次出現的力導向圖節點位置不變。
而 D3 v3.x 的力導向圖,每次繪製出來的位置不會相同,每次重新整理可以得到相似關聯的圖,但節點位置不同。
參考文章: D3 版本力導向圖 (適用 v3.x 版本)