newbie doesn't understand d3 `update()`

OK, so I have a dataset that I’m trying to visualize with d3. Each data point has a number of attributes. The strategy I’m trying to use is to create a ‘g’ for each datapoint. Then append elements to each one of those 'g’s, with each additional element representing an additional attribute of the data.

I’m able to use the selectAll().data().enter().append() pattern to make the first pass work. In this pass, I create each ‘g’ and append the element that represents the first attribute of each data point.

But now I want to pass through a second time. My understanding (which evidently is wrong) is that I need to selectAll() the 'g’s that I created in the first pass, and then data().update().append() on that selection. But evidently update() is not a function!

See the fail here.

Help?

Thanks!

OK…so I learned by trial and error that in the second pass, it works if I do selectAll.data().append() instead of selectAll.data().update().append().

So I suppose my problem is solved, but I’d love it if someone could explain why.

The Venn diagram in this article makes me think that I have to call update() whenever I want to modify elements that already exist and are then joined to the data. But apparently that’s not true?

Thanks!

I’m not great at this, but I’ll give it a try. Where it says below the Venn diagram “Data points joined to existing elements produce the update (inner) selection”. It’s saying you automatically pick up to update any elements that happen to already exist when you do the selectAll. So even if you had several tags hard coded in an html page, and used d3 to select them, those would start in the update section. When you did the selectAll('g.datapoints') the second time, you are picking up the DOM elements created by the previous .enter() function. You also already have the data referenced in the svg variable you created, so you don’t even need the second .data(data).

  svg
    .selectAll('g')
    .data(data)
    .enter()
    .append('g')
      .attr('class', 'datapoint')
      .attr('transform', d => `translate(${d.x}, ${0.5*chartHeight})`)
    .append('circle')
      .attr('r', d => d.r)
      .attr('fill', 'black')

  svg.selectAll('g.datapoint')
    .append('path')
      .attr('stroke', 'black')
      .attr('stroke-width', '1px')
      .attr('fill','none')
      .attr('d', d => `M0 0 l${d.y[0]} ${d.y[1]}`)

1 Like