20

I have the following code that works great, except when I iterate through my data set, the first row (the 0 index) is getting skipped.

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x",function(d){
    console.log(data);
    console.log(d);
    return xScale(d.year-1980);
  })

Note the console.log(data) returns my full data set, including the first row so the data is there!

But console.log(d) shows all rows after and including my second row of data - it drops the first row.

Any suggestions are welcome.

code_fish
  • 3,381
  • 5
  • 47
  • 90
user2846817
  • 231
  • 2
  • 3
  • 18
    I'm going to guess that you already have a `rect` element when you run that code. This element is getting matched to the first data row and thus the `.enter()` selection is missing it. – Lars Kotthoff Oct 04 '13 at 13:43
  • D3 is very powerful yet too vast. Its not widely used or published too. It harnesses the power of javascript entirely. Wish we had more tutorials on D3 – MarsOne Oct 04 '13 at 13:50
  • Move console.log(data) outside of your x function(d). It gets printed for each d. Maybe, you missed it. Then, post some of your output. – Phuoc Do Oct 04 '13 at 20:44
  • 1
    Thanks @LarsKotthoff , you saved at least few hours of my time ! – Aditya Jan 30 '15 at 12:12
  • I found this to be a lifesaver too. It took some time to come up on the searches. ```d3 selectall .data skipping first element``` didn't cut it. – EFH Dec 16 '15 at 20:19

2 Answers2

16

I had the same issue with similar code, and fixed it based on Lars Kothoff's comment.

In my case it made sense to change the selectAll to work on a g element, more like so:

svg.selectAll("g")
    .data(data);
    .enter()
    .append("g")
    .append("rect")
    .attr("x",function(d) { return xScale(d.year-1980); });

You could also differentiate the rects with a class:

svg.selectAll("rect.year")
    .data(data)
    .enter()
    .append("rect")
    .attr("x",function(d){ return xScale(d.year-1980); })
    .classed("year");
Community
  • 1
  • 1
James Manley
  • 175
  • 1
  • 6
2

Yeah, it seems if there is already an element, it gets "skipped" by the .enter()

<html>
<head>

<title>D3 Test</title>
</head>

<body>

</body>

<script type='text/javascript' src='https://d3js.org/d3.v4.min.js'></script>
<script type='text/javascript'> 

var theData = ["James", "Sue", "Ben"]

var p = d3.select("body").selectAll("p")    
    .data(theData)
    .enter()
    .append('p')
    .text(function (d,i) {
      return " i =" + i + "data =" + d;
    });

</script>

</html>

Produces

i =0data =James

i =1data =Sue

i =2data =Ben

But if you add a p element in there, it'll skip it.

...[previous code]

<body>
<p>Here is the first p tag that "James gets matched too"</p>

</body>

...[previous code]
James Holland
  • 1,102
  • 10
  • 17