Seb*_*orz 6 javascript igraph d3.js force-layout
我正在尝试使用igraph预先计算稳定力导向图的位置,并将它们传递到我的d3.js图中.这是由于我将使用的数据集的大小,这意味着如果在客户端完成全力计算,我不能依赖客户端不冻结.我有JSON格式的位置,并使用线性比例,以使它们在d3.js中有用.
var positions =
{"positions": [{"x":"-68.824367374", "y": "-6.10824525755"},
{"x":"-80.8080803911", "y": "-3.38997541264"},
{"x":"6.75334817585", "y": "-49.6040729697"},
{"x":"14.6608797291", "y": "-81.8897019921"},
....
var force = d3.layout.force()
.charge(-100)
.linkDistance(3)
.size([width, height])
.nodes(data.nodes)
.links(data.links)
.start();
var posX = d3.scale.linear()
.range([0,960])
.domain([-125,120]);
var posY = d3.scale.linear()
.range([0,500])
.domain([-125,125]);
Run Code Online (Sandbox Code Playgroud)
这就是我试图这样做的方式.我已经尝试过px和py,但结果是一样的.好像这段代码从未运行过.如果我扔到console.log下面看到的地方,则不会打印该值.无论我在何处放置此代码,无论是在启动力之前还是之后.
force.on("start", function() {
node
.data(positions.positions)
.attr("cx", function(d) {
console.log(posX(d.x));
return posX(d.x);
})
.attr("cy", function(d) {
return posY(d.y);
})
});
Run Code Online (Sandbox Code Playgroud)
为什么on start事件没有设置我的节点的初始位置?它们似乎仍然是随机初始化的.或者,什么是预先计算d3.js力导向图的稳定状态的好方法?我曾经看过在Phantomjs上做过但是放弃了.
感谢您抽出宝贵时间阅读我的问题!
编辑
这是一个愚蠢的例子:https://jsfiddle.net/xp0zgqes/ 如果你运行它几次并注意节点的起始位置,你可以看到它们是随机初始化的.
确实不喜欢回答我自己的问题,但是我认为这将非常有用。首先,(这仅在我的情况下可能是特定的)如果初始位置数据来自与节点/链接数据不同的数据对象,那么如果您将它们组合在一起,就可以省去绑定到两个数据源的麻烦(或者可以比我聪明,只需创建具有x和y位置的原始json对象)。就我而言:
for (var i = 0; i < data.nodes.length; i++){
data.nodes[i].x = posX(positions.positions[i].x);
data.nodes[i].y = posY(positions.positions[i].y);
data.nodes[i].newAttribute = value;
}
Run Code Online (Sandbox Code Playgroud)
得益于JSON的魔力,可以轻松地向数据添加新属性,这很好,例如,如果您希望固定节点。
问题似乎出在force.start()电话上。如果在初始化力时调用,如下所示:
var force = d3.layout.force()
.charge(-100)
.linkDistance(3)
.size([width, height])
.nodes(data.nodes)
.links(data.links)
.start();
Run Code Online (Sandbox Code Playgroud)
默认情况下,布局将随机初始化节点。我发现解决该问题的方法是添加一个on tick事件,然后稍后开始加力。
var force = d3.layout.force()
.charge(-100)
.linkDistance(3)
.size([width, height])
.nodes(data.nodes)
.links(data.links)
.on("tick", tick);
force.start(); //Note, not chained
//Standard code that goes in the on.tick event
function tick() {
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; });
}
Run Code Online (Sandbox Code Playgroud)
还有Voilà!现在,我们有了一个功能齐全的力导向图,其初始位置从json设置。
工作提琴:https : //jsfiddle.net/zbxbzmen/