简体   繁体   English

d3js强制布局未按预期工作

[英]d3js Force Layout Not Working As Expected

I've been working on a D3JS force layout graph, that isn't quite working as expected. 我一直在研究D3JS强制布局图,但效果并不理想。

I've uploaded my code to JSFiddle, and can be seen here: 我已经将代码上传到JSFiddle,可以在这里看到:

http://jsfiddle.net/jonaths/e9L3aq4k/ http://jsfiddle.net/jonaths/e9L3aq4k/

I think the important part of it is the following, that deals with updating the threshold of the nodes / links: 我认为其中重要的部分是以下内容,这些内容涉及更新节点/链接的阈值:

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();
}

The idea is that as the threshold is increased, nodes and links that don't meet that threshold are removed. 想法是,随着阈值的增加,不符合该阈值的节点和链接将被删除。 When the threshold is subsequently updated, additional links / nodes should be added / removed accordingly. 当阈值随后更新时,应相应地添加/删除其他链接/节点。

I used the code here as the basis for what I'm trying to do, but had to amend it to get the nodes to disappear, so there may well be an issue with my code. 我在这里使用代码作为我要执行的操作的基础,但是必须对其进行修改以使节点消失,因此我的代码可能存在问题。

Now what I'm finding, is that if you increase the threshold slowly, then it works perfectly. 现在,我发现,如果您缓慢增加阈值,那么它会完美运行。 However, if you just click the threshold on to a high value, and then subsequently change it again, there is some weird behaviour that results in the graph breaking. 但是,如果仅将阈值单击为一个较高的值,然后再将其更改,则有些奇怪的行为会导致图形中断。 You may notice the nodes collect in the top left. 您可能会注意到节点收集在左上方。 Reviewing outputs in the console shows the following error message: 在控制台中查看输出会显示以下错误消息:

Uncaught TypeError: Cannot read property 'weight' of undefined Uncaught TypeError:无法读取未定义的属性“ weight”

But I can't for the life of me work out why that's happening sometimes, but not every time. 但是我无法为自己的生活弄清楚为什么有时而不是每次都如此。 I'm fairly new to D3, so any help & advice would be greatly appreciated, and I hope that I've provided all the required information for someone to give me some pointers. 我刚接触D3,因此对您的帮助和建议将不胜感激,我希望我已为某人提供了所有必需的信息,以便给我一些指导。 Thanks! 谢谢!

If you inspect your data when the error condition occurs, you are losing a source reference in a link to one of the nodes (it goes undefined): 如果在发生错误情况时检查数据,则将丢失指向其中一个节点的链接中的source引用(未定义):

[Object]
 0: Object
   source: undefined
   target: Object
   value: 75
   __proto__: Object
 length: 1
 __proto__: Array[0]

I'm not sure why, but I rewrote your threshold function to work on the d3 link and nodes objects (instead of going back to source json) and it behaves as expected: 我不确定为什么,但是我重写了您的阈值函数以在d3链接和节点对象上工作(而不是返回到源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();
}

Updated fiddle . 更新小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM