Indeed, the problem is in that part of the code: Demo
var layer = svg.selectAll(".layer")
.data(stack);
layer.enter()
.append("g")
.attr("class", "layer");
// Set the colors in the `update` cycle, not the `enter` cycle.
layer.style("fill", function (d, i) {
return color(i);
});
layer.exit()
.remove();
There is an interesting history of why this behaves this way. In earlier versions of D3, the enter
and update
set of elements were kept separate, just like update
and exit
events are still kept separate, i.e. operations you performed on the update
set would not be performed on the exit
set and vice-versa.
However, in version 2.0 of D3, it was decided that any element appended in the enter
phase would also become a part of the update
set. This was done because often the enter
set of elements and the update
set of elements needed to have the exact same operation performed on them (like in your case). To avoid this effect, you'll need to write the update
phase before the enter
phase.
Hence, in the enter
cycle, elements should be appended
and their initial attributes should should be set while their final values (which they should have in static state) should be set in the update
cycle.