D3.js hierarchy data structure and usage

Explains hierarchy in D3.js for visualizing hierarchical structures.

hierarchy is a library for visualizing hierarchical data and provides the following five drawing types.

  • Cluster
  • Tree (coming soon)
  • Treemap (coming soon)
  • Partition (coming soon)
  • Pack

For each drawing type, refer to its own page. This page explains the data structure common to all of them.

Data structure

First, prepare data for one node in the following format.

{
  "name": "A",
  "children": [{ },{ }]
}

If you want to add child or grandchild nodes, add objects with the same format to the children array. For terminal nodes, omit "children".

For example, if you want to draw a tree with the following structure,

prepare the following data structure.

var data =
{
    "name": "A",
    "children": [
      { "name": "B" },
      {
        "name": "C",
        "children": [{ "name": "D" }, { "name": "E" }, { "name": "F" }]
      },
      { "name": "G" },
      {
        "name": "H",
        "children": [{ "name": "I" }, { "name": "J" }]
      },
      { "name": "K" }
    ]
  };

Data structure conversion

To draw with the prepared data above, you need to convert the data structure twice.

Prepared hierarchical data -> hierarchy data structure -> data structure for each drawing type

To do this, you only need to call one function for each conversion. The structure is designed so that the same data structure can be converted into different drawings.

First, use the following function to convert to the data structure for hierarchy.

var root = d3.hierarchy(data);

root creates an object with the same structure as the prepared data and adds the following variables.

Object Description
node.data Reference to the original data associated with the node.
node.depth Position in the depth direction, with the root as 0. Integer.
node.height Maximum position from the terminal node to the child node. Terminal nodes are 0. Integer.
node.parent Reference to the parent node. null for the root.
node.children Reference to child nodes. Undefined for terminal nodes.

The root variable itself contains the object corresponding to the root node. In a structure like the previous diagram, you can access the object for node "B" as follows.

root.children[0]

List of hierarchy node functions

Nodes provide the following functions.

Function Description
node.ancestors() Returns an array from the node itself up through its parents to the root.
node.descendants() Returns an array tracking the node itself, children, grandchildren, and later descendants.
node.leaves() Returns an array of terminal nodes, or nodes with no children, related to this node.
node.path(target) Returns the shortest path from the node to the specified target node as an array including the nodes.
node.links() Returns an array of links connecting nodes in the following format:
[{"source": parent node, "target": child node}, ...]
node.sum() Calculates the sum of values set on descendant nodes.
Set a function as the argument, such as function(d) { return d.value; }.
Used to determine parent sizes in treemap, partition, and pack.
node.count() Counts the number of terminal nodes under this node and assigns it to node.value.
If this node is terminal, returns 1.
node.sort(compare) Sorts siblings using the specified comparison function compare.
node.each(function) Processes the specified node’s child and grandchild elements in order with the specified function.
node.eachAfter(function) Processes the specified node’s child and grandchild elements in order with the specified function.
Terminal nodes are called first. Nodes with child nodes are always processed after their child nodes.
node.eachBefore(function) Processes the specified node’s child and grandchild elements in order with the specified function.
Parents are called first. Nodes with parent nodes are always processed after their parent nodes.
node.copy() Returns a deep copy of the subtree starting from the specified node. The parent of the first element of the copied tree is null.