2017-09-28 21 views
1

シナリオせずにノードを削除:D3 v3の強制のレイアウトは、優雅に追加/リフレッシュ

私はオンラインの例から取った標準D3 v3のフォースレイアウト から始まりました。

私はこれを強化したいと私の目的は次のとおりです。

  1. スクリプトの負荷が初期化し、いくつかのデータでグラフを描画するための関数を呼び出すとき
  2. 追加するには、ページ上のグラフを更新するには、ボタンをクリックしてください/ノードを削除し、優雅リンク - 。内のノードの飛行 'で完全な再描画なしすなわち

私が望む行動の種類の例は番目ですドラッグしきい値スライダは完全な再レンダリングなし/アウトでリンクを「ポップ」幻想グラフは削除/追加されているかを確認することは容易である:http://jsfiddle.net/simonraper/TdHgx/?utm_source=website&utm_medium=embed&utm_campaign=TdHgx

問題:

  • I上記のポイント2を達成する方法が不明です。
  • グラフを完全な再描画で更新できません
  • 答えはD3の一般的な更新パターンの使い方とは関係ありません。 jsfiddleためhttps://jsfiddle.net/thedev19/uvqosxrr/3/

    コード:


    HTML:

    <body> 
    
        <button id="update-button1">Update Data - Remove</button> 
        <button id="update-button2">Update Data - Add</button> 
    
    </body> 
    

    JS:

    ここ

は、私がこれまで持っているものの一例です

var width = 400, 
    height = 500; 

var force = d3.layout.force() 
    .size([width, height]) 
    .charge(-400) 
    .linkDistance(40) 
    .on("tick", tick); 

var drag = force.drag() 
    .on("dragstart", dragstart); 

//Set up the force layout 
var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var link = svg.selectAll(".link"), 
    node = svg.selectAll(".node"); 

    //we call this function when we first draw graph 
    var drawInit = function(graph){ 

    link = link.data(graph.links, function(d) { return d.id; }) 
     .enter().append("line") 
     .attr("class", "link"); 

    node = node.data(graph.nodes, function(d) { return d.id; }) 
     .enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 12) 
     .on("dblclick", dblclick) 
     .call(drag); 

    force 
     .nodes(graph.nodes) 
     .links(graph.links) 
     .start(); 
}; 

    //call this function whenever we want to update the graph 
var update = function(graph){ 

    link = link.data(graph.links, function(d) { return d.id; }); 

    link.exit().remove(); 

    link 
     .enter().append("line") 
     .attr("class", "link"); 

    node = node.data(graph.nodes, function(d) { return d.id; }); 

    //Remove nodes not in new data set 
    node.exit().remove(); 

    //For each datum in dataset that wasn't in old dataset append 
     circle 
    node.enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 12) 
     .on("dblclick", dblclick) 
     .call(drag); 

    //Update the force layout graph 
    force 
     .nodes(graph.nodes) 
     .links(graph.links) 
     .start(); 
}; 

function tick() { 
    link.attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

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

function dblclick(d) { 
    console.log("double clicked on " + d.name); 
    d3.select(this).classed("fixed", d.fixed = false); 
} 

function dragstart(d) { 
    d3.select(this).classed("fixed", d.fixed = true); 
} 

//data1 is used for our initial drawing 
data1 = { 
    "nodes": [ 
    { 
     "id":0, 
     "name": 0, 
     "group": 1, 
     "size": 10 
    }, 
    { 
     "id":1, 
     "name": 1, 
     "group": 1, 
     "size": 10 
    }, 
    { 
     "id":2, 
     "name": 2, 
     "group": 1, 
     "size": 20 
    }, 
    { 
     "id":3, 
     "name": 3, 
     "group": 1, 
     "size": 30 
    }, 
    { 
     "id":4, 
     "name": 4, 
     "group": 1, 
     "size": 25 
    } 
], 
    "links": [ 
    { 
     "source": 1, "target": 0, "value":1, "id":0 
    }, 
    { 
     "source": 1, "target": 2, "value":1, "id":1 
    }, 
    { 
     "source": 1, "target": 3, "value":1, "id":2 
    }, 
    { 
     "source": 1, "target": 4, "value":1, "id":3 
    } 
] 

}; 

drawInit(data1); 

//When user clicks on button update force layout graph *gracefully* 
d3.select("#update-button1").on("click", function(e) { 

    var data2 = { 
     "nodes": [ 
      { 
       "id": 0, 
       "name": 0, 
       "group": 1, 
       "size": 10 
      }, 
      { 
       "id": 1, 
       "name": 1, 
       "group": 1, 
       "size": 10 
      }, 
      { 
       "id": 2, 
       "name": 2, 
       "group": 1, 
       "size": 20 
      }, 
      { 
       "id": 3, 
       "name": 3, 
       "group": 1, 
       "size": 30 
      } 
     ], 
     "links": [ 
      { 
       "source": 1, "target": 0, "value": 1, "id": 0 
      }, 
      { 
       "source": 1, "target": 2, "value": 1, "id": 1 
      }, 
      { 
       "source": 1, "target": 3, "value": 1, "id": 2 
      } 
     ] 
    }; 

     update(data2); 
}); 

//When user clicks on button update force layout graph *gracefully* 
d3.select("#update-button2").on("click", function(e) { 

    //this simulates removing a node 
    var data3 = { 
     "nodes": [ 
      { 
       "id": 0, 
       "name": 0, 
       "group": 1, 
       "size": 10 
      }, 
      { 
       "id": 1, 
       "name": 1, 
       "group": 1, 
       "size": 10 
      }, 
      { 
       "id": 2, 
       "name": 2, 
       "group": 1, 
       "size": 20 
      }, 
      { 
       "id": 3, 
       "name": 3, 
       "group": 1, 
       "size": 30 
      }, 
      { 
       "id": 4, 
       "name": 4, 
       "group": 1, 
       "size": 30 
      }, 
      { 
       "id": 5, 
       "name": 5, 
       "group": 1, 
       "size": 30 
      } 
     ], 
     "links": [ 
      { 
       "source": 1, "target": 0, "value": 1, "id": 0 
      }, 
      { 
       "source": 1, "target": 2, "value": 1, "id": 1 
      }, 
      { 
       "source": 1, "target": 3, "value": 1, "id": 2 
      }, 
      { 
       "source": 1, "target": 4, "value": 1, "id": 3 
      }, 
      { 
       "source": 1, "target": 5, "value": 1, "id": 4 
      } 
     ] 
    }; 

    update(data3); 
}); 

答えて

関連する問題