Published
Edited
Jul 6, 2022
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
// x0: initial value
// T: doubling time
exp = (x0, T) => t => x0 * 2 ** (t / T)
Insert cell
curves = d3
.range(1, 8)
.map(T => range(0, domain.length, 1).map((d, i) => [i, exp(threshold, T)(d)]))
Insert cell
// inclusive!
range = (min, max, step) => [...d3.range(min, max, step), max]
Insert cell
domain = Array.from(data.get(series[0]).keys())
Insert cell
latest = domain[domain.length - 1]
Insert cell
series = Array.from(data.keys())
Insert cell
data = getCovidDataGrouped({
statistic: "positive",
transformation: "linear",
derivative: 0,
smoothing: 7
})
Insert cell
dataFinal = getCovidDataGrouped({
statistic: "positive",
transformation: "linear",
derivative: 1,
smoothing: 7
})
Insert cell
keyframes = [
{
title: html`Start with cumulative positive test results`,
statistic: "positive",
transformation: "linear",
derivative: 0,
smoothing: 1
},
{
title: html`Take day-to-day change`,
statistic: "positive",
transformation: "linear",
derivative: 1,
smoothing: 1
},
{
title: html`Make each point the average of the last seven`,
statistic: "positive",
transformation: "linear",
derivative: 1,
smoothing: 7
},
{
title: html`Align the first day they pass ${threshold} cases`,
statistic: "positive",
transformation: "linear",
derivative: 1,
smoothing: 7,
seriesTransform: d => `translate(${-x(xOffsets.get(d))}, 0)`
},
{
// title: html`Draw solutions of ${tex`f'(x)=cf(x)`} of the form ${tex`2^{x/T}`} for integer ${tex`T`}s`,
title: html`Draw constant growth rate curves`,
statistic: "positive",
transformation: "linear",
derivative: 1,
smoothing: 7,
curves: curve => curve.attr("opacity", 1)
},
{
title: html`Warp vertically to make them straight`,
statistic: "positive",
transformation: "linear",
derivative: 1,
smoothing: 7,
yScale: d3
.scaleLog()
.base(2)
.domain([threshold, max(dataFinal)])
.range([height - margin.bottom, margin.top])
}
]
Insert cell
logY = d3
.scaleLog()
.domain([threshold, max(dataFinal)])
.range([height - margin.bottom, margin.top])
Insert cell
logY(10)
Insert cell
height - margin.bottom
Insert cell
keyframeData = keyframes.map(getCovidDataGrouped)
Insert cell
xOffsets = mapEach(map =>
Array.from(map.values()).findIndex(d => d > threshold)
)(dataFinal)
Insert cell
dataFinal
Insert cell
threshold = 10
Insert cell
Insert cell
expSolveForX = (x0, T) => y => (T * Math.log(y / (x0 / 2))) / Math.LN2 - T
Insert cell
duration = 1750
Insert cell
line = d3
.line()
.x(d => x(d[0]))
.y(d => y(d[1]))
.defined(d => valid(d[1]))
Insert cell
lineTrunc = d => line(d.filter(([i, d]) => d < 20 * y.domain()[1]))
Insert cell
x = d3
.scaleLinear()
.domain([0, domain.length - 1])
.range([margin.left, width - margin.right])
Insert cell
y = d3
.scaleLinear()
.domain([0, max(data)])
.range([height - margin.bottom, margin.top])
Insert cell
height = width / 2
Insert cell
max = map =>
d3.max(
d3
.merge(
Array.from(map, ([key, value]) =>
Array.from(value, ([key, value]) => value)
)
)
.filter(valid)
)
Insert cell
hues = new Map(series.map(d => [d, Math.floor(Math.random() * 360)]))
Insert cell
valid = d => d !== null && d !== Infinity && d !== -Infinity && !isNaN(d)
Insert cell
logValid = d => valid(d) && d !== 0
Insert cell
margin = ({ top: 10, right: 20, bottom: 0, left: 0 })
Insert cell
d3 = require("d3@5")
Insert cell
import { mapEach, draft } from "@tophtucker/scrapbook"
Insert cell
import {
transformData,
getCovidDataGrouped,
dateParse
} from "@tophtucker/covid-tracking-project-data"
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