我在D3中创建一个强制定向网络,其中每个节点代表一个集合中的网页,它们之间的有向链接代表从一个网页到另一个网页的超链接。当用户在网页之间移动时,链接将添加到网络中。集合中的节点/网页数量不会发生变化。
每当添加新链接时,我重新加载网络,读取包含新旧链接和所有节点的JSON代码。目前,我正试图平静"此网络的初始加载使得节点不会在随机位置创建,从而可能创建一个网络,其中节点远离它们之前的位置。为此,我想将每个节点的初始位置设置为前一个网络中的位置。
我已通过设置节点的x和y属性来完成此操作,如以下代码段所示:
var links = data.links;
var nodes = data.nodes;
var nodeDictionary = new Object();
if (node != 0) {
force.stop();
node.each(function(d) {
var pos = [];
var thisNode = d3.select(this);
pos[0] = thisNode.attr("x");
pos[1] = thisNode.attr("y");
var page = thisNode.attr("page");
nodeDictionary[page] = pos;
});
nodes.forEach(function(node) {
var x = nodeDictionary[node.id][0];
var y = nodeDictionary[node.id][1];
//node.px = undefined;
//node.py = undefined;
node.x = x;
node.y = y;
});
}
这似乎在某些时候或某些节点有效,但大多数情况下这导致节点具有NaN位置。具体来说,这些位置是网络的tick()方法中的NaN,如下所示:
// Animates the force-directed network
function tick() {
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
link.attr("d", drawCurve);
}
function drawCurve(d) {
var testing = "M" + d.source.x + "," + d.source.y + "L" + d.target.x + "," + d.target.y;
return testing
}
在其他示例中,我已经看到在强制定向网络中设置初始节点位置的位置,tick()方法看起来更像是这样:
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
我需要做些什么才能使我的代码使用translate函数吗?我已经尝试在创建新网络之前停止tick方法,如此线程https://groups.google.com/forum/#!topic/d3-js/k6VSYZfMjGA中所建议的那样,但这并没有帮助。在生成新网络之前,是否需要清除某些变量或元素?我还尝试使用各种值组合设置px和py属性以及px,py,x和y属性,但没有成功。
我创建了一个基本代码的jsfiddle,显示了我在这里遇到的问题:http://jsfiddle.net/ew5qprhe/1/ 双击任何节点将导致生成新网络。某些节点已正确设置为其先前位置,但具有NaN位置的节点将移至左上角。
答案 0 :(得分:2)
关键是改变这项业务:
node.each(function(d) {
var pos = [];
var thisNode = d3.select(this);
pos[0] = thisNode.attr("x");
pos[1] = thisNode.attr("y");
var page = thisNode.attr("page");
nodeDictionary[page] = pos;
});
到此:
node.each(function(d) {
pos = [];
pos[0] = d.x;
pos[1] = d.y;
var page = d.id;
nodeDictionary[page] = pos;
});
由于我使用了.attr(“x”)和.attr(“y”),所以发生了奇怪的事情。另外,诅咒我对D3的不熟悉!