添加节点到d3网络错误(用小提琴示例)

时间:2014-10-29 08:32:36

标签: javascript d3.js

我有以下问题:

我的情景很小 -

  

向图表添加三个相互关联的节点,   使用过滤功能删除一个,   再加回来

一旦我重新添加了删除的一个,它就会变得有点乱,并留在角落里。我确定我在某处或其他地方缺少设置功能。请查看我的jsFiddle并随时更新。

我的添加节点功能

/* step 3: node B reappears with links */
    function step3() {
        var nB = {id: 'bbb'};

        nodes.push(nB);

        /* find exiting nodes for links */
        var nA = nodes.filter(function(n) { return n.id === 'aaa'; })[0];
        var nC = nodes.filter(function(n) { return n.id === 'ccc'; })[0];

        var lAB = {source: nA, target: nB};
        var lBC = {source: nB, target: nC};
        links.push(lAB);
        links.push(lBC);

        recalc();
    }

由于

2 个答案:

答案 0 :(得分:1)

我和你的小提琴一起玩。看来新添加的节点没有x和y坐标。该属性由力布局生成。所以我再次将节点分配给力布局。它解决了你的问题。见这里:JFiddle

/* step 3: node B reappears with links */
function step3() {
    var nB = {id: 'bbb'};

    nodes.push(nB);

    /* find exiting nodes for links */
    var nA = nodes.filter(function(n) { return n.id === 'aaa'; })[0];
    var nC = nodes.filter(function(n) { return n.id === 'ccc'; })[0];

    var lAB = {source: nA, target: nB};
    var lBC = {source: nB, target: nC};
    links.push(lAB);
    links.push(lBC);

    // I added this line
    force.nodes(nodes);

    recalc();
}

答案 1 :(得分:1)

问题在于您删除节点和链接的方式。以下行创建了新的nodeslinks数组,隐藏了之前的定义:

nodes = nodes.filter(function(n) { return n.id !== 'bbb'; });
links = links.filter(function(l) { return (l.source.id !== 'bbb' && l.target.id !== 'bbb'); });

旧的,现在被遮蔽的定义仍在内部使用强制布局。也就是说,(已移除)节点bbb的位置仍在更新中。您无法看到,因为覆盖的定义在tick处理函数中使用。

现在,当您添加新节点和新链接时,强制布局内部使用的数据结构(旧nodeslinks)不会更新,只会更新新的,由tick处理函数是。这意味着在绘制新节点时,力布局不知道它,因此不计算它的坐标。

有两种方法可以解决这个问题。正如在另一个答案中指出的那样,您可以在更改时将nodes(以及links!)重新分配给强制布局:

 force.nodes(nodes);
 force.links(links);

这种方法的缺点是你失去了力布局的内部状态。在您进行更改时布局相当稳定的特定情况下,这一点很少,但如果您在力量仍然非常强大的情况下开始执行此操作后,您可能会遇到一些“跳跃”。

另一种方法是直接修改强制布局使用的数据结构,而不是重新分配:

 function step2() {
   links.splice(0, 1);
   links.splice(1, 1);

   nodes.splice(1, 1);

   recalc();
 }

完整示例here。我已经硬编码了节点和链接的索引以在此处删除以简化,但您显然也可以动态计算它们,就像我在this demo中所做的那样。