Published
Edited
Sep 18, 2020
2 forks
1 star
Insert cell
Insert cell
viewof selectedTable = navio(tableData)
Insert cell
groupedData = d3.rollup(
selectedTable,
v => v.length,
d => d.object_type,
d => d.request_category
)
Insert cell
treeData = d3.hierarchy(groupedData)
Insert cell
treeData.leaves()
Insert cell
layTree = d3.tree().size([width, height])
Insert cell
layedOutTreeData = layTree(treeData)
Insert cell
layedOutTreeData.links()
Insert cell
{
const svg = d3
.create("svg")
.attr("viewBox", [
-margin,
-margin,
width + margin * 2,
height + margin * 2
]);

svg
.selectAll(".link")
.data(layedOutTreeData.links())
.join("path")
.attr("class", "link")
.attr(
"d",
d3
.linkVertical()
.x(d => d.x)
.y(d => d.y)
)
.attr("fill", "none")
.attr("stroke", "#ccc");

svg
.selectAll(".node")
.data(layedOutTreeData)
.join("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.x}, ${d.y})`)
.call(g =>
g
.append("circle")
.attr("r", 5)
.attr("fill", "#333")
)
.call(g => g.append("text").text(d => d.data[0]));

return svg.node();
}
Insert cell
{
const svg = d3
.create("svg")
.attr("viewBox", [
-margin,
-margin,
height + margin * 2,
width + margin * 2
])
.attr("width", height);

svg
.selectAll(".link")
.data(layedOutTreeData.links())
.join("path")
.attr("class", "link")
.attr(
"d",
d3
.linkHorizontal()
.x(d => d.y)
.y(d => d.x)
)
.attr("fill", "none")
.attr("stroke", "#ccc");

svg
.selectAll(".node")
.data(layedOutTreeData)
.join("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.y}, ${d.x})`)
.call(g =>
g
.append("circle")
.attr("r", 5)
.attr("fill", "#333")
)
.call(g => g.append("text").text(d => d.data[0]));

return svg.node();
}
Insert cell
md`## Containment`
Insert cell
treeDataAggregated = d3.hierarchy(groupedData).sum(d => d[1])
Insert cell
layTreemap = d3
.treemap()
.size([width, height])
.round(true)
.padding(1)
Insert cell
layedOutTreemapData = layTreemap(treeDataAggregated.copy())
Insert cell
swatches({color})
Insert cell
{
const svg = d3
.create("svg")
.attr("viewBox", [
-margin,
-margin,
width + margin * 2,
height + margin * 2
]);

svg
.selectAll(".node")
.data(layedOutTreemapData.leaves())
.join("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.x0}, ${d.y0})`)
.call(g =>
g
.append("rect")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("fill", d => color(d.data[0]))
)
.call(g =>
g
.append("text")
.attr("y", 10)
.call(text =>
text
.append("tspan")
.attr("x", 0)
.attr("dy", 0)
.text(d => d.data[0])
)
.call(text =>
text
.append("tspan")
.attr("x", 0)
.attr("dy", 10)
.text(d => d.data[1])
)
);

return svg.node();
}
Insert cell
layIcicle = d3
.partition()
.size([width, height])
.round(true)
.padding(1)
Insert cell
layedOutIcicleData = layIcicle(treeDataAggregated)
Insert cell
{
const svg = d3
.create("svg")
.attr("viewBox", [
-margin,
-margin,
width + margin * 2,
height + margin * 2
]);

svg
.selectAll(".node")
.data(layedOutIcicleData.descendants())
.join("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.x0}, ${d.y0})`)
.call(g =>
g
.append("rect")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("fill", d => color(d.data[0]))
)
.call(g =>
g
.append("text")
.attr("y", 10)
.call(text =>
text
.append("tspan")
.attr("x", 0)
.attr("dy", 0)
.text(d => d.data[0])
)
.call(text =>
text
.append("tspan")
.attr("x", 0)
.attr("dy", 10)
.text(d => d.value)
)
);

return svg.node();
}
Insert cell
layPack = d3
.pack()
.size([width, height])
.padding(1)
Insert cell
layedOutPackedData = layPack(treeDataAggregated.copy())
Insert cell
{
const svg = d3
.create("svg")
.attr("viewBox", [
-margin,
-margin,
width + margin * 2,
height + margin * 2
]);

svg
.selectAll(".node")
.data(layedOutPackedData.descendants())
.join("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.x}, ${d.y})`)
.call(g =>
g
.append("circle")
.attr("r", d => d.r)
.attr("fill", d => color(d.data[0]))
)
.call(g =>
g
.append("text")
.attr("y", 10)
.call(text =>
text
.append("tspan")
.attr("x", 0)
.attr("dy", 0)
.text(d => d.data[0])
)
.call(text =>
text
.append("tspan")
.attr("x", 0)
.attr("dy", 10)
.text(d => d.value)
)
);

return svg.node();
}
Insert cell
color = d3
.scaleOrdinal()
.range(
d3.quantize(
t => d3.interpolateSpectral(t * .8 + .2),
new Set(tableData.map(d => d.request_category)).size
)
)
Insert cell
new Set(tableData.map(d => d.request_category)).size
Insert cell
html`<style>svg text { font-size: 8pt; font-family: sans-serif }</style>`
Insert cell
height = 400
Insert cell
margin = 20
Insert cell
url = "https://data.cityofberkeley.info/resource/bscu-qpbu.csv?$limit=10000"
Insert cell
tableData = d3.csv(url)
Insert cell
d3 = require("d3@6")
Insert cell
import { navio } from "@john-guerra/navio"
Insert cell
import { swatches } from "@d3/color-legend"
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