2012-10-20 9 views
21

私のウェブサイトにネットワークを表示するために、強制レイアウトの例(http://bl.ocks.org/1153292)を使用しています。基礎となるデータが変更された場合のD3強制レイアウトの要素の更新方法

私はユーザーがいつでもどの種類のリンクを見るかを選択することができます。リンクタイプAを表示することを選択すると、リンクタイプBを追加してリンクタイプAを削除すると、タイプBの残りのリンクはAカラーで表示されます。

これは、svg図へのリンクを追加するために実行されるコードです。私はそれにリンクを追加したり削除したりして、配列this.linksを変更しています。あなたが見ることができるように私はクラス属性を設定するが、それは更新されていない - それは私が現在、ダニ機能内部クラス属性が、このオフコースの原因を更新することでこの問題を回避するリンクA.

var path = svg.append("svg:g") 
    .selectAll("path") 
    .data(this.links) 
    .enter() 
    .append("svg:path") 
    .attr("class", function(d) { return "link " + d.type; }) 
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); 

のタイプのまま多くの不必要な作業。

私は、既存の要素と新しい要素のマージされた選択を返すので、attr操作は既存の要素を更新して新しい要素を設定する必要があります。

私には何が欠けていますか?

答えて

19

私はanswer in this post

var circle = svg.selectAll("circle") 
    .data(data); 

circle.enter().append("circle") 
    .attr("r", 2.5); 

circle 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }); 

circle.exit().remove(); 

答えは私がselectAll.dataの結果にではなく追記演算子の結果にATTRオペレーターを呼び出す必要があるということがわかりました。

+1

Ido、これは古い投稿であることは分かっていますが、あなたと同じ問題が発生していると思いますが、この解決策はまだ分かりません。どのように動作するのか、元の問題をどのように解決するのか説明できますか?ありがとうございました。 – Mars

+3

cxとcyのattrの更新がenter()コンテキストの外にあるので、毎回発生するので、このソリューションは機能します。元のコードでは、attr関数はenter()コンテキスト内で呼び出されるため、オブジェクトIDに基づいて作成されるのは1回だけです。私にとって、データの第2引数として重要な機能について学ぶことは何だったのですか?(http://bost.ocks.org/mike/constancy/) – velotron

4

強制的なレイアウトからノードを追加および削除する例がhttp://bl.ocks.org/1095795です。リンクとノードを別々に処理しなければならず、フォースレイアウトを再開する必要があります。

function restart() { 
    var link = vis.selectAll("line.link") 
     .data(links, function(d) { return d.source.id + "-" + d.target.id; }); 

    link.enter().insert("svg:line", "g.node") 
     .attr("class", "link"); 

    link.exit().remove(); 

    var node = vis.selectAll("g.node") 
     .data(nodes, function(d) { return d.id;}); 

    var nodeEnter = node.enter().append("svg:g") 
     .attr("class", "node") 
     .call(force.drag); 

    nodeEnter.append("svg:image") 
     .attr("class", "circle") 
     .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png") 
     .attr("x", "-8px") 
     .attr("y", "-8px") 
     .attr("width", "16px") 
     .attr("height", "16px"); 

    nodeEnter.append("svg:text") 
     .attr("class", "nodetext") 
     .attr("dx", 12) 
     .attr("dy", ".35em") 
     .text(function(d) { return d.id }); 

    node.exit().remove(); 

    force.start(); 
} 
+1

これでは十分ではありません。私はリンクを追加したり削除したりしていますが、問題は順序通りではないということです。リンク配列が[A1、A2、A3]である場合、タイプBのリンクが[A1、A2、A3、B1、B2]のリンクを表示するように選択すると、タイプが表示されないように選択します配列は[B1、B2]です。 D3は2つの要素を残して3を削除することを選択しますが、現在はA1とA2にバインドされているため、B1とB2にバインドする必要があるため、2つの要素を更新する必要があります。私はvis.selectAll( "g.Node")。data(nodes)を保存してそれを更新することで管理します。 –

+0

あなたが現在やっていることと何が問題なのかを示すjsfiddleを作成すると、より良い解決策を見つけることができます。 – Bill

関連する問題