D3.js 网络图使用力导向布局和矩形节点
Posted
技术标签:
【中文标题】D3.js 网络图使用力导向布局和矩形节点【英文标题】:D3.js network graph using force-directed layout and rectangles for nodes 【发布时间】:2015-08-12 14:46:52 【问题描述】:我正在尝试修改 Mike 的 Force-Directed Graph 示例以使用矩形而不是圆形作为节点。另外,我想要矩形内的文本。
我有正确显示文本的矩形,但是它们没有附加到链接上,并且它们不会移动。
这是一个 codepen 链接:http://codepen.io/anon/pen/gpgWaz
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d)
return Math.sqrt(d.value);
);
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("transform", function(d)
return "translate(" + d.x + "," + d.y + ")";
)
.call(force.drag);
node.append("rect")
.attr("class", "node")
.attr("width", 100)
.attr("height", 35)
.style("fill", function(d)
return color(d.group);
)
.style("stroke", "black")
.style("stroke-width", "1px");
node.append("text")
.text(function(d)
return d.name;
)
.style("font-size", "12px")
.attr("dy", "1em");
node.append("title")
.text(function(d)
return d.name;
);
force.on("tick", function()
link.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;
);
node.attr("x", function(d)
return d.x;
)
.attr("y", function(d)
return d.y;
);
);
更新
感谢Lars 的评论,以及他的codepen 现在可以使用了。
我对代码所做的更新:
-
添加由 Lars 说明的变换
将链接更改为在矩形中心连接
为矩形添加圆角
给文本一个小边距缩进
改为使用窗口宽度/高度
这是我的新代码笔:http://codepen.io/anon/pen/bdgREd
var width = window.innerWidth,
height = window.innerHeight,
nodeWidth = 100,
nodeHeight = 35;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-1500)
.linkDistance(100)
.friction(0.5)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d)
return Math.sqrt(d.value);
);
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("transform", function(d)
return "translate(" + d.x + "," + d.y + ")";
)
.call(force.drag);
node.append("rect")
.attr("class", "node")
.attr("width", nodeWidth)
.attr("height", nodeHeight)
.attr("rx", 5)
.attr("ry", 5)
.style("fill", function(d)
return color(d.group);
)
.style("stroke", "black")
.style("stroke-width", "1px");
node.append("text")
.attr("x", 5)
.attr("y", 2)
.text(function(d)
return d.name;
)
.style("font-size", "12px")
.attr("dy", "1em");
node.append("title")
.text(function(d)
return d.name;
);
force.on("tick", function()
link.attr("x1", function(d)
return d.source.x + (nodeWidth / 2);
)
.attr("y1", function(d)
return d.source.y + (nodeHeight / 2);
)
.attr("x2", function(d)
return d.target.x + (nodeWidth / 2);
)
.attr("y2", function(d)
return d.target.y + (nodeHeight / 2);
);
node.attr("transform", function(d)
return "translate(" + d.x + "," + d.y + ")";
);
);
【问题讨论】:
您需要像附加矩形时那样设置transform
属性:codepen.io/anon/pen/YXNVNY
做到了。如果您将此作为答案发布,我会接受。谢谢!
【参考方案1】:
您正在设置g
元素上的x
和y
属性来改变它们的位置——这不会做任何事情。您需要设置 transform
属性,就像您在添加 g
元素时所做的那样。所以你的 tick
处理函数将包含
node.attr("transform", function(d)
return "translate(" + d.x + "," + d.y + ")";
);
而不是
node.attr("x", function(d)
return d.x;
)
.attr("y", function(d)
return d.y;
);
完整的演示here。
【讨论】:
以上是关于D3.js 网络图使用力导向布局和矩形节点的主要内容,如果未能解决你的问题,请参考以下文章