在Mike发布的here答案中,他概述了基于索引或自定义过滤器对匹配元素应用更改的三种不同方法。我试图澄清,希望更多的人,而不仅仅是我自己,这些解决方案中的实际选择。
所以给定一个带有6个SVG rects with class .bar
的文档,我们有不同的选择以及它们返回的内容:
d3.select(“。bar”):
[Array[1]
0: rect.[object SVGAnimatedString]
length: 1
parentNode: html
__proto__: Array[0]
d3.selectAll( “条”):
[Array[6]
0: rect.[object SVGAnimatedString]
1: rect.[object SVGAnimatedString]
2: rect.[object SVGAnimatedString]
3: rect.[object SVGAnimatedString]
4: rect.[object SVGAnimatedString]
5: rect.[object SVGAnimatedString]
length: 6
parentNode: html
__proto__: Array[0]
$( “条”):
[
<rect class="dataBars" x="53.191489361702125" width="212.7659574468085" y="4.761904761904762" height="11.11111111111111"></rect>,
<rect class="dataBars" x="74.46808510638297" width="372.3404255319149" y="20.634920634920636" height="11.11111111111111"></rect>,
<rect class="dataBars" x="127.6595744680851" width="212.7659574468085" y="36.507936507936506" height="11.11111111111111"></rect>,
<rect class="dataBars" x="31.914893617021274" width="212.7659574468085" y="52.38095238095238" height="11.11111111111111"></rect>,
<rect class="dataBars" x="159.5744680851064" width="265.9574468085106" y="68.25396825396825" height="11.11111111111111"></rect>,
<rect class="dataBars" x="234.04255319148936" width="138.29787234042553" y="84.12698412698413" height="11.11111111111111"></rect>,
]
现在这里变得更加棘手(至少对我来说),说我想将style
应用到第三个矩形,可以使用
d3.selectAll(".bar")[0][2]
但是如果我们想要使用d3.selection.attr()
,则返回
TypeError: Property 'style' of object #<SVGRectElement> is not a function
但我们可以将这个选择包装好
d3.select(d3.selectAll(".bars rect")[0][2]).style("fill", "red")
这将按预期工作。
然后,如果我们想要应用过滤器,例如
filter(function (d) { return d === 5 || d === 15;}
必须使用d3.selectAll(".bar")
,d3.select(d3.selectAll(".bar"))
将无法正常使用。
我已经阅读了Mike关于选择的优秀教程和文档,但就在我认为我已经弄明白的时候,有些东西突然出现并让我感到惊讶。那么这些选择之间的区别是什么,以及如何知道何时使用哪一个?非常感谢,对不起,我很抱歉!
答案 0 :(得分:5)
我过去曾尝试这样做并遇到类似的错误。然后我意识到我并没有真正遵循预期的API。第二个是你开始按索引访问选择元素,你就远离了人迹罕至的路径。
所以,如果你想为第三个栏设置样式,你就可以
d3.selectAll(".bar").style("color", function(d,i) { return i === 2 ? "red" : null; } )
如果你的选择是比这更嵌套的一个级别,那就把它function(d,i,j)
同样地从那里开始。等
答案 1 :(得分:3)
通常,您不应通过索引访问返回选择的元素,而应过滤或使用子选择。这样,您可以毫无问题地应用.attr()
和.atyle()
。原因是D3不返回DOM元素的“纯”数组(如jquery所做),而是返回支持D3操作的包装器中的元素。它仍然表现得像一个数组 - 如果你索引它,你会得到一个“纯粹的”DOM元素。您还可以向d3.select()
提供一个DOM元素,它将生成围绕此元素的包装器,以启用所有D3内容。
如果你看一下documentation for filter()
,你会发现一些关于如何使用它和子选择的例子。例如,您可以使用这些技术来获取选择的第三个元素。使用.filter()
函数只有在将数据绑定到要过滤的对象时才有意义,否则子选择应该按照您的意愿执行。