Reputation: 33
I have data like this:
[{
label: "ABC", p1: "23", p2: "3"
},
{
label: "EF", p1: "4", p2: "10"
},
{
label: "GV", p1: "5", p2: "15"
},
{
label: "FD", p1: "9", p2: "5"
},
{
label: "SDF", p1: "20", p2: "10"
},]
and i try to draw the data with:
var keys = ["p1", "p2"];
function draw(data) {
var p = d3.select("body")
.selectAll(".one")
.data(d3.stack().keys(keys)(data))
p.enter()
.append("p")
.attr("class", "one")
var span = p
.selectAll("span")
.data(function(d) { return d})
span
.enter()
.append("span")
.html(function(d) { return d})
span.exit().remove();
}
The p Elements are created with the first call of the draw function but not the span elements
I want to have a span element for each object in the data array
Why is it not created correctly the first time?
https://jsfiddle.net/h2ujjo98/
Upvotes: 0
Views: 97
Reputation: 108567
You are dealing with a nested selection. First, you don't need to re-bind the data to the nested element, it's automatically passed. Second, you aren't handling the enter, update and exit selections properly. Re-factored it would look like this:
// update selection
var p = d3.select("body")
.selectAll(".lol")
.data(d3.stack().keys(keys)(data));
// those being removed
p.exit().remove();
// those entering
var pEnter = p.enter()
.append("p")
.attr("class", "lol");
// append a span to those entering
pEnter.append("span");
// this is update + enter
p = pEnter.merge(p);
// update the update + enter selection's sub-selection
p.select("span").html(function(d) { return d });
Updated fiddle.
Upvotes: 1