Question

What exactly does extra select() on enter() selection do and why does it not have selectAll()?

Now here I am probably supposed to post more text to "meet your quality standards", but I am quite sure the question is precise enough and hopefully not too stupid. I spent few days reading through various d3 tutorials and docs, and this part still escaped from me.

Was it helpful?

Solution

Calling select on the enter selection is rare; it is much more common to use append or insert instead. Yet the end result of all three of these methods is the same: it specifies how to instantiate elements in the enter selection.

When you perform a data-join, three new selections are returned:

  • the update selection: selected elements that correspond to the data
  • the exit selection: any leftover elements (no corresponding data)
  • the enter selection: any leftover data (no corresponding elements)

Since the enter selection is leftover data, there are by definition no corresponding elements. The enter selection thus initially contains placeholder nodes which you must instantiate into proper elements. You almost never see these nodes because you immediately tell D3 how to create the missing elements, typically by calling append or insert. These methods create new elements and insert them into the DOM. (The parent node is determined by the previous select, as described in the nested selections tutorial.)

In rare cases, you might want to do something beyond the standard append or insert for instantiating entering nodes. For example, the standard append method always creates elements of the same name (such as "div" or "rect"). If you wanted to specify the name dynamically, you could use select instead and pass in a function to create the new elements (as discussed in this thread in the d3-js mailing list):

enterSelection.select(function(d) {
  return this.appendChild(document.createElement(d.name));
});

In fact, if you look at how append is implemented, you'll see that it's just a wrapper on top of select. A slightly simplified implementation is:

d3.selection.prototype.append = function(name) {
  return this.select(function() {
    return this.appendChild(document.createElement(name));
  });
};

These example implementations are simplified because they don't deal with namespaced SVG elements. For this reason it's easier to use the built-in methods, and these examples are solely to explain how D3 works internally.

OTHER TIPS

Calling .select() on an .enter() selection does the same thing it does for other selections -- you can use it to narrow down what you select further. Having .selectAll() wouldn't really make sense as the .enter() selection refers to things that are not actually there yet. Therefore you would only be able to select the entire selection again (as there're no distinguishing characteristics).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top