I've been studying d3 for a job I'm doing, and tutorial after tutorial shows how to use .enter() to add elements, and .exit().remove() to remove elements. But when it comes to updating, it's either just a handwave implying there's a .update() property (there isn't), or they use .transition() for an animated change. If you're adding and removing some things, but setting all the old elements and all new elements with the same data-driven attributes, I didn't find any good examples out there. This is it:

var chart = d3.select("svg").selectAll("rect").data(data);
chart.enter().append("rect");  // creates empty rects where needed
chart  // this is it, where we set attributes for all old and new rects
 .attr("x", function(d) {return d.xproperty;})
 .attr("y", function(d) {return d.yproperty;})
 .attr("width", function(d) {return d.widthproperty;})
 .attr("height", function(d) {return d.heightproperty;});
chart.exit().remove();  // get rid of any leftovers from longer data
Of course, xproperty et. al. are the properties in your data; I'm using things like timestamps and voltage, but you could be using just about anything.

The main difference between this and what I saw in the tutorials is that the .attr() calls are not chained to .enter(), which would only apply to the brand-new rects. Those left over from the previous run, with different data, would remain with their old data. And it would be silly to duplicate the same block of code for updating old elements as for creating new ones.

Back to blog or home page

last updated 2012-06-29 14:54:13. served from tektonic.jcomeau.com