d3js 强制布局无法按预期工作
d3js Force Layout Not Working As Expected
我一直在研究 D3JS 强制布局图,但效果不如预期。
我已经将我的代码上传到 JSFiddle,可以在这里看到:
http://jsfiddle.net/jonaths/e9L3aq4k/
我认为它的重要部分如下,处理更新节点/链接的阈值:
function threshold(thresh) {
graph.links.splice(0, graph.links.length);
for (var i = 0; i < graphRec.links.length; i++) {
if (graphRec.links[i].value > thresh) {
graph.links.push(graphRec.links[i]);
}
}
graph.nodes.splice(0, graph.nodes.length);
for (var j = 0; j < graphRec.nodes.length; j++) {
if (graphRec.nodes[j].value > thresh) {
graph.nodes.push(graphRec.nodes[j]);
}
}
restart();
}
//Restart the visualisation after any node and link changes
function restart() {
node = node.data(graph.nodes);
link = link.data(graph.links);
link.exit().remove();
node.exit().remove();
node.enter().insert("circle", ".node").attr("class", "node").attr("r", function (d) {
return d.value / 5
}).style("fill", "steelblue").call(force.drag);
link.enter().insert("line", ".node").attr("class", "link").call(force.drag);
force.start();
}
想法是,随着阈值的增加,不满足该阈值的节点和链接将被删除。当随后更新阈值时,应相应地添加/删除额外的链接/节点。
我使用 code here 作为我正在尝试做的事情的基础,但必须对其进行修改以使节点消失,因此我的代码很可能存在问题。
现在我发现,如果您缓慢增加阈值,那么它会完美运行。但是,如果您只是将阈值单击到一个高值,然后再次更改它,则会出现一些导致图形中断的奇怪行为。您可能会注意到节点聚集在左上角。查看控制台中的输出显示以下错误消息:
未捕获类型错误:无法读取未定义的 属性'weight'
但我终其一生都无法弄清楚为什么有时会发生这种情况,但不是每次都会发生。我是 D3 的新手,所以任何帮助和建议都将不胜感激,我希望我已经提供了所有必需的信息,以便有人给我一些指导。谢谢!
如果您在错误情况发生时检查数据,您将丢失 link 中对其中一个节点的 source
引用(未定义):
[Object]
0: Object
source: undefined
target: Object
value: 75
__proto__: Object
length: 1
__proto__: Array[0]
我不确定为什么,但我重写了你的阈值函数以处理 d3
link 和节点对象(而不是返回到源 json)并且它表现符合预期:
var masterNodes = graph.nodes;
var masterLinks = graph.links;
function threshold(thresh) {
graph.nodes = [];
masterNodes.forEach(function(d,i){
if (d.value > thresh){
graph.nodes.push(d);
}
});
graph.links = [];
masterLinks.forEach(function(d,i){
if (d.value > thresh){
graph.links.push(d);
}
});
restart();
}
已更新 fiddle。
我一直在研究 D3JS 强制布局图,但效果不如预期。
我已经将我的代码上传到 JSFiddle,可以在这里看到:
http://jsfiddle.net/jonaths/e9L3aq4k/
我认为它的重要部分如下,处理更新节点/链接的阈值:
function threshold(thresh) {
graph.links.splice(0, graph.links.length);
for (var i = 0; i < graphRec.links.length; i++) {
if (graphRec.links[i].value > thresh) {
graph.links.push(graphRec.links[i]);
}
}
graph.nodes.splice(0, graph.nodes.length);
for (var j = 0; j < graphRec.nodes.length; j++) {
if (graphRec.nodes[j].value > thresh) {
graph.nodes.push(graphRec.nodes[j]);
}
}
restart();
}
//Restart the visualisation after any node and link changes
function restart() {
node = node.data(graph.nodes);
link = link.data(graph.links);
link.exit().remove();
node.exit().remove();
node.enter().insert("circle", ".node").attr("class", "node").attr("r", function (d) {
return d.value / 5
}).style("fill", "steelblue").call(force.drag);
link.enter().insert("line", ".node").attr("class", "link").call(force.drag);
force.start();
}
想法是,随着阈值的增加,不满足该阈值的节点和链接将被删除。当随后更新阈值时,应相应地添加/删除额外的链接/节点。
我使用 code here 作为我正在尝试做的事情的基础,但必须对其进行修改以使节点消失,因此我的代码很可能存在问题。
现在我发现,如果您缓慢增加阈值,那么它会完美运行。但是,如果您只是将阈值单击到一个高值,然后再次更改它,则会出现一些导致图形中断的奇怪行为。您可能会注意到节点聚集在左上角。查看控制台中的输出显示以下错误消息:
未捕获类型错误:无法读取未定义的 属性'weight'
但我终其一生都无法弄清楚为什么有时会发生这种情况,但不是每次都会发生。我是 D3 的新手,所以任何帮助和建议都将不胜感激,我希望我已经提供了所有必需的信息,以便有人给我一些指导。谢谢!
如果您在错误情况发生时检查数据,您将丢失 link 中对其中一个节点的 source
引用(未定义):
[Object]
0: Object
source: undefined
target: Object
value: 75
__proto__: Object
length: 1
__proto__: Array[0]
我不确定为什么,但我重写了你的阈值函数以处理 d3
link 和节点对象(而不是返回到源 json)并且它表现符合预期:
var masterNodes = graph.nodes;
var masterLinks = graph.links;
function threshold(thresh) {
graph.nodes = [];
masterNodes.forEach(function(d,i){
if (d.value > thresh){
graph.nodes.push(d);
}
});
graph.links = [];
masterLinks.forEach(function(d,i){
if (d.value > thresh){
graph.links.push(d);
}
});
restart();
}
已更新 fiddle。