Published
Edited
Jan 31, 2020
Insert cell
md`# DC Treemap`
Insert cell
viewof input = html`<input type=file accept=".csv">`
Insert cell
csv = {
const data = d3.csvParse(await Files.text(input), d3.autoType);
return data;
}
Insert cell
data = {
let nested = d3.nest()
.key(d => d.DATASET)
.key(d => d.PROGRAM)
.key(d => d.TYPE)
.entries(csv);
let root = {key: "Buildings", values: nested};
function rename(node) {
if ("GSF" in node.values[0]) {
let name = node.key;
let value = node.values.reduce((acc, d) => acc + d.GSF, 0);
return {name: name, value: value};
}
return {name: node.key, children: node.values.map(d => rename(d))};
}
return rename(root);
}
Insert cell
viewof tile = html`<select>
<option>treemapBinary</option>
<option>treemapDice</option>
<option>treemapSlice</option>
<option>treemapSliceDice</option>
<option selected>treemapSquarify</option>
</select>`
Insert cell
Insert cell
chart = {
const root = treemap(data);

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.style("font", "10px sans-serif");

const leaf = svg.selectAll("g")
.data(root.leaves())
.join("g")
.attr("transform", d => `translate(${d.x0},${d.y0})`);

leaf.append("title")
.text(d => `${d.ancestors().reverse().map(d => d.data.key).join("/")}\n${format(d.value)}`);

leaf.append("rect")
.attr("id", d => (d.leafUid = DOM.uid("leaf")).id)
.attr("fill", d => { while (d.depth <1) d = d.parent; return color(d.data.name); })
.attr("fill-opacity", 1)
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0);

leaf.append("clipPath")
.attr("id", d => (d.clipUid = DOM.uid("clip")).id)
.append("use")
.attr("xlink:href", d => d.leafUid.href);

leaf.append("text")
.attr("clip-path", d => d.clipUid)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/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);

return svg.node();
}
Insert cell
color = d => {
let lookup = {
"T0": "#a8a7ab",
"T1": "#8958a4",
"T2": "#04a8dc",
"T3": "#0c7c3e",
"T4": "#559459",
"T5": "#f4847b",
"T6": "#aa85bd",
"T7": "#f59087",
"T8": "#c0bec0",
"T9": "#f69c93",
"T10": "#d3d2d3",
"T11": "#f6a9a1",
"T12": "#84b280",
"T13": "#e8e8e8",
"T14": "#f7b6af",
"T15": "#d4bcdb",
"T16": "#b8ddae",
"T17": "#f8da63",
"T18": "#8dd1e9",
"T19": "#f8c3be",
"T20": "#f8d0cd",
"T21": "#b65e07",
"T22": "#fee8a3",
"T23": "#d0f1f4",
"T24": "#f99f1b",
"T25": "#faaa3b",
"T26": "#fcb65b",
"T27": "#fdc377",
"T28": "#fecf92",
"T29": "#fedcae",
"T30": "#ffe9cc"
}
return lookup[d];
}
Insert cell
d3 = require("d3@v5")
Insert cell
width = 960
Insert cell
height = 600
Insert cell
_ = require('lodash@4.17.15/lodash.js').catch(() => window["_"])
Insert cell
format = d3.format(",d")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more