2014-07-23 62 views
16

我有一個組合的條形圖/折線圖。對於輸入文件中的每一行,我創建一個包含多個元素(直線,矩形,文本)一組:D3:使用組中的多個元素更新數據

var myGroups = svg.selectAll('g').data(myData) 
myGroups.enter().append('g') 
... 
myGroups.append('line') 
... 
myGroups.append('polygon') 
... 
myGroups.append('text') 
... 

我目前只是

svg.selectAll('*').remove() 

,每次從頭開始創建一切數據已更新。不過,我希望所有元素都能平滑過渡。

我已經通過this tutorial幾次,但我仍然不明白我怎麼能做到這一點在我的情況。

回答

39

的關鍵是處理所有的選擇,而不僅僅是輸入選擇:

var myGroups = svg.selectAll('g').data(myData); 

// enter selection 
var myGroupsEnter = myGroups.enter().append("g"); 
myGroupsEnter.append("line"); 
myGroupsEnter.append("polygon"); 
// ... 

// update selection -- this will also contain the newly appended elements 
myGroups.select("line").attr(...); 
// ... 

// exit selection 
myGroups.exit().remove(); 

這裏有兩件事情值得進一步的解釋。首先,輸入選擇中添加了新元素的元素合併到更新選擇中。也就是說,如果在更新選擇中發生相同的事情,則不需要在輸入選擇中的元素上設置屬性。這使您可以添加新元素並更新現有元素,而無需複製代碼。

第二件事對隨後調用更新數據變得重要。由於綁定數據的元素不是實際繪製的元素,因此需要將新數據傳播給它們。這就是.select()所做的。也就是說,通過執行myGroups.select("line"),您會將綁定到g元素的新數據傳播到子元素line。因此設置屬性的代碼與輸入大小寫相同。

現在您可以在設置新屬性之前簡單地在所需的位置添加轉場。

+4

你是我翅膀下的風! – Mikhail

+1

根據d3文檔,'select()'應該返回一個元素。但是這裏似乎選擇了語句myGroups.select(「line」)。attr(...);'中的所有行元素。在我的實驗中,'selectAll()'看起來不起作用。你能解釋明顯的差異嗎? – brainjam

+3

'myGroups'包含多個元素,'.select()'爲每個元素執行選擇。也就是說,您正在爲多個元素選擇一個元素。 '.selectAll()'可能不起作用,因爲它不更新數據。 –