2012-10-20 26 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 + ")"; }); 

我目前通過更新蜱函數內部的階級屬性,解決此問題,但這種偏離航線的原因很多不需要的工作。

我讀到enter操作返回存在的元素的合併選擇,也是新的,因此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(); 

答案是,我需要調用ATTR操作上selectAll.data的結果,而不是追加操作的結果。

+1

Ido,我知道這是一箇舊帖子,但我相信我遇到了和你一樣的問題,但我仍然不明白這個解決方案。你能否解釋它是如何工作的 - 它如何解決你最初的問題?謝謝。 – Mars

+3

該解決方案的工作原理是因爲cx和cy的attr更新在enter()上下文之外,所以它們每次都會發生。在原始代碼中,attr函數在enter()上下文中調用,所以它們只根據對象標識創建一次。對我來說,它是作爲data()的第二個參數來學習關鍵函數的: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

這還不夠。我添加和刪除鏈接,問題是它沒有按順序。當我選擇查看類型A的鏈接時,鏈接數組是[A1,A2,A3],然後我選擇看到類型B的鏈接,數組是[A1,A2,A3,B1,B2],然後選擇不看類型數組是[B1,B2]。 D3然後選擇離開2個元素並刪除3,但是我必須更新這兩個元素,因爲它們現在綁定到A1和A2,我需要它們綁定到B1和B2。我設法通過保存vis.selectAll(「g.Node」)。data(節點)並更新它。 –

+0

如果您創建一個jsfiddle來顯示您當前正在做什麼以及問題是什麼,那麼我們可能會幫助您找到更好的解決方案。 – Bill