Published
Edited
Apr 24, 2021
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = ({
data,
name,
height,
showLegend = true,
titlePrefix = "Age Distrubution of"
}) => {
height = height || 100;
const container = html`<div class="chart-container">
<style>
.chart-container { padding: 12px; }
.chart-container p.title { margin: 0; font-family: sans-serif; }
.chart-container svg { display: block; margin: 0; }
.chart-container svg:last-of-type { margin-left: 8px; }
</style>
<p class="title"><strong>${titlePrefix} ${name}</strong></p>
<svg viewBox="0, 0, ${width}, ${height}"></svg>
${showLegend ? legend({ color }) : ""}
</div>`;

const svg = d3.select(container).select("svg");

const g = svg.append("g");

const stacks = g
.selectAll("g")
.data(data, (d) => d.key)
.join("g")
.attr("fill", (d) => color(d.key))
.attr("transform", `translate(0 ,${margin.top})`);

stacks
.selectAll("rect")
.data((d) => d)
.join("rect")
.attr("width", (d) => x(d[1]) - x(d[0]))
.attr("height", height - margin.top - margin.bottom)
.attr("x", (d) => x(d[0]))
.attr("y", 0)
.append("title")
.text((d) => d.data[d.key].toLocaleString());

svg.append("g").call(xAxis, data);

return container;
}
Insert cell
margin = ({ top: 24, right: 30, bottom: 0, left: 18 })
Insert cell
series = d3
.stack()
.keys(Object.keys(datum))
.offset(d3.stackOffsetExpand)([datum])
.map(d => (d.forEach(v => (v.key = d.key)), d))
Insert cell
stops = Array.from(
new Set(d3.merge(series.map(s => s[0]).map(([d1, d2], i) => [d1, d2])))
)
Insert cell
getTicks = series =>
Array.from(
new Set(d3.merge(series.map(s => s[0]).map(([d1, d2], i) => [d1, d2])))
)
Insert cell
xAxis = (g, _series) =>
g
.attr("transform", `translate(0,${margin.top})`)
.call(
d3
.axisTop(x)
.tickValues(getTicks(_series))
.tickFormat((d, i) => {
let formatter = ".1f";
if (i === 0 || i === getTicks(_series).length - 1) formatter = ".0f";
return d3.format(formatter)(d * 100) + "%";
})
)
.call(g =>
g.select(".tick:last-of-type > text").attr("text-anchor", "start")
)
.call(g =>
g.select(".tick:first-of-type > text").attr("text-anchor", "end")
)
.call(g => g.selectAll(".domain").remove())
Insert cell
x = d3
.scaleLinear()
.domain([0, 1])
.range([margin.left, width - margin.right])
Insert cell
color = d3
.scaleOrdinal()
.domain(series.map(d => d.key))
.range(d3.schemeSpectral[series.length])
.unknown("#ccc")
Insert cell
Insert cell
datum = countySums.reduce((acc, cur, i) => {
acc[ageBuckets[i]] = cur;
return acc;
}, {})
Insert cell
countySums = sums[fipsIndex]
Insert cell
countyTotal = totals[fipsIndex]
Insert cell
fipsIndex = fipsIndexMap.get(counties2FipsMap.get(targetCounty))
Insert cell
targetCounty = selected || defaultCounty
Insert cell
defaultCounty = "Alameda County, California"
Insert cell
Insert cell
d3 = require("d3@6")
Insert cell
import { autoSelect } from "@jashkenas/inputs"
Insert cell
import { legend } from "@d3/color-legend"
Insert cell
import {
sums,
totals,
fipsIndex as fipsIndexMap,
ageBuckets,
counties2FipsMap
} from "1ec3e013ab0fb19a"
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