D3.js 被selection.filter弄糊涂了

D3.js 被selection.filter弄糊涂了,d3.js,D3.js,我很难理解selection.filter。我在一个空白文档中尝试了以下内容: d3.selectAll('rect') .data([1, 2, 3]) .filter(function(d) { return d>1; }) // [ Array[0] ] 我希望选择有2个元素,但它有0个元素。可能是因为我正在处理一个空的更新选择 d3.selectAll('rect') .data([1, 2, 3]) .enter() .filter(fun

我很难理解
selection.filter
。我在一个空白文档中尝试了以下内容:

d3.selectAll('rect')
    .data([1, 2, 3])
    .filter(function(d) { return d>1; })

// [ Array[0] ]
我希望选择有2个元素,但它有0个元素。可能是因为我正在处理一个空的更新选择

d3.selectAll('rect')
    .data([1, 2, 3])
  .enter()
    .filter(function(d) { return d>1; })

// []
现在看来我连一个选择都没有

如果DOM元素存在

d3.selectAll('rect').data([1, 2, 3])
  .enter().append('rect')
然后我选择并过滤

d3.selectAll('rect').filter(function(d) { return d>1; })

// [ Array[2] ]
它似乎起作用了。这是怎么回事?筛选器似乎适用于与任何DOM元素都不对应的选择,因此我希望它适用于上面的第一个示例。

Filter()函数只适用于已经绑定了数据的选择,即在调用了
.data()
之后。您链接到的示例实际上并不像它看起来那样工作--为了清楚起见,让我重申一下:

var node = svg.selectAll(".node")
  .data(bubble.nodes(classes(root))
    .filter(function(d) { return !d.children; })
  )
  .enter().append("g")

.filter()
函数实际上并不应用于此处的选择,而是应用于
bubble.nodes()
返回的数组。然后将其传递到
.data()
。这正是在类似您的情况下所要做的——如果您可以过滤决定选择的数据,则无需过滤选择。

!非常感谢,拉尔斯。这是我通常做的,我只是看到了这个例子,想用惯用的方式做一些事情。没问题,这个例子中的缩进很容易误导。