d3过滤器选择不起作用?

时间:2014-08-16 21:33:24

标签: d3.js

要么我没有正确使用d3的selection.filter,要么它是错误的。我可以将这个问题提炼成几行。我在加载了d3的Chrome调试器中。让我们从一个空选择开始

d3.selectAll("nonexistant").empty()
> true

并将一些数据绑定到它。

d3.selectAll("nonexistant").data([1,2,3,4])
> [Array[4]]

好,所以它有四个。我们来看看selection.size

d3.selectAll("nonexistant").data([1,2,3,4]).size()
> 0

嗯,我想那是因为还没有DOM元素更新选择是空的,因为没有以前的元素。所以让我们 make 访问输入选择。

d3.selectAll("nonexistant").data([1,2,3,4]).enter()
> [Array[4]]
d3.selectAll("nonexistant").data([1,2,3,4]).enter().size()
> TypeError: undefined is not a function
d3.selectAll("nonexistant").data([1,2,3,4]).enter().append("p").size()
> 4

不确定为什么输入选择会导致错误(更新:在v3.4.12中修复)但是无论如何,如果我们尝试使用文档中的示例函数进行过滤,

function odds(d, i) { return i & 1; }
d3.selectAll("nonexistant").data([1,2,3,4]).filter(odds);
> [Array[0]]
d3.selectAll("nonexistant").data([1,2,3,4]).enter().filter(odds);
> []
d3.selectAll("nonexistant").data([1,2,3,4]).enter().append("p").filter(odds)
> [Array[2]]

为什么在没有绑定DOM元素时会静默过滤掉所有元素?当我已经拥有DOM元素时,它似乎确实有效。但这感觉很无用,因为我不想为我丢弃的数据创建元素。也许如果我早点放过滤器?

d3.selectAll("nonexistant").data([1,2,3,4]).filter(odds).enter().append("p").size()
> TypeError: undefined is not a function
d3.selectAll("nonexistant").data([1,2,3,4]).enter().filter(odds).append("p").size()
> TypeError: undefined is not a function

不。似乎可以采用JS在数组上的原生filter

d3.selectAll("nonexistant").data([1,2,3,4].filter(odds)).enter().append("p").size()
> 2

d3文档似乎没有区分具有DOM元素绑定的选择和不绑定DOM元素的选择。似乎我应该能够将filter粘贴到我的方法链中(并在任何选择上调用size),并获得正确的结果而不会出现类型错误。当然,filter也支持需要DOM元素的CSS选择器,但我不在这里使用它们。

我想知道的事情: d3正在做什么和我期望的不匹配。我在多大程度上怀疑对选择的误解以及哪些操作对他们有效?文件在多大程度上不清楚?这种行为是否有资格成为错误?

1 个答案:

答案 0 :(得分:8)

来自.enter()方法的the documentation

  

...输入选择仅定义appendinsertselectcall运算符;在修改任何内容之前,必须使用这些运算符来实例化输入节点。 (输入选择也支持empty以检查它们是否为空。)

调用其他任何内容都不会产生有用的结果。无论这是一个错误,副作用还是一个特征,都可能引起争议。在几乎所有情况下,它都不会产生任何障碍,除非你需要知道这个选择size()以找出你传递给data()的数组中有多少个基准还没有创建元素。

虽然您在输入选项上调用append(),但它表现良好,就像任何正常选择一样。事实上,append()正在返回一个新的选择,因此它!==的返回值为enter()

当您还可以检查此选项的size()时,如果您需要知道调用append()之前的大小,那么它真的只会成为一个问题。

您认为使用原生数组filter是一种解决方案,如果您不需要将元素追加到odds(d) == false

当您已经创建了绑定到<p>的DOM节点(例如[1,2,3,4] s)时,过滤器非常有用,并且(例如,在用户单击&#时,在事件处理程序中) 34;突出显示你打电话的所有赔率&#34;按钮

d3.selectAll('p').filter(odds).css('color', 'red')
顺便说一下,这是一个写得很好的问题。