冻结力定向网络图,并在D3中可拖动

Freezing force directed network graph and make draggable in D3

本文关键字:D3 并在 拖动 网络 冻结      更新时间:2023-09-26

我正试图完全冻结d3中的力定向网络!我尝试将摩擦值设置为0,但网络变得更紧凑,节点仍然稍微悬停。

var force = d3.layout.force()
.charge(-220)
.linkDistance(70)
.friction(0);

我也希望我的节点是可拖动的,即移动位置时,他们被拖动。

最终,我试图得到类似于Cytoscape js的东西,看起来像这样。

谢谢!

首先,如果您想在某个时间"冻结"图形,您可以使用force布局的stop命令:

force.stop()

一个好的用法是首先让图形自组织(使用tick),然后停止强制:

// include in beginning of script
force.start();
for (var i = 0; i < n; ++i) force.tick();
force.stop();

然后,如果你想拖放节点,一个好主意是在d3示例页面上搜索drag,你会发现以下链接:拖放支持将节点设置为固定位置,当它被放下时,它有你想要的一切。顺便说一下,它也涉及到一个stackoverflow问题,你可能会发现有趣的:D3强制有向图与拖放支持,使选定的节点位置固定时,下降

这里是有趣的拖放代码,适用于力已经停止的图形(我只是注释了一些行,不确定,所以通过取消注释来验证,如果它不像预期的那样工作)

var node_drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);
function dragstart(d, i) {
    //force.stop() // stops the force auto positioning before you start dragging
}
function dragmove(d, i) {
    d.px += d3.event.dx;
    d.py += d3.event.dy;
    d.x += d3.event.dx;
    d.y += d3.event.dy; 
    tick(); // this is the key to make it work together with updating both px,py,x,y on d !
}
function dragend(d, i) {
    //d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
    //tick();
    //force.resume();
}
function tick() {
  link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
  node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
};