我有以下问题:
我的情景很小 -
向图表添加三个相互关联的节点, 使用过滤功能删除一个, 再加回来
一旦我重新添加了删除的一个,它就会变得有点乱,并留在角落里。我确定我在某处或其他地方缺少设置功能。请查看我的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();
}
由于
答案 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)
问题在于您删除节点和链接的方式。以下行创建了新的nodes
和links
数组,隐藏了之前的定义:
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
处理函数中使用。
现在,当您添加新节点和新链接时,强制布局内部使用的数据结构(旧nodes
和links
)不会更新,只会更新新的,由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中所做的那样。