8

に設定されているD3力指向レイアウトのノードがあります。固定=true。.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:

ジェイソンのアドバイスに基づく仕事関数は次のとおりです。

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

1 に答える 1

14

力指向のレイアウトは、実際のレンダリングから切り離されています。通常、ティックハンドラーがあり、レイアウトアルゴリズムの「ティック」ごとに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()(確かに、冷却に関係なく常にティックイベントを発生させるとよいかもしれませんが、それは現在の動作ではありません)。

コメントで正しく指摘したように、とを手動で設定d.xした場合、ノードを特定の位置に残したい場合は、とを同じ値で設定d.yする必要があります。d.pxd.py

于 2012-05-08T22:24:44.797 に答える