利用 D3 力導向版型 (Force Layout) ,或稱重力場版型,繪製力導向圖: (適用 v3.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 force = d3.layout.force() .nodes(nodes) .links(links) .size([width, height]) .charge(-200) .linkDistance(70) .on("tick", ticked); var color = d3.scale.category10(); var lines = svg.selectAll(".force-line") .data(links) .enter() .append("line") .attr("class", "force-line") .attr("stroke", "#999") .attr("stroke-width", "1px"); var circles = svg.selectAll(".force-node") .data(nodes) .enter() .append("circle") .attr("class", "force-node") .attr("r", 15) .style("fill", function(d, i) { return color(i); }); var texts = svg.selectAll(".force-text") .data(nodes) .enter() .append("text") .attr("class", "force-text") .attr("x", function(d) { return d.x; }) .attr("y", function(d) { return d.y; }) .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; } ); circles.attr("cx", function (d) { return d.x; } ) .attr("cy", function (d) { return d.y; } ); texts.attr("x", function (d) { return d.x; } ) .attr("y", function (d) { return d.y; } ); } force.start();
執行結果:
D3 v3.x 的力導向圖,每次繪製出來的位置不會相同,每次重新整理可以得到相似關聯的圖,但節點位置不同。 (若有人知道如何固定,再請不吝指教) ^^
而 D3 v4.x / v5.x 之後的版本,每次出現的力導向圖節點位置不變。