Nick
Nick

Reputation: 33

d3.js data not bound the first time

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

Answers (1)

Mark
Mark

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

Related Questions