2016-11-22 13 views
1

我正在绘制有向图:JSBin。我希望图形最初可以用力显示,但用户可以自由移动节点。有两种选择,其中任何一种对我都很好:一旦显示强制图形,禁用力

1)一旦显示图形,我希望能够将任何节点拖到任何位置,不会干预;链接的长度将自动调整

2)一旦显示图形,我希望能够拖动节点,链接的长度可以始终保持不变,但我不希望来介入以自动改变其他节点的位置。

我试图修改.charge(-300),但它不能很好地工作,任何人都可以帮助吗?

编辑1:

我加force.nodes([])JSBin,但预期它不工作...

+0

可能有两个办法从什么是马克的回答表明不同。选择哪一个在很大程度上取决于1)当力量仍在运行时或刚刚停止时,你想要拖动行为吗? 2)力量布局是否会在初始停顿后重新加热? – altocumulus

回答

4

我要解决这个:

1)一旦显示图形,我希望能够拖动任意节点任何位置,部队不干预;链路的长度会自动调整

第一:

当你让你的矩形或圆形的节点,然后给它一个像这样的类:

var circlesOrRects = svg.append("g").selectAll(".foo") 
.data(force.nodes()) 
.enter() 
.append("path") 
.attr("class", "foo")//give it a class 

力向图后,下一步停止,修复如下所示的节点:

var force = d3.layout.force() 
    .nodes(d3.values(nodes)) 
    .links(links) 
    .size([width, height]) 
    .linkDistance(150) 
    .charge(-300) 
    .on("tick", tick) 
    .start() 
    .on("end", function(p) { 
     //using the class for selecting nodes. 
     d3.selectAll(".foo").each(function(d){ 
     d.fixed=true;//thsi will fix the node. 
     }); 
    }); 

现在在力停止后,您可以将节点拖到任何地方。

请注意,结束事件将被触发,一旦强制阿尔法变为0,只有这样才能修复节点。

工作代码here

+1

有一个缺点但是:这不会阻止力量在每次拖拽时被重新加热,它只是修复了节点的位置。如果布局中有许多节点,这可能会对整体性能产生显着影响。 – altocumulus

+0

耶你提出的许多节点可能是一个问题。 – Cyril

0

手动停止力向图,你可以简单地调用force.stop()

你所描述的是当你做出任何改变时阻止强制重新运行。有几种方法可以做到这一点,我认为最好的做法是从有向图中“分解”节点。

要做到这一点只需拨打force.nodes([])。现在,强制有向图正在使用空图,并且您可以继续使用您的节点。要在初始配置后,这样做,你会想:

force.on("end", function() { 
    force.nodes([]); 
}); 
+0

值得一提的是,这只适用于D3 v3,然而,这是OP要求的。在v3中,武力自己的阻力在每次拖曳事件中重新加热力量。在v4中,力布局与拖动行为分离,导致拖动事件不会重新加热布局。我在使用v4时看到至少有一个问题要求完全相反:*“为什么我的模拟不能在拖动时运行?”* – altocumulus

+0

@altocumulus非常感谢您的澄清。我还没有机会使用v4的力量 - 没有意识到行为已经改变。 – Ian

+0

感谢您的回答,但我没有看到'force.on'的位置(“end ...'。我把它放在JavaScript脚本的末尾,它不工作... – SoftTimur