D3、Jquery中的选择

Selections in D3, Jquery

本文关键字:选择 Jquery D3      更新时间:2023-09-26

在Mike发布的答案中,他概述了基于索引或自定义过滤器将更改应用于匹配元素的三种不同方法。我正在努力澄清这些解决方案中的实际选择,希望能让更多的人而不仅仅是我自己。

因此,给定一个具有.bar类的6个SVG矩形的文档,我们有这些不同的选择以及它们返回的内容:

d3.select(".bar"):

[Array[1]  
0: rect.[object SVGAnimatedString]  
length: 1  
parentNode: html  
__proto__: Array[0]  

d3.selectAll(".bar"):

[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]  

$(".bar"):

[
<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关于选择的优秀教程和文档,但就在我想明白的时候,突然出现了一些东西,让我大吃一惊。那么,这些选择之间有什么区别,我如何知道什么时候该使用哪一个呢?非常感谢,很抱歉发了这么长的帖子!

我过去曾尝试过这样做,但也遇到过类似的错误。然后我意识到我并没有真正遵循预期的API。当你开始通过索引访问选择元素的那一刻,你就偏离了常规。

参见嵌套选择

所以,如果你想设计你的第三个酒吧,你可以做

d3.selectAll(".bar").style("color", function(d,i) { return i === 2 ? "red" : null; } )

如果您的选择比它多嵌套一级,则将其设为function(d,i,j),然后类似地从那里开始。等等

通常,您不应该通过索引访问返回选择的元素,而应该过滤或使用子选择。通过这种方式,您可以毫无问题地应用.attr().atyle()。原因是D3没有返回DOM元素的"纯"数组(就像jquery一样),而是返回支持D3操作的包装器中的元素。不过,它的行为仍然有点像一个数组——如果对它进行索引,就会得到一个"纯"DOM元素。您还可以为d3.select()提供一个DOM元素,它将围绕这个元素生成一个包装器,该包装器启用所有D3内容。

如果你看过filter()的文档,你会发现一些关于如何使用它和子选项的例子。例如,您可以使用这些技术来获取选择的第三个元素。只有在将数据绑定到要筛选的对象时,使用.filter()函数才有意义,否则子选择应该按您的意愿进行。