2013-05-29 1 views
13

私はネットワークビジュアライゼーションで作業するD3.js初心者です。フォースレイアウトのリンクを正しく指定する方法がわかりません。問題は、デフォルトでは、d3がリンクの「ソース」と「ターゲット」を「ノード」配列内のノードのインデックスに解釈することです。しかし、私のデータでは、ソースとターゲットは、ノード属性に格納されているノードのID番号を参照しています。 node.indexではなく、node.idを指すようにリンクを設定するにはどうすればよいですか?D3:配列内のインデックスの代わりにリンクのノード属性を使用する

var nodes = data.nodes; 
var edges = data.edges; 
var force = d3.layout.force() 
      .nodes(d3.values(nodes)) 
      .links(edges) 
      .size([w, h]) 
      .linkDistance(80) 
      .charge(-500) 
      .gravity(0.2) 
      .on("tick", tick) 
      .start(); 

...しかし、私は.nodes()一部または.links()一部を変性するべきであるかどうかはわからない:ここで私は、私はそれを行う必要がありますね場所です。私はちょうどそれの前にこれを追加してみました:

var nodes = data.nodes; 
for (var i = 0; i < nodes.length; i++) { 
    nodes[i].index = nodes[i].id; 
    console.log(i + " " + nodes[i].index + " " + nodes[i].id); 
} 

...しかし、私は力を作成するときにindex属性は、単に上書きされます。

私はthis質問を読んでいますが、唯一の答えは少しハックのようです。彼らはまた "データキー"について言及していますが、実際にはenter()機能を使用していないので、私はそれらを多く見つけることはできません。どのように組み込むのか分かりません。

答えて

21

私はあなたがインデックスとして属性node.idを使用するようにD3を強制できるとは思わないが、あなたは右の参照を持っているリンクを処理することができます:あなたが設定している場合

var edges = []; 

data.edges.forEach(function(e) { 
    // Get the source and target nodes 
    var sourceNode = data.nodes.filter(function(n) { return n.id === e.source; })[0], 
     targetNode = data.nodes.filter(function(n) { return n.id === e.target; })[0]; 

    // Add the edge to the array 
    edges.push({source: sourceNode, target: targetNode}); 
}); 

var force = d3.layout.force() 
    .nodes(data.nodes) 
    .links(edges) 
    // the rest of your code here 
    .start(); 

力のレイアウトは、インデックスを上書きそれはリンクに各ノードのソースとターゲットの参照を保持します。

+0

これはうまくいきませんでした。「ノードオブジェクトのキーがIDだとしますか?」とはどういう意味ですか?どうやらIDでやっていけばいいのですが、 'data.nodes []'は配列インデックスだけでノードにアクセスしていませんか? – FrancesKR

+0

はい、申し訳ありませんが、私はあなたのデータ構造について間違った仮定をしました。それに応じてコードを更新しました。 –

+0

ありがとう、それは動作します!私はまた、エッジのための 'type'属性を持っていましたので、私は各エッジ、すなわち' edges.push({source:sourceNode、target:targetNode、type:e.type})を押したときに追加しなければなりませんでした ' – FrancesKR