Reputation: 12704
I'm having a hard time understanding selection.filter
. I tried this, in a blank document:
d3.selectAll('rect')
.data([1, 2, 3])
.filter(function(d) { return d>1; })
// [ Array[0] ]
I expected the selection to have 2 elements, but it has 0. Maybe it's because I'm working with an empty update selection...
d3.selectAll('rect')
.data([1, 2, 3])
.enter()
.filter(function(d) { return d>1; })
// []
Now it seems I don't even have a selection.
If the DOM elements exist
d3.selectAll('rect').data([1, 2, 3])
.enter().append('rect')
and then I select and filter
d3.selectAll('rect').filter(function(d) { return d>1; })
// [ Array[2] ]
it seems to work. So what's going on here? Filter seems to work in this example on selections that don't correspond to any DOM elements, so I'd expect it to work in my first example above.
Upvotes: 1
Views: 190
Reputation: 109252
The .filter()
function only works on selections that have data bound to them already, i.e. not after you've called .data()
on them. The example you've linked to doesn't actually work the way it seems to do -- let me reindent for clarity:
var node = svg.selectAll(".node")
.data(bubble.nodes(classes(root))
.filter(function(d) { return !d.children; })
)
.enter().append("g")
The .filter()
function isn't actually applied to a selection here, but to the array that bubble.nodes()
returns. This is then passed to .data()
. And this is exactly what you would do in a case like yours -- there's no need to filter the selection if you can filter the data that determines it.
Upvotes: 2