D3.js d3过滤器选择不工作?

D3.js d3过滤器选择不工作?,d3.js,D3.js,要么我没有正确使用d3,要么就是它有问题。我可以把这个问题概括成几行。我在Chrome调试器中加载了d3。让我们从一个空选项开始 d3.selectAll("nonexistant").empty() > true 并将一些数据绑定到它 d3.selectAll("nonexistant").data([1,2,3,4]) > [Array[4]] 很好,所以它是四号的。让我们检查一下: 嗯,我想这是因为没有DOM元素,但是更新选择是空的,因为没有以前的元素。让我们进入enter

要么我没有正确使用d3,要么就是它有问题。我可以把这个问题概括成几行。我在Chrome调试器中加载了d3。让我们从一个空选项开始

d3.selectAll("nonexistant").empty()
> true
并将一些数据绑定到它

d3.selectAll("nonexistant").data([1,2,3,4])
> [Array[4]]
很好,所以它是四号的。让我们检查一下:

嗯,我想这是因为没有DOM元素,但是更新选择是空的,因为没有以前的元素。让我们进入enter选项

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
不确定enter选择导致错误的原因,(更新:在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的本机阵列:

d3.selectAll("nonexistant").data([1,2,3,4].filter(odds)).enter().append("p").size()
> 2
d3文档似乎没有区分绑定了DOM元素和未绑定DOM元素的选择。似乎我应该能够在方法链中的任何位置粘贴
过滤器
(并在任何选择上调用
大小
),并在没有类型错误的情况下获得正确的结果。当然,
filter
也支持需要DOM元素的CSS选择器,但我这里不使用它们

我想知道的是:d3所做的和我所期望的不匹配。我对选择有多大程度的误解,哪些操作对选择有效?文件在多大程度上不清楚?这些行为是否符合bug的条件?

来自
.enter()
方法:

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

调用其他任何东西都不会产生有用的结果。这是一个bug、一个副作用还是一个特性,可能还有争议。几乎在所有情况下,它都不会产生任何障碍,除非您需要知道此选择的
size()
,以了解从传递到
data()
的数组中有多少基准尚未创建元素

但是,一旦在输入的选择上调用
append()
,它就会像任何正常选择一样表现良好。实际上,
append()
正在返回一个新的选择,因此它
==
enter()的返回值

此时,您还可以检查此选择的
size()
,因此实际上,只有在调用
append()
之前需要知道大小时,它才算是一个问题

如果您甚至不需要在
赔率(d)=false
的位置追加元素,那么使用本机数组
过滤器是解决方案,这是正确的

当您已经创建绑定到
[1,2,3,4]
的DOM节点(例如,在事件处理程序中,当用户单击“突出显示所有赔率”按钮)时,过滤器非常有用

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

d3.selectAll('p').filter(odds).css('color', 'red')