Published
Edited
Apr 6, 2021
3 forks
23 stars
Insert cell
Insert cell
Insert cell
Insert cell
viz = {
const ctx = DOM.context2d(width, height);
const path = d3.geoPath(null, ctx);
const container = html`<div class="canvas-container" style="position:relative;">
<style>
.canvas-container {
position: relative;
width: ${width}px;
height: ${height}px;
}
.canvas-container > svg,
.canvas-container > canvas {
position: absolute;
}
.canvas-container > canvas {
top: 0;
left: 0;
}
.canvas-container > svg {
display: inline-block;
top: 10px;
left: ${width / 2 - 100}px;
}
</style>
${legend({
color: colorScaleThreshold,
width: 200,
height: 45,
title: "Cumulative Coronavirus Cases",
tickFormat: ","
})}
${ctx.canvas}
${basemap}
</div>`;

ctx.clearRect(0, 0, width, height);

curData.forEach(d => {
const geojson = countyGeomLookUp.get(d.fips);
if (geojson) {
ctx.beginPath();
path(geojson);
ctx.lineWidth = 0;
ctx.fillStyle = colorScaleThreshold(d.cases);
ctx.fill();
}
});

return container;
}
Insert cell
Insert cell
// see https://observablehq.com/@d3/color-schemes
colorScaleThreshold = d3
.scaleThreshold()
.domain([100, 1000, 10000, 100000])
.range(["#fee391", "#fec44f", "#fe9929", "#d95f0e", "#993404"]) // color brewer yl-or-brwn
Insert cell
formatDate = date =>
date.toLocaleString("en", { month: "long", day: "numeric" })
Insert cell
Insert cell
casesDistributionChart = {
const chart = d3.select(
html`<svg width="${width}" height="${chartHeight}"></svg>`
);

chart
.selectAll("circle")
.data(binnedByTotalCases)
.join("circle")
.attr("cx", ([k, v]) => xScale(k))
.attr("cy", ([k, v]) => yScale(v))
.attr("fill", "steelblue")
.attr("r", 2.5)
.append("title")
.text(([k, v]) => `${k.toLocaleString()} has ${v} instances`);

chart
.append("g")
.attr("transform", `translate(0, ${chartHeight - margin.bottom})`)
.call(xAxis);

chart
.append("g")
.attr("transform", `translate(${margin.left}, 0)`)
.call(yAxis);

return chart.node();
}
Insert cell
chartHeight = 300
Insert cell
margin = ({ top: 10, left: 36, bottom: 36, right: 24 })
Insert cell
xScale = d3
.scaleLog()
.base(2)
.domain([1, d3.max(cases)])
.range([margin.left, width - margin.right])
Insert cell
xAxis = d3.axisBottom(xScale)
Insert cell
yScale = d3
.scaleLinear()
.domain(d3.extent(binnedByTotalCases, ([k, v]) => v))
.range([chartHeight - margin.bottom, margin.top])
Insert cell
yAxis = d3.axisLeft(yScale)
Insert cell
binnedByTotalCases = d3.rollups(
grouped.get(datesExtent[1]),
v => v.length,
d => d.cases
)
Insert cell
Insert cell
Insert cell
nonMatches = rows.filter(d => countyGeomLookUp.get(d.fips) === undefined)
Insert cell
[...d3.group(nonMatches, d => d.fips).keys()]
Insert cell
Insert cell
totalCases = d3.sum(curData, d => d.cases)
Insert cell
curData = grouped.get(date)
Insert cell
maxNumCases = d3.max(cases)
Insert cell
quantiles = [0, 0.25, 0.5, 0.75, 1].map(d => d3.quantile(cases, d))
Insert cell
datesExtent = d3.extent(dates)
Insert cell
dates = [...grouped.keys()]
Insert cell
cases = rows.map(d => d.cases).sort()
Insert cell
// for joining covid cases to county geometries
countyGeomLookUp = new Map(
topojson
.feature(us, us.objects.counties)
.features.map(({ id, ...rest }) => [id, rest])
)
Insert cell
Insert cell
grouped = new Map(
[...d3.group(rows, d => d.date)].map(([key, value]) => [new Date(key), value])
)
Insert cell
rows = {
const rows = await d3.csv(githubRawCsvUrl);
rows.forEach(d => {
d.cases = +d.cases;
d.deaths = +d.deaths;
});
return rows;
}
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