移动在D3固定节点(Moving fixed nodes in D3)

2019-06-24 05:59发布

我在被设置为D3力导向布局节点。 固定 =真。 如果我设置.x或.Y值,节点本身不移动到新的位置。

这里是我的功能:

function fixNode(idArray, locationX, locationY) {
    for ( x = 0; x < idArray.length; x++ ) {
        for ( y = 0; y < nodes.length; y++ ) {
            if (nodes[y].id == idArray[x]) {
                nodes[y].fixed = true;
                nodes[y].x = 50;
                nodes[y].y = 50;
                break;
            }
        }
    }
}

更新1:

这是基于Jason的咨询工作功能:

function fixNode(idArray, locationX, locationY) {
    for ( x = 0; x < idArray.length; x++ ) {
        for ( y = 0; y < nodes.length; y++ ) {
            if (nodes[y].id == idArray[x]) {
                nodes[y].fixed = true;
                nodes[y].x = 50;
                nodes[y].y = 50;
                nodes[y].px = 50;
                nodes[y].py = 50;
                break;
            }
        }
    }
    tick();
}

Answer 1:

力导向布局从实际的渲染分离。 通常情况下,你有一个节拍处理,这将更新您的SVG元素的属性为每个布局算法的“滴答”(约脱钩的好处是你呈现到<canvas>替代,或别的东西)。

因此,要回答你的问题,你只需要直接以更新您的SVG元素的属性,调用这个处理程序。 例如,你的代码可能是这样的:

var node = …; // append circle elements

var force = d3.layout.force()
    .nodes(…)
    .links(…)
    .on("tick", tick)
    .start();

function tick() {
  // Update positions of circle elements.
  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

所以,你可以简单地调用tick()在任何点和更新元素的位置。

你可能会打电话给force.tick()但是这意味着被用作同步替代force.start()可以反复调用它,每次调用执行布局算法的步骤。 然而,有一个内部alpha用于控制内部使用的模拟退火变量,并且一旦布局“冷却”,该变量将是0和进一步调用force.tick()将没有任何效果。 (诚然,如果它可能是好的, force.tick()始终点火蜱事件,无论散热,但这不是当前的行为)。

当您在评论正确地指出,如果手动设置dxdy ,你也应该设置d.pxd.py如果您希望节点保持在一定的位置相同的值。



文章来源: Moving fixed nodes in D3