2016-04-07 67 views
2

我需要更改svg容器中由d3創建的所有形狀的順序。但我無法做到。 JSFiddle中的以下腳本在本地執行時會給出「a和b未定義」。應該如何糾正?如何在d3中對形狀選擇進行排序

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

svg.append("rect") 
.attr({x:0,y:0,height:10,width:10,fill:'yellow'}) 
.attr("sort",3); 
svg.append("rect") 
.attr({x:0,y:20,height:10,width:10,fill:'red'}) 
.attr("sort",2); 
svg.append("rect") 
.attr({x:0,y:40,height:10,width:10,fill:'blue'}) 
.attr("sort",1); 

d3.selectAll("rect").sort(function(a,b){return a.attr("sort")-b.attr("sort")}); 

d3.selectAll("rect") 
.each(function(d,i){alert(d3.select(this).attr("sort"))}); 
+0

更好地嘗試對數據集進行排序,然後調用selection.sort()對元素進行重新排序。 –

+0

你是什麼意思? – tic

+2

'sort'裏面的'a'和'b'不是對選擇的引用(因此它們沒有'.attr()'方法),它們是綁定到這些選擇/元素的數據的引用。在你的情況下,'a'和'b'都是'null',因爲你沒有綁定數據。綁定數據涉及調用d3的'data()'方法,並使用'enter()'來處理它們的'append()'。說了這麼多,排序只改變他們在DOM中的順序,而不是在屏幕上(這是x和y的用途)。這是你的意圖嗎? – meetamit

回答

2

你需要排序是這樣的:的

var rects = d3.selectAll("rect")[0].sort(function(a, b) { 
    return d3.select(a).attr("sort") - d3.select(b).attr("sort") 
}); //here rects will store the correct sorted order rectangle DOMs. 

,而不是做這樣的:

d3.selectAll("rect").sort(function(a,b){return a.attr("sort")-b.attr("sort")}); 

我們改變矩形按排序這樣做:

rects.forEach(function(rect, i){ 
    d3.select(rect).attr("y", (i*20));//change the attribute of y 
}) 

工作代碼here

注意:我只是根據您提供的信息回答這個問題,但正確的做法是按照@meetamit在評論中建議的數據方式。

+0

我的例子是一個玩具的例子。我的目標是改變形狀元素的前後(z-次序)優先級,我想最簡單的方法是對形狀選擇進行排序。我已經完成了你的代碼來達到我的目標。我認爲這是正確的做法。最初的順序是藍色 - 紅色 - 黃色;最後一個是yellow-red-blue:https://jsfiddle.net/b09zbcu8/1/ – tic

+0

只是另一個問題:[0]在d3.selectAll(「rect」)[0]中意味着什麼? – tic

+0

'd3.selectAll(「rect」)'給出一個數組元素選擇的數組。所以爲了獲得選擇中的所有元素,我們做'd3.selectAll(「rect」)[0]'這裏0是第一個元素。 – Cyril

相關問題