Skip to content

D3.js Hierarchies — Tree and Cluster Layouts

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about D3.js Hierarchies. We cover key concepts, practical examples, and best practices to help you master this topic.

D3.js hierarchical layouts transform nested data into tree diagrams, cluster charts, treemaps, and partition layouts for visualizing parent-child relationships.

What You'll Learn

By the end of this guide, you will create trees from hierarchical data, use d3.stratify for flat data, build treemaps for proportion visualization, create dendrograms, and add interactive collapse/expand.

Why Hierarchies Matter

Hierarchical data is everywhere. In Durga Antivirus Pro, the threat classification tree shows malware categories and subcategories, helping analysts navigate the taxonomy of known threats.

flowchart TD
    A[Root] --> B[Category A]
    A --> C[Category B]
    B --> D[Sub A1]
    B --> E[Sub A2]
    C --> F[Sub B1]
    C --> G[Sub B2]

Creating a Tree Layout

var data = {
    name: 'Root',
    children: [
        { name: 'Branch 1', children: [
            { name: 'Leaf 1A' },
            { name: 'Leaf 1B' }
        ]},
        { name: 'Branch 2', children: [
            { name: 'Leaf 2A' },
            { name: 'Leaf 2B' }
        ]}
    ]
};

var root = d3.hierarchy(data);
var treeLayout = d3.tree().size([400, 300]);
treeLayout(root);

Rendering the Tree

// Links
svg.append('g')
    .selectAll('path')
    .data(root.links())
    .enter()
    .append('path')
    .attr('fill', 'none')
    .attr('stroke', '#555')
    .attr('stroke-width', 2)
    .attr('d', d3.linkHorizontal()
        .x(function(d) { return d.y; })
        .y(function(d) { return d.x; })
    );

// Nodes
svg.append('g')
    .selectAll('circle')
    .data(root.descendants())
    .enter()
    .append('circle')
    .attr('cx', function(d) { return d.y; })
    .attr('cy', function(d) { return d.x; })
    .attr('r', 5);

Using d3.stratify for Flat Data

var data = [
    { id: 'A', parent: '' },
    { id: 'B', parent: 'A' },
    { id: 'C', parent: 'A' },
    { id: 'D', parent: 'B' },
    { id: 'E', parent: 'B' }
];

var root = d3.stratify()
    .id(function(d) { return d.id; })
    .parentId(function(d) { return d.parent; })
    (data);

var tree = d3.tree().size([400, 300]);
tree(root);

Treemap

var root = d3.hierarchy(data)
    .sum(function(d) { return d.value || 0; });

d3.treemap()
    .size([500, 400])
    .padding(2)
    (root);

svg.selectAll('rect')
    .data(root.leaves())
    .enter()
    .append('rect')
    .attr('x', function(d) { return d.x0; })
    .attr('y', function(d) { return d.y0; })
    .attr('width', function(d) { return d.x1 - d.x0; })
    .attr('height', function(d) { return d.y1 - d.y0; })
    .attr('fill', function(d) { return d.data.color || '#4ecdc4'; });

Common Mistakes

1. Calling Layout Before hierarchy

The layout functions require a d3.hierarchy root. Always wrap data with d3.hierarchy() first.

2. Not Summing for Treemap

Treemap needs .sum() to compute leaf values. Without it, all leaves have the same size.

3. Forgetting That Tree Layout Inverts X and Y

By default, d3.tree uses x for vertical position and y for horizontal. Use .size([height, width]) if you want horizontal layout.

4. Data With Cycles

d3.hierarchy requires acyclic data. Circular references in children cause infinite Recursion.

5. Not Handling Missing Parent References in Stratify

Nodes with parent="" must have a root node where parent is null or the parent exists. Orphaned nodes throw errors.

Practice Questions

Q1: What is the difference between d3.tree and d3.cluster? A: d3.tree spreads leaf nodes to avoid overlap. d3.cluster places all leaves at the same depth.

Q2: What does d3.hierarchy() do? A: It converts a nested JSON object into a d3 hierarchy node with properties like children, depth, height, and parent.

Q3: How do you convert flat tabular data to hierarchy? A: Use d3.stratify() with an id accessor and parentId accessor.

Q4: What is the purpose of .sum() in treemap? A: It computes the total value for each node, which determines the size of treemap rectangles.

Q5: How do you create a collapsible tree? A: Add click handlers on nodes that toggle the visibility of child nodes. Use node.children and node._children.

Challenge: Build an interactive organizational chart. Load employee data as flat CSV with manager IDs. Render a tree. Click employees to expand/collapse their teams. Highlight the chain of command on hover.

FAQ

Can d3.tree handle thousands of nodes?

Yes, but the rendered diagram becomes dense. Use zoom and pan, or switch to a treemap for large datasets.

What is d3.dendrogram?

D3 does not have a dedicated dendrogram layout. Use d3.cluster or d3.tree with appropriate styling.

How do I add labels to tree nodes?

Append text elements positioned at node x,y coordinates. Use the node's data.name or custom label property.

What is the difference between tree and treemap?

Tree shows explicit parent-child connections with lines. Treemap shows proportion through nested rectangle sizes.

Can I animate tree transitions?

Yes. Use transitions on node and link elements when the data updates, interpolating path d attributes for links.

Try It Yourself

Build an interactive tree diagram with expandable branches.

<!DOCTYPE html>
<html>
<head>
    <title>Interactive Tree</title>
    <style>
        body { font-family: sans-serif; padding: 20px; background: #f5f5f5; }
        .node circle { fill: #4ecdc4; stroke: #2a9d8f; stroke-width: 2; cursor: pointer; }
        .node text { font-size: 12px; fill: #333; }
        .link { fill: none; stroke: #ccc; stroke-width: 2; }
    </style>
</head>
<body>
<svg width="600" height="450" id="tree"></svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
var data = {
    name: 'CEO', children: [
        { name: 'CTO', children: [
            { name: 'Dev Lead', children: [{ name: 'Engineer A' }, { name: 'Engineer B' }] },
            { name: 'QA Lead', children: [{ name: 'Tester A' }, { name: 'Tester B' }] }
        ]},
        { name: 'CFO', children: [
            { name: 'Accountant A' }, { name: 'Accountant B' }
        ]},
        { name: 'CMO' }
    ]
};

var width = 600, height = 450;
var svg = d3.select('#tree').append('g').attr('transform', 'translate(60, 40)');
var root = d3.hierarchy(data);
var tree = d3.tree().size([height - 80, width - 120]);
tree(root);

svg.selectAll('.link')
    .data(root.links()).enter()
    .append('path').attr('class', 'link')
    .attr('d', d3.linkHorizontal().x(function(d) { return d.y; }).y(function(d) { return d.x; }));

var node = svg.selectAll('.node')
    .data(root.descendants()).enter()
    .append('g').attr('class', 'node')
    .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; });

node.append('circle').attr('r', 5);
node.append('text').attr('x', 8).attr('y', 4).text(function(d) { return d.data.name; });
</script>
</body>
</html>

What's Next

Create geographic map visualizations.

Geo Maps — Geographic mapping with D3.js. Request Data — Loading external data in D3.js.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro