omic
omic

Reputation: 381

style and attr in D3.js

I'm new to D3.js and following the tutorial.

I'm confused why the circle.style("fill", "steelblue"); below doesn't take effect; but if put the style line after circle.enter().append("circle") line it can fill colors to all circles. To my understanding, the style is global, should be applied to all circles, or at least affect the existing circles in html in the following code.

//js
var svg = d3.select("svg");
var circle = svg.selectAll("circle").data([32, 57, 112, 293], function(d) { return d; });
circle.style("fill", "steelblue");
circle.enter().append("circle")
    .attr("cy", 60)
    .attr("cx", function(d, i) { return i * 100 + 30; })
    .attr("r", function(d) { return Math.sqrt(d); });
circle.exit().remove();



//html
<svg width="720" height="120">
<circle cx="40" cy="60" r="10"></circle>
<circle cx="80" cy="60" r="10"></circle>
<circle cx="120" cy="60" r="10"></circle>
</svg>

Thanks!

Upvotes: 0

Views: 586

Answers (1)

Cool Blue
Cool Blue

Reputation: 6476

The first time the code runs, the size of the circle selection is zero because there are no elements matching the key. All of the circle elements will be put in the exit selection. The data method returns the update selection which is initially empty, it's (second dimension) length is equal to the length of the first dimension of the first argument passed to .data, but each element of the selection is null. It's not until the enter method is executed that new nodes are created and the enter and update selections are merged.

If the code runs again, with one data element replaced with a new value for example, then the three matching nodes will be placed in the update selection and that will be returned by .data. The one that doesn't match will be placed in the exit selection and its old position in the update selection will be set to null. One placeholder object, with the new data element attached, will be placed in the enter selection which will end up with a reference to a newly created node after the .append and which will be merged into the update selection by .enter.

If you don't use a key function, then, first time, the three existing nodes will be in the update selection, along with one null value, and one placeholder will be put in the enter selection with data attached (with value of 293 in this case). The exit selection would be empty (length 0) and a new node will be created and added to the enter selection with the new data element bound to it. At this point, the update selection (circle) will have the enter selection merged with it. It's null entry having been replaced by the new node with the new data bound to it. This is a side effect of calling .enter.

However, if you then called the code again, with the order of the data element changed (still with the same set of values but all in different positions in the array), then the exit and enter selections will be empty, but the data value bound to all nodes will be changed. If you used a key in this case then nothing would be changed.

Upvotes: 2

Related Questions