Public
Edited
Oct 12, 2023
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const nodes = root.descendants();

const svg = d3.create("svg")
.attr("viewBox", [-nodeWidth / 2, -nodeHeight * 3 / 2, width, (root.maxIndex+1) * nodeHeight])
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.style("overflow", "visible");

const link = svg.append("g")
.attr("fill", "none")
.attr('stroke-width', 2)
.selectAll("path")
.data(root.links())
.join("path")
.attr("d", d => {
let p1 = {x: d.source.depth * 2 * nodeWidth, y: d.source.index * nodeHeight}
let pc = {x: (d.source.depth*2 + 1.25) * nodeWidth, y: (d.target.index-1) * nodeHeight}
let p2 = {x: (d.source.depth+1) * 2 * nodeWidth, y: d.target.index * nodeHeight}
return rounded(p1, pc, {corner_radius: 16}).toString() + rounded(pc, p2, {sweep: false, corner_radius: 16}).toString()
})
.attr('stroke', d => (colors ? color(d.source.index) : '#999'));

const node = svg.append("g")
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", d => `translate(0,${d.index * nodeHeight})`);

node.append("circle")
.attr("cx", d => d.depth * 2 * nodeWidth)
.attr("r", 4.5)
.attr('stroke', d => d.children ? 'black' : (colors ? color(d.parent.index) : '#999'))
.attr('stroke-width', d => d.children ? 2.5 : 1.75)
.attr("fill", d => d.children ? 'white' : (colors ? color(d.parent.index) : '#999'));

node.append("text")
.attr("dy", d => d.children ? "-0.6em" : "0.32em")
.attr("x", d => d.depth * 2 * nodeWidth + (d.children ? 4 : 10))
.style("font-size", 14)
.style("font-weight", d => d.children ? 'bold' : 'normal')
.text(d => d.data.name);

node.append("title")
.text(d => d.ancestors().reverse().map(d => d.data.name).join("/"));

return svg.node();
}
Insert cell
columns = [
{
label: "Size",
value: d => d.value,
format,
x: 380
},
{
label: "Count",
value: d => d.children ? 0 : 1,
format: (value, d) => d.children ? format(value) : "-",
x: 440
}
]
Insert cell
format = d3.format(",")
Insert cell
data = FileAttachment("flare-2.json").json()
Insert cell
root = {
let i = 0;
let last_node;
let r = d3.hierarchy(data).eachBefore(d => {
// add one more if this is a first child or after a subhierarchy is completed or if an inner node is right after a sibling leaf
if(d.parent && d === d.parent.children[0] || last_node && (d.depth < last_node.depth || d.depth == last_node.depth && d.children && !(last_node.children))) {
i++
}
d.index = i++
last_node = d
});
r.maxIndex = i;
return r;
}
Insert cell
nodeHeight = 26
Insert cell
nodeWidth = 32
Insert cell
color = d3.scaleOrdinal(d3.schemeDark2)
Insert cell
d3 = require("d3@6")
Insert cell
Insert cell
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