Published
Edited
Sep 6, 2020
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
allEvents = {
// Durations in minutes in the calculations
const rand = (a, b) => Math.random() * (b - a) + a; // uniform random in [a, b)
const randc = (c, r) => rand(c - r, c + r); // uniform random with radius r and center c
const nContestants = 20;
const nRounds = 20;
const startSpacing = 2;
const meanDurationPerRound = 2 * 60 / nRounds;
const roundWeights = new Array(nRounds).fill(0).map(() => meanDurationPerRound * randc(1, 0.5));

const now = Date.parse("2020-05-16 12:00");
const events = [];
for (let iContestant = 0; iContestant < nContestants; iContestant++) {
let t0 = iContestant * startSpacing;
const tAll = [t0];
let t = t0;
const speed = randc(1, 0.5);
for (let iRound = 0; iRound < nRounds; iRound++) {
const roundSpeed = speed * randc(1, 0.3);
t = t + roundWeights[iRound] / roundSpeed;
tAll.push(t);
}
events.push(...tAll.map((ti, i) => ({
contestant: iContestant,
checkpoint: i,
timestamp: Math.round(now + ti * 60 * 1000), // Convert to milliseconds
})))
}
return events;
}
Insert cell
Insert cell
pastEvents = {
const events = allEvents.filter(e => e.timestamp <= t);
const startEventsByContestant = d3.group(events.filter(e => e.checkpoint === 0), d => d.contestant);
return events.map(e => ({
...e,
elapsed: e.timestamp - startEventsByContestant.get(e.contestant)[0].timestamp,
}));
};
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 3)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(k === 0 ? "Elapsed time [minutes]" : "Deviation from k⋅mean [minutes]"))
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