2016-04-07 26 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

相关问题