-
Notifications
You must be signed in to change notification settings - Fork 4
Treemap Layout
Wiki ▸ API Reference ▸ Layouts ▸ Hierarchy ▸ Treemap Layout
Introduced by Ben Shneiderman in 1991, a treemap recursively subdivides area into rectangles. As with adjacency diagrams, the size of any node in the tree is quickly revealed. “Squarified” treemaps use approximately-square rectangles, which offer better readability and size estimation than naïve “slice-and-dice” subdivision. Fancier algorithms such as Voronoi and jigsaw treemaps also exist but are less common.
Like other classes in D3, layouts follow the method chaining pattern where setter methods return the layout itself, allowing multiple setters to be invoked in a concise statement.
# d3.layout.treemap()
Creates a new treemap layout with the default settings: the default sort order is by descending value; the default value accessor assumes each input data is an object with a numeric value attribute; the default children accessor assumes each input data is an object with a children array; the default size is 1×1.
# treemap(root)
# treemap.nodes(root)
Runs the treemap layout, returning the array of nodes associated with the specified root node. The treemap layout is part of D3's family of hierarchical layouts. These layouts follow the same basic structure: the input argument to the layout is the root node of the hierarchy, and the output return value is an array representing the computed positions of all nodes. Several attributes are populated on each node:
- parent - the parent node, or null for the root.
- children - the array of child nodes, or null for leaf nodes.
- value - the node value, as returned by the value accessor.
- depth - the depth of the node, starting at 0 for the root.
- x - the minimum x-coordinate of the node position.
- y - the minimum y-coordinate of the node position.
- dx - the x-extent of the node position.
- dy - the y-extent of the node position.
Note that this will modify the nodes that you pass in!
Although the layout has a size in x and y, this represents an arbitrary coordinate system; for example, you can treat x as a radius and y as an angle to produce a radial rather than Cartesian layout. In Cartesian orientation, x, y, dx and dy correspond to the "x", "y", "width" and "height" attributes of the SVG rect element.
# treemap.links(nodes)
Given the specified array of nodes, such as those returned by nodes, returns an array of objects representing the links from parent to child for each node. Leaf nodes will not have any links. Each link is an object with two attributes:
- source - the parent node (as described above).
- target - the child node.
This method is useful for retrieving a set of link descriptions suitable for display, often in conjunction with the diagonal shape generator. For example:
svg.selectAll("path")
.data(partition.links(nodes))
.enter().append("path")
.attr("d", d3.svg.diagonal());
# treemap.children([children])
If children is specified, sets the specified children accessor function. If children is not specified, returns the current children accessor function, which by default assumes that the input data is an object with a children array:
function children(d) {
return d.children;
}
Often, it is convenient to load the node hierarchy using d3.json, and represent the input hierarchy as a nested JSON object. For example:
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "MergeEdge", "size": 743}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality", "size": 3534},
{"name": "LinkDistance", "size": 5731}
]
}
]
}
]
}
The children accessor is first invoked for root node in the hierarchy. If the accessor returns null, then the node is assumed to be a leaf node at the layout traversal terminates. Otherwise, the accessor should return an array of data elements representing the child nodes.
# treemap.sort([comparator])
If comparator is specified, sets the sort order of sibling nodes for the layout using the specified comparator function. If comparator is not specified, returns the current group sort order, which defaults to descending order by the associated input data's numeric value attribute:
function comparator(a, b) {
return b.value - a.value;
}
The comparator function is invoked for pairs of nodes, being passed the input data for each node. A null comparator disables sorting and uses tree traversal order. Comparator functions may also be implemented using d3.ascending or d3.descending.
# treemap.value([value])
If value is specified, sets the value accessor to the specified function. If value is not specified, returns the current value accessor, which assumes that the input data is an object with a numeric value attribute:
function value(d) {
return d.value;
}
The value accessor is invoked for each input data element, and must return a number representing the numeric value of the node. This value is used to set the area of each node proportionally to the value.
# treemap.size([size])
If size is specified, sets the available layout size to the specified two-element array of numbers representing x and y. If size is not specified, returns the current size, which defaults to 1×1.
# treemap.padding([padding])
Get or set the padding for each treemap cell, in pixels. The padding determines the amount of extra space to reserve between the parent and its children; this space can be used to indicate the hierarchy through enclosure, or to reserve space for parent labels. If no padding is used, then the leaves of the tree will completely fill the layout's size.
If padding is specified, sets the new padding and returns the treemap layout; if padding is not specified, returns the current padding. The padding may be specified several ways:
- A null value disables padding; null is equivalent to zero.
- A number indicates uniform padding, in pixels, on all four sides.
- An array of numbers indicates the top, right, bottom and left padding values.
The padding may also be specified as a function which returns one of the three above values. This function is evaluated for each internal (non-leaf) node, and can be used to compute padding dynamically.
# treemap.round([round])
If round is specified, sets whether or not the treemap layout will round to exact pixel boundaries. This can be nice to avoid antialiasing artifacts in SVG. If round is not specified, returns whether the treemap will be rounded.
# treemap.sticky([sticky])
If sticky is specified, sets whether or not the treemap layout is "sticky": a sticky treemap layout will preserve the relative arrangement of nodes across transitions. The allocation of nodes into squarified horizontal and vertical rows is persisted across updates by storing a z attribute on the last element in each row; this allows nodes to be resized smoothly, without shuffling or occlusion that would impede perception of changing values. Note, however, that this results in a suboptimal layout for one of the two states. If sticky is not specified, returns whether the treemap layout is sticky.
Implementation note: sticky treemaps cache the array of nodes internally; therefore, it is not possible to reuse the same layout instance on multiple datasets. To reset the cached state when switching datasets with a sticky layout, call sticky(true) again. Since version 1.25.0, hierarchy layouts no longer copy the input data by default on each invocation, so it may be possible to eliminate caching and make the layout fully stateless.
# treemap.mode([mode])
If mode is specified, sets the layout algorithm. If mode is not specified, returns the current layout algorithm, which defaults to "squarify". The following modes are supported:
- squarify - rectangular subdivision; squareness controlled via the target ratio.
- slice - horizontal subdivision.
- dice - vertical subdivision.
- slice-dice - alternating between horizontal and vertical subdivision.