2012-05-08 14 views
7

D3の強制指定レイアウトのノードがに設定されています。 固定 = true。 .xまたは.yの値を設定すると、ノード自体は新しい位置に移動しません。D3の固定ノードの移動

はここに私の機能です:

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

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

答えて

12

力指向レイアウトが切り離されます実際のレンダリング。通常は、ダンプハンドラがあります。これは、レイアウトアルゴリズムのすべての「目盛り」に対して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.xd.yを設定する場合は、ノードが特定の位置のままにしたい場合、あなたは同じ値でd.pxd.pyをも設定する必要があります。

+0

ありがとう、今私はそれを得る。私はちょうど動作をテストし、デフォルトの例から来ている人々を捨てるかもしれない何かを指摘したい:ノードが動いている場合は、px/py値とx/y値を変更する必要があります。私は上記の更新された関数を投稿します。 – Elijah

関連する問題