D3 力導向圖 (適用 v4.x / v5.x 版本)

利用 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 版本)

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *