Reputation: 1998
I am using d3v4 and within the html document I have 20 g.node elements, with 4 having the value: d.nameY === "responded No".
The following statement works correct:
d3.select("g.sankeyFrame.single")
.selectAll("g.node")
.filter( function(d) { return d.nameY === "responded No";})
.size();
It returns 4 as desired.
However, the following data join doesn't return the expected selection:
d3.select("g.sankeyFrame.single")
.selectAll("g.node")
.data(["responded No"], function(d){ return d.nameY;})
.size();
It returns 0, it should return all 4 g.node elements, where d.nameY === 4.
What possible reason prevents the data join from working? (The code base is too large to publish here)
Upvotes: 1
Views: 276
Reputation: 102194
What possible reason prevents the data join from working?
No reason at all. It is working. And the result is not wrong, that's the expected behaviour. You have another problem here.
To show you the problem, let's create a very simple demo, which appends 20 <div>
s, 4 of them with the datum "foo"
. Here is the code using your first approach, with filter
:
var p = d3.select("body")
.selectAll(null)
.data(d3.range(20).map(function(d) {
return d < 4 ? "foo" : "bar"
}))
.enter()
.append("div")
.html(String);
var filtering = d3.selectAll("div")
.filter(function(d) {
return d === "foo"
}).size();
console.log("size is: " + filtering)
<script src="https://d3js.org/d3.v4.min.js"></script>
Now let's see your second approach:
d3.select("g.sankeyFrame.single")
.selectAll("g.node")
.data(["responded No"], function(d){ return d.nameY;})
.size();
You have two problems here:
nameY
in a simple, flat array like ["responded No"]
. That's why your selection's size is 0
.var p = d3.select("body")
.selectAll(null)
.data(d3.range(20).map(function(d) {
return d < 4 ? "foo" : "bar"
}))
.enter()
.append("div")
.html(String);
var dataBinding = d3.selectAll("div")
.data(["baz"])
.size();
console.log("size is: " + dataBinding)
<script src="https://d3js.org/d3.v4.min.js"></script>
That point #2 is the most important here: the size of the update selection returned by data()
is the size of its array.
Finally, to clearly show that the data()
is working, let's see the datum of each <div>
:
var p = d3.select("body")
.selectAll(null)
.data(d3.range(20).map(function(d) {
return d < 4 ? "foo" : "bar"
}))
.enter()
.append("div")
.html(String);
var dataBinding = d3.selectAll("div")
.data(["baz"])
.size();
d3.selectAll("div").each(function(d, i) {
console.log("div number " + i + " - datum: " + d)
})
<script src="https://d3js.org/d3.v4.min.js"></script>
Upvotes: 2