D3.js
powerful SVG-based visualization library for JavascriptBasics
Selections
Selections are groups of (references to) html elements. These selections can be acted on, merged into other selections, and more. Selections are made with the selectAll(selector)
function, where selector
is a CSS selector string. selectAll()
can be called using D3 globally, or it can be called on an already existing selection.
Data
The data()
function sets data for a given selection of elements. That is, for the data array passed to to the data()
function, each element of the array is bound to each element in the selection. It is not always the case that there are the correct number of elements in the DOM for the data, so update
, enter
, and exit
selections are created. A call to data()
returns the update selection, which is a reference to the elements that already existed and now have newly bounded data. The enter
and exit
selections are covered further below. Additionally, the key function allows you to specify
Enter
The enter()
method returns the enter
selection corresponding to a selection and its assigned data. If there are more data elements than selection elements, new placeholder elements are created for those data elements without an already existing DOM element. The enter
selection is comprised entirely of placeholder elements, and they can be passed down the chain as references for a function such as append
to create.
Exit
The exit()
method returns the exit
selection corresponding to a selection and its assigned data. This selection is precisely opposite that of enter
; the exit
selection holds those currently created DOM elements that are left without a data element after the binding of data in data()
. References to these elements are returned by exit()
and can be passed down the chain to something like remove()
for deletion.
Append
The append(element)
function is responsible for creating elements in accordance to the placeholder elements present in a selection created by enter()
. For each placeholder element, it appends an element of the specified type to the DOM in the location corresponding to the selection on which it is called. The function then returns references to the appended elements for use on down the chain.
Join
The join()
function is newly introduced in D3v5, and serves to simplify some of update process. join
can take a selector string (like append), and will automatically
- Append (i.e. create) the specified selector elements from the
enter
selection - Remove exiting elements, i.e. performing
exit().remove()
- Merge the newly created elements from the
enter
selection into the existingupdate
selection
join
thus returns this merged selection, and you can call chained updates to all “now existing elements” as you would normally. This makes the typical use of the update pattern slightly nicer (e.g. removes the need to set the update
selection separately, the standard enter and exit operations, etc). The join
function can also still exert control over different selections like update
, enter
, and exit
if individual/separate updates need to be made. This can be done as follows: (finish later)
Update Pattern
The general D3 update pattern is the standard method by which elements are updated dynamically within a D3 visualization. In code the pattern generally looks roughly as follows:
// SELECTION & DATA (#1, #2)
let text = g.selectAll("text")
.data(data);
// UPDATE (#3)
.attr("class", "update");
text
// ENTER (#4)
.enter().append("text")
text.attr("class", "enter")
// MERGE (#5)
.merge(text)
.text(function(d) { return d; });
// EXIT (#6)
.exit().remove(); text
The pattern typically consists of
selectAll()
:: get a selection of the type or class of elements you want to update. This selection may be empty.data()
:: bind some data to the elements in the selection. This prepares the enter, update, and exit selections.- Perform any stand alone updates to those already existing elements found in the
update
selection. enter().append()
:: get theenter
selection of placeholders and create them usingappend()
. Changes made along this chain are applied only to these newly created elements.merge()
:: merge the enter selection with the original selection. The resulting selection contains all elements that exist in the DOM and have freshly bound data.exit().remove()
:: get theexit
selection of elements that do not have freshly bound data and delete them usingremove()
. Updates can be performed on theexit
selection before removal such as transitions.
On data
vs datum
Warning: Many people believe that selection.datum(data) is equivalent to selection.data(data) but this is only true if selection contains a single element. If selection contains multiple DOM elements, then selection.datum(data) will bind the entirety of data to every single element in the selection. In contrast, selection.data(data) only binds the entirety of data to the first element in selection. This is consistent with the data-join behavior of selection.data. [taken from here, reflects my intuition]
Plots
Drag
The d3.drag
module makes it easy to handle drag events associated with items in a selection. On a selection, you can use the .call(d3.drag()...)
syntax to specify a command triad of drag events: dragstarted
, dragged
, dragended
. These are
Version note: v5 doesn’t support the newer subject
object being passed