2013-04-10 42 views
1

所以我想了解http://bl.ocks.org/mbostock/4062045的例子,並且有幾個問題。D3:從頭開始添加新節點的最佳方式

從例如:

var link = svg.selectAll(".link") 
     .data(graph.links) 
    .enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value); }); 

那是什麼基本上是做(據我所知)越來越(即無)「鏈接」類的所有元素,然後從「graphs.links」,並稱一切到那個空的元素列表。所有新的元素(如「enter()」所表示的都被一個「行」標籤封裝,並且具有「class」屬性集並被程式化。是不會得到任何東西爲什麼都做呢?爲什麼不這樣做?:

var link = svg 
     .data(graph.links) 
    .enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value); }); 

我想一個理由不這樣做的是,它似乎並沒有工作,但笑爲什麼不呢?

當然,如果您認爲一切都是新的,enter()似乎也是多餘的。

有什麼想法?

回答

1

如果APPY這個空graph.links,然後做console.log(links),這裏是你將得到的鉻什麼JavaScript控制檯:

[數組[0],選擇:功能,全選:功能,ATTR:功能, 歸類:功能,款式:函數...]

所以,是的,你將有一個空數組,但你有所有的功能已經存在,這樣,當您添加數據之後,你不必須再做一切。這就是d3的智能。

0

要了解究竟是什麼做,讓我們走的例子,從頂部到底部:

var link = svg.selectAll(".link") 
    .data(graph.links) 
.enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { return Math.sqrt(d.value); }); 

selectAll進行捕捉任何預先存在的鏈接(這是沒有像你正確的假設),並返回一個選擇(這是空的)。然後通過data將數據分配給空的選擇。 enter然後基於data中假定的節點之間的差異和selectAll返回的選擇返回節點的選擇,在本例中這是所有節點,因爲沒有先前存在的節點。然後通過使用append將這些節點附加到svg元素。

現在,爲什麼selectAll必須使用的理由很簡單:在這種情況下,通過select

var svg = d3.select("body").append("svg") 
.attr("width", width) 
.attr("height", height); 

append(因爲它是select後)returns an d3 selection array with one element:SVG的元素創建使用append這裏。這假定返回的節點是one element only。因爲Sizzle引擎在類似數組的對象中返回所有選擇,所以它的行爲就像一個數組,但是d3假定它是一個只有一個節點元素的數組。這就是爲什麼當你解除selectAllenter聲明時,one single node is drawndataappend。如果您試圖通過將enter重新記錄到聲明中來更改此項,那麼您運氣不佳:enter會嘗試使其選擇包含由data定義的所有節點,該節點不存在於先前存在的選擇中。因爲它假定先前存在的選擇是一個節點數組,it fails to do its job with a single node returned by select

selectAll另一方面,returns the needed array of nodes。因爲沒有預先存在的節點,所以you could also relieve the string selector,但它肯定更好,因爲它顯示了相應地更新所有鏈接和節點的意圖。如果您稍後添加預先存在的節點,則很容易出現錯誤。