D3.js

powerful SVG-based visualization library for Javascript

Basics

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

  1. Append (i.e. create) the specified selector elements from the enter selection
  2. Remove exiting elements, i.e. performing exit().remove()
  3. Merge the newly created elements from the enter selection into the existing update 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)
text.attr("class", "update");

// ENTER (#4)
text.enter().append("text")
    .attr("class", "enter")
    // MERGE (#5)
  .merge(text)
    .text(function(d) { return d; });

// EXIT (#6)
text.exit().remove();

The pattern typically consists of

  1. selectAll() :: get a selection of the type or class of elements you want to update. This selection may be empty.
  2. data() :: bind some data to the elements in the selection. This prepares the enter, update, and exit selections.
  3. Perform any stand alone updates to those already existing elements found in the update selection.
  4. enter().append() :: get the enter selection of placeholders and create them using append(). Changes made along this chain are applied only to these newly created elements.
  5. 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.
  6. exit().remove() :: get the exit selection of elements that do not have freshly bound data and delete them using remove(). Updates can be performed on the exit 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