Kevin, regarding your original question and fiddle:
// Why does "select" work, but not "selectAll"?
legend.selectAll("text").text(function(d) { return d; });
legend.selectAll("rect").style("fill", color);
To summarize the observations:
- the initial data has two elements
- the initial legend looks correct:
a) there are two legend elements and
b) both fill and text are according to data
- the updated data has three elements
- the updated legend looks only partially correct:
a) there are three legend elements and
b) all three fill colors are correct, however
c) the text is only correct in the last, just added, legend element
So, why is the fill color correct and the text isn't? And why is the text correct for the enter() selection, but not for the update() selection? This has not so much to do with what kind of selection is returned, but more with how bound data propagates through the document.
In your code, the "fill" style update doesn't rely on bound data, because it directly uses the variable color. Therefore the color is always correct.
However, the text update does rely on the datum bound to the text element, which is a child of the g.legend element. When joining updated data, it is the g elements that receive the new data:
// Update legend
var legend = svg.selectAll(".legend")
.data(color.domain());
So, the question is how will the child text element receive this new data? There are only five methods in D3 that can affect the bound data, and selectAll is not one of those:
When a new g.legend element is created (enter), the text element is appended and both parent and child will own the same data. Therefore everything looked fine for all entered legend elements.
During update you used selectAll to change the text, and this operation will not copy data from parent to child. When you use selection.select it will copy data (note d3.select does not propagate data).
Tore
On Saturday, November 24, 2012 10:41:24 AM UTC-8, kank wrote: