Public
Edited
Jun 24
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
waveHeight = [
{date: '2025-04-01', naples: 2.2, rincon: 2.5, campus_point: 1.4},
{date: '2025-04-02', naples: 2.6, rincon: 2.5, campus_point: 1.6},
{date: '2025-04-03', naples: 1.8, rincon: 0.9, campus_point: 1.5},
{date: '2025-04-04', naples: 3.4, rincon: 3.0, campus_point: 3.2},
{date: '2025-04-05', naples: 3.0, rincon: 2.8, campus_point: 2.5}
]
Insert cell
Insert cell
{
const waveHeightLong = [];
for (const row of waveHeight) {
for (const location of ["naples", "rincon", "campus_point"]) {
waveHeightLong.push({
date: row.date,
location,
height: row[location]
});
}
}
return waveHeightLong;
}
Insert cell
Insert cell
Insert cell
Insert cell
simpleArray = [1, 5, 10, 11, 25]
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.barY(simpleArray),
Plot.ruleY([0])
]
})
Insert cell
Insert cell
chart = {
const width = 600;
const height = 300;
const barPadding = 10;
const barWidth = width / simpleArray.length;

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

const yScale = d3.scaleLinear()
.domain([0, d3.max(simpleArray)])
.range([0, height]);

svg.selectAll("rect")
.data(simpleArray)
.join("rect")
.attr("class", "bar")
.attr("x", (d, i) => i * barWidth)
.attr("y", d => height - yScale(d))
.attr("width", barWidth - barPadding)
.attr("height", d => yScale(d));

return svg.node();
};
Insert cell
Insert cell
Insert cell
shippingNetwork = [
{
hub: "Chicago",
distributors: [
{
city: "St. Louis",
towns: [
{ name: "Springfield, IL", packages: 120 },
{ name: "Columbia, MO", packages: 95 }
]
},
{
city: "Indianapolis",
towns: [
{ name: "Bloomington, IN", packages: 110 },
{ name: "Lafayette, IN", packages: 90 }
]
},
{
city: "Milwaukee",
towns: [
{ name: "Green Bay, WI", packages: 80 },
{ name: "Madison, WI", packages: 105 }
]
}
]
},
{
hub: "Dallas",
distributors: [
{
city: "Austin",
towns: [
{ name: "San Marcos, TX", packages: 140 },
{ name: "Georgetown, TX", packages: 85 }
]
},
{
city: "Houston",
towns: [
{ name: "Sugar Land, TX", packages: 100 },
{ name: "Pasadena, TX", packages: 120 }
]
},
{
city: "San Antonio",
towns: [
{ name: "New Braunfels, TX", packages: 75 },
{ name: "Seguin, TX", packages: 95 }
]
}
]
},
{
hub: "Atlanta",
distributors: [
{
city: "Charlotte",
towns: [
{ name: "Gastonia, NC", packages: 110 },
{ name: "Concord, NC", packages: 98 }
]
},
{
city: "Nashville",
towns: [
{ name: "Franklin, TN", packages: 130 },
{ name: "Murfreesboro, TN", packages: 125 }
]
},
{
city: "Birmingham",
towns: [
{ name: "Tuscaloosa, AL", packages: 85 },
{ name: "Hoover, AL", packages: 90 }
]
}
]
}
];
Insert cell
Insert cell
flatShippingData = shippingNetwork.flatMap(hubEntry =>
hubEntry.distributors.flatMap(distributor =>
distributor.towns.map(town => ({
location: `${hubEntry.hub}-${distributor.city}-${town.name}`,
packages: town.packages
}))
)
);
Insert cell
Insert cell
Plot.plot({
axis: null,
margin: 10,
marginRight: 100,
marks: [
Plot.tree(flatShippingData, {path: "location", delimiter: "-"})
]
})
Insert cell
Insert cell
tidyShippingData = shippingNetwork.flatMap(hubEntry =>
hubEntry.distributors.flatMap(distributor =>
distributor.towns.map(town => ({
hub: hubEntry.hub,
city: distributor.city,
town: town.name,
packages: town.packages
}))
)
);
Insert cell
Insert cell
Insert cell
penguins
Insert cell
Insert cell
penguinCounts = d3.rollup(penguins, v => v.length, d => d.species)
Insert cell
penguinCounts
Insert cell
Insert cell
Array.from(penguinCounts, ([species, count]) => ({ species, count }));
Insert cell
Insert cell
d3.rollup(penguins, v => d3.mean(v, d => d.body_mass_g), d => d.island)
Insert cell
Insert cell
Insert cell
dams = FileAttachment("dams.csv").csv({typed: true})
Insert cell
Insert cell
hierarchicalDams = {
function group(data, [name, ...path]) {
return d3.groups(data, (d) => d[name])
.map(([value, rows]) => path.length
? { name: value, children: group(rows, path) }
: { name: value, value: rows.length }
);
}
return {
name: "damsHierarchy",
children: group(dams, [
"Primary Purpose",
"Primary Dam Type",
"Primary Owner Type",
"Condition Assessment",
"Hazard Potential Classification"
])
};
}
Insert cell
Insert cell
chart2 = {
const height = 400;
const width = 800;
const color = d3.scaleOrdinal(d3.quantize(d3.interpolateRainbow, hierarchicalDams.children.length + 1))
const format = d3.format(",d");
const partition = data => {
const root = d3.hierarchy(data)
.sum(d => d.value)
.sort((a, b) => b.height - a.height || b.value - a.value);
return d3.partition()
.size([height, (root.height + 1) * width / 3])
(root);
}
const root = partition(hierarchicalDams);
let focus = root;

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

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

const rect = cell.append("rect")
.attr("width", d => d.y1 - d.y0 - 1)
.attr("height", d => rectHeight(d))
.attr("fill-opacity", 0.6)
.attr("fill", d => {
if (!d.depth) return "#ccc";
while (d.depth > 4) d = d.parent;
return color(d.data.name);
})
.style("cursor", "pointer")
.on("click", clicked);

const text = cell.append("text")
.style("user-select", "none")
.attr("pointer-events", "none")
.attr("x", 4)
.attr("y", 13)
.attr("fill-opacity", d => +labelVisible(d));

text.append("tspan")
.text(d => d.data.name);

const tspan = text.append("tspan")
.attr("fill-opacity", d => labelVisible(d) * 0.7)
.text(d => d.children ? ` ${format(d.value)}` : ` ${format(d.value)} series`);

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

function clicked(event, p) {
focus = focus === p ? p = p.parent : p;

root.each(d => d.target = {
x0: (d.x0 - p.x0) / (p.x1 - p.x0) * height,
x1: (d.x1 - p.x0) / (p.x1 - p.x0) * height,
y0: d.y0 - p.y0,
y1: d.y1 - p.y0
});

const t = cell.transition().duration(750)
.attr("transform", d => `translate(${d.target.y0},${d.target.x0})`);

rect.transition(t).attr("height", d => rectHeight(d.target));
text.transition(t).attr("fill-opacity", d => +labelVisible(d.target));
tspan.transition(t).attr("fill-opacity", d => labelVisible(d.target) * 0.7);
}
function rectHeight(d) {
return d.x1 - d.x0 - Math.min(1, (d.x1 - d.x0) / 2);
}

function labelVisible(d) {
return d.y1 <= width && d.y0 >= 0 && d.x1 - d.x0 > 16;
}
return svg.node();
}
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