1
0
mirror of https://github.com/d3/d3.git synced 2026-02-01 16:41:44 +00:00
d3/examples/treemap.md
Philippe Rivière 8a83cc5404 when adding labels, filter out small shapes
(an alternative if we wanted to keep the labels, could be to set an opacity 0 on these)
2024-05-21 17:48:08 +02:00

100 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Treemap
Introduced by [Ben Shneiderman](http://www.cs.umd.edu/hcil/treemap-history/), treemaps recursively partition space into rectangles according to each nodes associated value. D3 supports several treemap [tiling methods](https://d3js.org/d3-hierarchy/treemap#treemap-tiling). See also [nested](./nested-treemap), [zoomable](./zoomable-treemap) and [animated](./animated-treemap) treemaps, and the [bubble chart](./bubble-chart).
<!-- If your data is flat, see the [treemap, CSV](https://observablehq.com/@d3/treemap-stratify?intent=fork) variant. -->
```js
const tile = view(Inputs.select(
new Map([
["binary", d3.treemapBinary],
["squarify", d3.treemapSquarify],
["slice-dice", d3.treemapSliceDice],
["slice", d3.treemapSlice],
["dice", d3.treemapDice]
]),
{label: "Tiling method", value: d3.treemapBinary}
));
```
```js
Plot.legend({color: {domain: color.domain(), range: color.range()}})
```
```js echo
// Set the height to the (default) width.
const height = width;
// Specify the color scale.
const color = d3.scaleOrdinal()
.domain(data.children.map((d) => d.name))
.range(d3.schemeObservable10);
// Compute the layout.
const root = d3.treemap()
.tile(tile) // e.g., d3.treemapBinary
.size([width, height])
.padding(1)
.round(true)
(d3.hierarchy(data)
.sum((d) => d.value)
.sort((a, b) => b.value - a.value));
// Create the SVG container.
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height)
.attr("fill", "currentColor")
.attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;");
// Add a cell for each leaf of the hierarchy.
const leaf = svg.selectAll("g")
.data(root.leaves())
.join("g")
.attr("transform", (d) => `translate(${d.x0},${d.y0})`);
const format = d3.format(",d");
// Append a tooltip.
leaf.append("title")
.text((d) => `${d.ancestors().reverse().map((d) => d.data.name).join(".")}\n${format(d.value)}`);
// Append a color rectangle.
leaf.append("rect")
.attr("id", (d, i) => `leaf-${i}`)
.attr("fill", (d) => { while (d.depth > 1) d = d.parent; return color(d.data.name); })
.attr("fill-opacity", 0.6)
.attr("width", (d) => d.x1 - d.x0)
.attr("height", (d) => d.y1 - d.y0);
// Append a clipPath to ensure text does not overflow.
leaf.append("clipPath")
.attr("id", (d, i) => `leaf-clip-${i}`)
.append("use")
.attr("xlink:href", (d, i) => `#leaf-${i}`);
// Append multiline text. The last line shows the value and has a specific formatting.
leaf.filter((d) => d.x1 - d.x0 > 7).append("text")
.attr("clip-path", (d, i) => `url(#leaf-clip-${i})`)
.selectAll("tspan")
.data((d) => d.data.name.split(/(?=[A-Z][a-z])|\s+/g).concat(format(d.value)))
.join("tspan")
.attr("x", 3)
.attr("y", (d, i, nodes) => `${(i === nodes.length - 1) * 0.3 + 1.1 + i * 0.9}em`)
.attr("fill-opacity", (d, i, nodes) => i === nodes.length - 1 ? 0.7 : null)
.text((d) => d);
display(svg.node());
```
The data here is provided as a JSON file.
```js echo
const data = FileAttachment("flare.json").json();
```
```js echo
data
```