In D3, we need to select a visual element in the DOM before we can do any modification or any sort of operation on it. D3 selection APIs are provided by the module named d3-selection.
d3-selection provides two methods to target any DOM element:
- d3.select(selector) : This method selects the first element that matches the specified selector string. If no elements match the selector, returns an empty selection. If multiple elements match the selector, only the first matching element (in document order) will be selected.
NOTE : D3 uses the W3C standardized selector strings. If you are familiar with CSS3 selectors then you will find D3 selectors to be very much similar.
- d3.selectAll(selector) : Selects all elements that match the specified selector string. The elements will be selected in document order (top-to-bottom). If no elements in the document match the selector, or if the selector is null or undefined, returns an empty selection.
Before proceeding further lets examine the return values of these selector methods. We need to have a clear understanding of the values returned from these methods because the return value allows us to do method chaining – a common pattern in D3.
For this open your browser console and type the following code:
The output you get in the console is:
In the screenshot you can see d3.select() returns a plain JS object called Selection. The Selection object has two important properties viz. _groups and _parents. Both of these properties are array. The _groups array contains our selected element (body in this case). So d3.select() and d3.selectAll() returns a new selection which can be used to chain other methods (e.g attr(), style() etc) to this selection.
NOTE : To get the DOM references of all the elements in the selection, D3 provides the node() and nodes() methods in the selection.
Now that we know how to select DOM elements lets look at how to modify them.
D3 provides selection.style() API to add or change style of a selection. It has the following syntax:
- If we specify a value, it will set the style property with the specified name to the specified value on the selected elements and returns the current selection.
- The value can be a constant or a function. If the value is a constant, all the selected elements will be given the same style value. If the value is a function, it will be invoked for each of the selected elements in the given order. The function will be passed with three parameters:
Current datum (d) : This is the data bound to the current element. (We will see what this is in Data Binding section).
Current index (i) : The current index in the iteration.
Current group (nodes) : The DOM reference array of the selection.
The function’s return value is then used to set each element’s style property. A null value will remove the style property.
NOTE : This kind of functions are very common in D3 and are known as the accessor functions. All the accessor functions has the same set of arguments passed to them.
There is an optional priority which can be null or the string important (without the exclamation mark). This is the same !important we use in the CSS.
If a value is not specified, returns the current computed value of the specified style property for the first (non-null) element in the selection.
This is generally useful only if you know the selection contains exactly one element.
NOTE: Almost all the APIs in D3 follow the same pattern as described for the style() API.
To achieve the same style using an accessor function
Note the method chaining pattern used in the above example. The selectAll() returns a new selection and the attr() uses that selection to change the attributes of the elements in the selection and then returns the current selection. Here each attr() is called for each of the elements in the selection in order.
NOTE : By convention, selection methods that return the current selection(e.g style(), attr()) use four spaces of indent, while methods that return a new selection(e.g select(), selectAll(), append()) use only two. This helps reveal changes of context by making them stick out of the chain.
Some HTML elements have special properties that are not addressable using attributes or styles, such as a checkbox’s checked boolean. We can use the following method to get or set the properties.
Adding or removing classes
We can assign or unassign classes to the selected elements using this method. If the value is true the class(es) specified in the names will assigned to each element in the selection. If the value is false , the classes will be removed from the elements.
The names argument is a string of space-separated class names.
D3 provides to methods to deal with the contents of an element:
- selection.text([value]) : Sets the text content to the specified value on all selected elements, replacing any existing child elements.
- selection.html([value]) : Sets the inner HTML to the specified value on all selected elements, replacing any existing child elements.
NOTE : selection.html() is only supported on HTML elements. SVG elements and other non-HTML elements do not support the innerHTML property, and thus are incompatible with selection.html().
Appending an element
This is one of the most frequently used method in D3 along with selectAll(). This method appends a new element of the specified type (tag name) as the last child of each selected element.
This method returns a new selection containing the appended elements as evident from the following screenshot:
Inserting an element
This method inserts a new element of type (tag name) before the first element matching the specified before selector for each selected element. This method returns a new selection containing the appended elements.
Removing an element
Removes the selected elements from the document. Returns this selection (the removed elements) which are now detached from the DOM.
Other useful selection methods
Filtering elements from a selection
This method filters the selection and returns a new selection containing only the elements for which the specified filter is true. The filter may be specified either
as a selector string or a function.
To filter a selection of table rows to contain only even rows:
This method returns a new selection merging the selection and the specified other selection. This method is commonly used to merge the enter and update selections after a data-join. We will see this in action in the Data Join section.
The each() method
The each() method invokes the specified function for each of the selected element. The ‘this’ inside the function refers to the current element of the selection being iterated.
So that covers the essential selection methods in D3. We saw how we can select one or multiple elements using the selectors methods. After selecting we can modify them and we can add or remove elements to the DOM using D3.
That’s all for this section. Next up is how to deal with data and bind data to our selection so that we can represent that data using SVG diagrams.