Unlisted
Edited
Mar 14, 2023
2 stars
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
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
Insert cell
// tplot(new Date("2023-01-29"), +new Date("2023-01-29") + 10*86400*1000*((1+Math.cos(now/1000))/2)**3)
Insert cell
function tickFormat(bilevelFormat, start, stop, count) {
const [interval, step] = tickInterval(start, stop, count);
switch (interval) {
case "millisecond":
return bilevelFormat(d3.utcFormat(":%M:%S"), d3.utcFormat(".%L"), d3.utcSecond, d3.utcMillisecond, step);
case "second":
return bilevelFormat(d3.utcFormat("%-I:%M"), d3.utcFormat(":%S"), d3.utcMinute, d3.utcSecond, step);
// return bilevelFormat(d3.utcFormat("%-I %p"), d3.utcFormat(":%M:%S"), d3.utcHour, d3.utcSecond, step);
case "minute":
return bilevelFormat(d3.utcFormat("%p"), d3.utcFormat("%-I:%M"), d3.utcHour.every(12), d3.utcMinute, step);
case "hour":
return bilevelFormat(d3.utcFormat("%b %-d"), d3.utcFormat("%-I %p"), d3.utcDay, d3.utcHour, step);
case "day":
return bilevelFormat(d3.utcFormat("%b"), d3.utcFormat("%-d"), d3.utcMonth, d3.utcDay, step);
case "week":
return bilevelFormat(d3.utcFormat("%b"), d3.utcFormat("%-d"), d3.utcMonth, d3.utcDay, step * 7);
case "month":
return bilevelFormat(d3.utcFormat("%Y"), d3.utcFormat("%b"), d3.utcYear, d3.utcMonth, step);
case "year":
return d3.utcFormat("%Y");
}
return [interval, step];
}
Insert cell
function bilevelFormatX(format1, format2, interval1, interval2, step) {
return (x, i, X) =>
interval2.count(interval1(x), x) < step || i === (X[0] > X[X.length - 1] ? X.length - 1 : 0)
? `${format2(x)}\n${format1(x)}`
: format2(x);
}
Insert cell
function bilevelFormatY(format1, format2, interval1, interval2, step) {
return (x, i, X) =>
interval2.count(interval1(x), x) < step || i === (X[0] > X[X.length - 1] ? X.length - 1 : 0)
// ? `${format1(x)} ${format2(x)}`
? `\n${format2(x)}\n${format1(x)}` // a \n is added for vertical symmetry
: format2(x);
}
Insert cell
tplot = scale === "x" ? xplot : yplot
Insert cell
function xplot(start, stop) {
const count = 360 / 35; // 600 / 80;
return Plot.plot({
marginTop: 0,
height: 40,
x: {
type: "utc",
domain: [start, stop],
reverse
},
marks: [
Plot.axisX({
tickFormat: multi ? tickFormat(bilevelFormatX, start, stop, count) : undefined,
ticks: multi ? count : undefined,
title: Plot.identity
})
]
});
}
Insert cell
function yplot(start, stop) {
const count = 360 / 35;
return Plot.plot({
y: {
type: "utc",
domain: [start, stop],
reverse
},
marks: [
Plot.axisY({
tickFormat: multi ? tickFormat(bilevelFormatY, start, stop, count) : undefined,
ticks: multi ? count : undefined,
title: Plot.identity
}),
Plot.gridY({
ticks: multi ? count : undefined
})
]
});
}
Insert cell
function tickInterval(start, stop, count) {
const target = Math.abs(stop - start) / count;
const i = d3.bisector(([,, step]) => step).right(tickIntervals, target);
if (i === tickIntervals.length) {
return ["year", d3.tickStep(start / durationYear, stop / durationYear, count)];
}
if (i === 0) {
const step = Math.max(d3.tickStep(start, stop, count), 1);
if (step === 1000) return ["second", 1];
return ["millisecond", step];
}
return tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
}
Insert cell
tickIntervals = [
["second", 1, durationSecond],
["second", 5, 5 * durationSecond],
["second", 15, 15 * durationSecond],
["second", 30, 30 * durationSecond],
["minute", 1, durationMinute],
["minute", 5, 5 * durationMinute],
["minute", 15, 15 * durationMinute],
["minute", 30, 30 * durationMinute],
[ "hour", 1, durationHour ],
[ "hour", 3, 3 * durationHour ],
[ "hour", 6, 6 * durationHour ],
[ "hour", 12, 12 * durationHour ],
[ "day", 1, durationDay ],
[ "day", 2, 2 * durationDay ],
[ "week", 1, durationWeek ],
[ "month", 1, durationMonth ],
[ "month", 3, 3 * durationMonth ],
[ "year", 1, durationYear ]
]
Insert cell
durationSecond = 1000
Insert cell
durationMinute = durationSecond * 60
Insert cell
durationHour = durationMinute * 60
Insert cell
durationDay = durationHour * 24
Insert cell
durationWeek = durationDay * 7
Insert cell
durationMonth = durationDay * 30
Insert cell
durationYear = durationDay * 365
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