Published
Edited
Aug 25, 2020
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
charts = {
const styles = smallMultiples
? `
.charts-container {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
}
.charts-container > .chart-container {
width: ${dims.width - dims.padding}px;
margin-top: ${dims.padding * 2}px;
}`
: `
.charts-container > .chart-container {
border-bottom: 1px solid #e2e2e2;
margin-top: ${dims.padding * 4}px;
}
.charts-container > .chart-container:last-of-type {
border-bottom: none;
}
`;

const container = html`
<div class="charts-container">
<style>${styles}</style>
</div>`;

// to disable when making lots of edits
if (renderCharts !== "true") return;

for (const ramp in colorRamps) {
const map = renderMap({
field: `${ramp}_rate`,
color: colorRamps[ramp],
race: ramp,
features: cartoData.features.filter(
// only show counties where
// the race/ethnicity is greater than 1% of the total
// and there is at least 1 case
d =>
d.properties[`pct_${ramp}`] > 0.01 &&
d.properties[`${ramp}_cases`] > 0
)
});
container.appendChild(map);
yield container;
}
}
Insert cell
// useful to disable for editing to prevent event blocking re-renders & layout shifts
viewof renderCharts = checkbox({
options: [{ value: "true", label: "Render All Maps" }],
value: "true"
})
Insert cell
Insert cell
test = {
const categories = Object.keys(colorRamps);
const race = categories[Math.floor(Math.random() * categories.length)];
const map = renderMap({
race,
color: colorRamps[race],
field: `${race}_rate`
});
return map;
}
Insert cell
renderMap = (config = {}) => {
const features = config.features || cartoData.features;
const field = config.field || "";
const race = config.race || "";
const color = colorScale.copy().range(config.color);
const title = `${race} cases per 10,000`;

const chart = html`
<div class="chart-container">
<div style="width: 110px; margin: 0 auto;">
${legend({
color,
title,
width: 110,
tickSize: 5,
height: 45
})}
</div>
<svg viewBox="0 0 ${dims.width} ${dims.height}">
<g stroke="#999" stroke-linejoin="round" stroke-linecap="round">
<!-- background -->
<path fill="#F5F5F5" stroke-width="0" d="${path(
topojson.feature(us, us.objects.nation)
)}"></path>
<!-- counties -->
${features.map(
d =>
`<path class="county" fill="${color(
d.properties[field]
)}" stroke-width="0" d=${path(d)}>
<title>${d.properties[field]}</title>
</path>`
)}
<path fill="none" stroke="#f1f1f1" stroke-width="0.5" d="${path(
topojson.mesh(
us,
us.objects.counties,
(a, b) => a !== b && ((a.id / 1000) | 0) === ((b.id / 1000) | 0)
)
)}"></path>
<path fill="none" stroke-width="0.5" d="${path(
topojson.mesh(us, us.objects.states, (a, b) => a !== b)
)}"></path>
</g>
</svg>
</div>`;

return chart;
}
Insert cell
dims = ({
width: width / 2,
height: (width / 2) * aspectRatio,
padding: 6
})
Insert cell
aspectRatio = 0.6256410256
Insert cell
path = d3.geoPath().projection(projection)
Insert cell
projection = d3
.geoAlbersUsa()
.fitExtent(
[
[dims.padding, dims.padding],
[dims.width - dims.padding, dims.height - dims.padding]
],
topojson.feature(us, us.objects.nation)
)
// .scale(1300)
// .translate([487.5, 305])
Insert cell
colorScale = d3.scaleThreshold().domain([25, 50])
Insert cell
// color ramps were copied from the maps in the NYT story linked to at the top of this notebook.
colorRamps = ({
black: ["#EEDBD9", "#DDBAB6", "#B36056"],
hispanic: ["#FAECD6", "#FADFBC", "#F4C17D"],
native: ["#E5E3E8", "#B8ADBE", "#7E6B8A"],
asian: ["#DAE4E7", "#ADC1CC", "#85A4B2"],
white: ["#CDDED8", "#A2C1B5", "#629685"]
})
Insert cell
sampleDatum = cartoData.features[
Math.floor(Math.random() * cartoData.features.length)
]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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