Recursive space-filling layouts that subdivide rectangular area into smaller rectangles. Each node's area encodes a quantitative dimension, making treemaps ideal for visualizing hierarchical data with size/value properties.
Creates a treemap layout with configurable tiling methods, padding, and size options.
/**
* Creates a treemap layout function
* @returns Treemap layout function with configuration methods
*/
function treemap();
interface TreemapLayout {
/** Apply treemap layout to hierarchy root */
(root: Node): Node;
/** Get/set the tiling method function */
tile(tile?: TilingFunction): TreemapLayout | TilingFunction;
/** Get/set the layout size [width, height] */
size(size?: [number, number]): TreemapLayout | [number, number];
/** Get/set coordinate rounding */
round(round?: boolean): TreemapLayout | boolean;
/** Get/set padding on all sides */
padding(padding?: number | Function): TreemapLayout | number | Function;
/** Get/set inner padding between siblings */
paddingInner(padding?: number | Function): TreemapLayout | number | Function;
/** Get/set outer padding on all sides */
paddingOuter(padding?: number | Function): TreemapLayout | Function;
/** Get/set top padding */
paddingTop(padding?: number | Function): TreemapLayout | number | Function;
/** Get/set right padding */
paddingRight(padding?: number | Function): TreemapLayout | number | Function;
/** Get/set bottom padding */
paddingBottom(padding?: number | Function): TreemapLayout | number | Function;
/** Get/set left padding */
paddingLeft(padding?: number | Function): TreemapLayout | number | Function;
}Usage Examples:
import { hierarchy, treemap } from "d3-hierarchy";
const data = {
name: "root",
children: [
{ name: "A", value: 20 },
{ name: "B", value: 30, children: [
{ name: "B1", value: 15 },
{ name: "B2", value: 15 }
]},
{ name: "C", value: 50 }
]
};
// Basic treemap
const root = hierarchy(data)
.sum(d => d.value) // Required: compute values
.sort((a, b) => b.value - a.value); // Optional: sort by value
const treemapLayout = treemap().size([400, 200]);
const treemapRoot = treemapLayout(root);
// Access computed bounds
treemapRoot.each(node => {
console.log(node.data.name, node.x0, node.y0, node.x1, node.y1);
const width = node.x1 - node.x0;
const height = node.y1 - node.y0;
const area = width * height;
});
// Treemap with padding
const paddedTreemap = treemap()
.size([600, 400])
.padding(2)
.round(true);
const paddedRoot = paddedTreemap(root.copy());Treemap tiling methods determine how rectangles are subdivided. Each method balances different trade-offs between aspect ratios, stability, and visual appeal.
Creates rectangles with aspect ratios as close to 1:1 as possible using the algorithm by Bruls et al.
/**
* Squarified tiling method with configurable aspect ratio
* @returns Squarify tiling function with ratio configuration
*/
function treemapSquarify();
interface SquarifyTiling {
/** Set desired aspect ratio (golden ratio by default) */
ratio(ratio?: number): SquarifyTiling | number;
}
/** Golden ratio constant used by squarify */
const phi: number;Usage Examples:
import { treemap, treemapSquarify } from "d3-hierarchy";
// Default squarify (golden ratio)
const squarifyTreemap = treemap()
.tile(treemapSquarify())
.size([400, 300]);
// Custom aspect ratio
const customSquarify = treemap()
.tile(treemapSquarify().ratio(1)) // Perfect squares
.size([400, 300]);Subdivides recursively into halves, creating a binary tree structure.
/**
* Binary tiling method - recursively subdivides into halves
*/
function treemapBinary();Creates regular slice or dice patterns for predictable layouts.
/**
* Slice tiling - vertical subdivisions only
*/
function treemapSlice();
/**
* Dice tiling - horizontal subdivisions only
*/
function treemapDice();
/**
* Slice-dice tiling - alternates between slice and dice by depth
*/
function treemapSliceDice();Stable version of squarify that minimizes changes during data updates.
/**
* Resquarified tiling - stable version of squarify for animated transitions
*/
function treemapResquarify();Tiling Method Comparison:
import { treemap, treemapSquarify, treemapBinary, treemapSliceDice } from "d3-hierarchy";
// Compare different tiling methods
const tilingMethods = [
{ name: "squarify", method: treemapSquarify() },
{ name: "binary", method: treemapBinary() },
{ name: "sliceDice", method: treemapSliceDice() }
];
tilingMethods.forEach(({ name, method }) => {
const layout = treemap().tile(method).size([400, 300]);
const result = layout(root.copy());
console.log(`${name} layout:`, result);
});Treemap layouts support multiple padding options for fine-grained spacing control.
/**
* Set uniform padding on all sides
* @param padding - Pixels or function returning pixels
*/
padding(padding?: number | ((node: Node) => number)): TreemapLayout;
/**
* Set inner padding between sibling rectangles
* @param padding - Pixels or function returning pixels
*/
paddingInner(padding?: number | ((node: Node) => number)): TreemapLayout;Usage Examples:
// Uniform padding
const uniformPadding = treemap()
.padding(5) // 5px on all sides
.size([400, 300]);
// Function-based padding
const dynamicPadding = treemap()
.padding(node => node.depth * 2) // More padding for deeper nodes
.size([400, 300]);
// Separate inner and outer padding
const customPadding = treemap()
.paddingInner(2) // 2px between siblings
.paddingOuter(5) // 5px on edges
.size([400, 300]);
// Individual side padding
const asymmetricPadding = treemap()
.paddingTop(10)
.paddingRight(5)
.paddingBottom(10)
.paddingLeft(5)
.size([400, 300]);Treemap layouts set rectangular bounds on each node:
x0, y0: Top-left corner coordinatesx1, y1: Bottom-right corner coordinatesx1 - x0y1 - y0(x1 - x0) * (y1 - y0)// Calculate rectangle properties
treemapRoot.each(node => {
const width = node.x1 - node.x0;
const height = node.y1 - node.y0;
const area = width * height;
const centerX = (node.x0 + node.x1) / 2;
const centerY = (node.y0 + node.y1) / 2;
console.log(`${node.data.name}: ${width}×${height} at (${centerX}, ${centerY})`);
});Treemap layouts require numeric values on nodes. Use the sum() method to compute values from leaf data:
// Compute values before applying treemap
const root = hierarchy(data)
.sum(d => d.value || 0) // Sum leaf values
.sort((a, b) => b.value - a.value); // Optional: sort by value
// Without sum(), treemap will not work correctly
const treemapRoot = treemap().size([400, 300])(root);