在D3中移动固定节点 [英] Moving fixed nodes in D3

查看:432
本文介绍了在D3中移动固定节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个D3强制导向布局中的节点设置为 fixed = true。如果我设置了.x或.y值,节点本身不会移动到新位置。

I have nodes in a D3 force-directed layout that are set to .fixed = true. If I set the .x or .y values, the nodes themselves don't move to their new position.

这是我的函数:

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

strong> UPDATE 1:

UPDATE 1:

这里是基于Jason的建议的工作功能:

Here is the working function based on Jason's advice:

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


推荐答案

与实际渲染脱钩。通常你有一个tick处理程序,它会更新布局算法的每个tick的SVG元素的属性(关于解耦的好处是你渲染到< canvas> 而不是其他)。

The force-directed layout is decoupled from the actual rendering. Normally you have a tick handler, which updates the attributes of your SVG elements for every "tick" of the layout algorithm (the nice thing about the decoupling is you render to a <canvas> instead, or something else).

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

So to answer your question, you simply need to call this handler directly in order to update the attributes of your SVG elements. For example, your code might look like this:

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

所以你可以简单地调用 code>在任何时候更新元素位置。

So you could simply call tick() at any point and update the element positions.

你可能会试着调用 force.tick $ c>,但是这意味着用作 force.start()的同步替代:可以重复调用它,每个调用执行布局算法的步骤。但是,有一个内部 alpha 变量用于控制内部使用的模拟退火,并且一旦布局冷却,该变量将 0 并进一步调用 force .tick()将没有效果。 (不可否认,如果 force.tick()总是触发一个tick事件,而不考虑冷却,但这不是当前的行为)。

You might be tempted to call force.tick(), but this is meant to be used as a synchronous alternative to force.start(): you can call it repeatedly and each call executes a step of the layout algorithm. However, there is an internal alpha variable used to control the simulated annealing used internally, and once the layout has "cooled", this variable will be 0 and further calls to force.tick() will have no effect. (Admittedly it might be nice if force.tick() always fired a tick event regardless of cooling, but that is not the current behaviour).

正如你在注释中指出的,如果手动设置 dx dy 您还应该设置具有相同值的 d.px d.py ,如果您希望节点保留在某一位置。

As you correctly noted in the comments, if you manually set d.x and d.y, you should also set d.px and d.py with the same values if you want the node to remain in a certain position.

这篇关于在D3中移动固定节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆