2014-10-29 36 views
0

我有以下问题:添加到d3网络错误的节点(与小提琴例子)

我有小的场景 -

添加三个相互联系的节点的图中, 使用过滤器除去一个功能, 再次添加它

一旦我重新添加删除的一个,它得到了一点扰码,并留在角落里。我确定我错过了设置功能的地方或某事。请看看我的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(); 
    } 

感谢

回答

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

完整示例。我已经对节点和链接的索引进行了硬编码,以便简化,但显然也可以动态计算它们,正如我在this demo中所做的那样。

+0

感谢您的回复和时间。我必须说一个非常好的阅读。因此,我的目标是这样的结果:有一个滑块,可以筛选出并删除节点及其连接,并根据节点参数之一重新连接到节点上 - 称为其半径。就像下面的[小提琴](http://jsfiddle.net/vlandham/yeQS2/191/);我试图在这里添加你的逻辑,但我不能重新考虑'遗漏'。你介意看看这个吗?任何建议非常感谢 – 2014-10-29 19:43:16

+0

你似乎没有做任何事情来重新连接节点。这听起来像你想要检查,没有连接的节点,离哪个节点最近,并添加一个新的连接。此外,这个例子和你在这里的节点和链接变量被覆盖的问题一样。 – 2014-10-29 19:58:21

+0

非常感谢。虽然现在完全失去了,但是我试着回顾一下代码......请原谅我的无知,但是按照你的方式做它是有效的,把节点和链接拼接起来,把它们放在一个变量中,这样我就可以重新添加他们如果过滤器被禁用?不是(批评只是一个问题) – 2014-10-29 20:07:54

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