|
1 | 1 | import * as Plot from "npm:@observablehq/plot";
|
2 |
| -import * as d3 from "npm:d3"; |
3 | 2 |
|
4 |
| -export const today = d3.utcDay(d3.utcHour.offset(d3.utcHour(), -10)); |
5 |
| -export const start = d3.utcYear.offset(today, -2); |
6 |
| - |
7 |
| -export function DailyPlot(data, {title, label = title, domain, width, height = 200, versions} = {}) { |
| 3 | +export function DailyPlot(data, {round = true, annotations, ...options} = {}) { |
8 | 4 | return Plot.plot({
|
9 |
| - width, |
10 |
| - height, |
11 |
| - round: true, |
12 |
| - marginRight: 60, |
13 |
| - x: {domain: [start, today]}, |
14 |
| - y: {domain, label, insetTop: versions ? 60 : 0}, |
| 5 | + ...options, |
| 6 | + round, |
15 | 7 | marks: [
|
16 |
| - Plot.axisY({ |
17 |
| - anchor: "right", |
18 |
| - label: `${title} (line = 28-day, blue = 7-day)` |
19 |
| - }), |
20 |
| - Plot.areaY( |
21 |
| - data, |
22 |
| - Plot.filter((d) => d.date >= start, { |
23 |
| - x: "date", |
24 |
| - y: "value", |
25 |
| - curve: "step", |
26 |
| - fillOpacity: 0.2 |
27 |
| - }) |
28 |
| - ), |
| 8 | + Plot.axisY({anchor: "right", label: null}), |
| 9 | + Plot.areaY(data, {x: "date", y: "value", curve: "step", fillOpacity: 0.2}), |
29 | 10 | Plot.ruleY([0]),
|
30 | 11 | Plot.lineY(
|
31 | 12 | data,
|
32 |
| - Plot.filter( |
33 |
| - (d) => d.date >= start, |
34 |
| - Plot.windowY( |
35 |
| - {k: 7, anchor: "start", strict: true}, |
36 |
| - { |
37 |
| - x: "date", |
38 |
| - y: "value", |
39 |
| - strokeWidth: 1, |
40 |
| - stroke: "var(--theme-foreground-focus)" |
41 |
| - } |
42 |
| - ) |
43 |
| - ) |
44 |
| - ), |
45 |
| - Plot.lineY( |
46 |
| - data, |
47 |
| - Plot.filter( |
48 |
| - (d) => d.date >= start, |
49 |
| - Plot.windowY({k: 28, anchor: "start", strict: true}, {x: "date", y: "value"}) |
| 13 | + Plot.windowY( |
| 14 | + {k: 7, anchor: "start", strict: true}, |
| 15 | + {x: "date", y: "value", stroke: "var(--theme-foreground-focus)"} |
50 | 16 | )
|
51 | 17 | ),
|
52 |
| - versionsMarks(versions), |
53 |
| - Plot.tip( |
54 |
| - data, |
55 |
| - Plot.pointerX({ |
| 18 | + Plot.lineY(data, Plot.windowY({k: 28, anchor: "start", strict: true}, {x: "date", y: "value"})), |
| 19 | + annotations && [ |
| 20 | + Plot.ruleX(annotations, {x: "date", strokeOpacity: 0.1}), |
| 21 | + Plot.text(annotations, { |
56 | 22 | x: "date",
|
57 |
| - y: "value", |
58 |
| - format: {y: ",.0f"} |
| 23 | + text: "text", |
| 24 | + href: "href", |
| 25 | + target: "_blank", |
| 26 | + rotate: -90, |
| 27 | + dx: -3, |
| 28 | + frameAnchor: "top-right", |
| 29 | + lineAnchor: "bottom", |
| 30 | + fontVariant: "tabular-nums", |
| 31 | + fill: "currentColor", |
| 32 | + stroke: "var(--theme-background)" |
59 | 33 | })
|
60 |
| - ) |
| 34 | + ], |
| 35 | + Plot.tip(data, Plot.pointerX({x: "date", y: "value"})) |
61 | 36 | ]
|
62 | 37 | });
|
63 | 38 | }
|
64 |
| - |
65 |
| -function versionsMarks(versions) { |
66 |
| - if (!versions) return []; |
67 |
| - const clip = true; |
68 |
| - return [ |
69 |
| - Plot.ruleX(versions, { |
70 |
| - filter: (d) => !isPrerelease(d.version), |
71 |
| - x: "date", |
72 |
| - strokeOpacity: (d) => (isMajor(d.version) ? 1 : 0.1), |
73 |
| - clip |
74 |
| - }), |
75 |
| - Plot.text(versions, { |
76 |
| - filter: (d) => !isPrerelease(d.version) && !isMajor(d.version), |
77 |
| - x: "date", |
78 |
| - text: "version", |
79 |
| - rotate: -90, |
80 |
| - dx: -10, |
81 |
| - frameAnchor: "top-right", |
82 |
| - fontVariant: "tabular-nums", |
83 |
| - fill: "currentColor", |
84 |
| - stroke: "var(--theme-background)", |
85 |
| - clip |
86 |
| - }), |
87 |
| - Plot.text(versions, { |
88 |
| - filter: (d) => isMajor(d.version), |
89 |
| - x: "date", |
90 |
| - text: "version", |
91 |
| - rotate: -90, |
92 |
| - dx: -10, |
93 |
| - frameAnchor: "top-right", |
94 |
| - fontVariant: "tabular-nums", |
95 |
| - fill: "currentColor", |
96 |
| - stroke: "white", |
97 |
| - fontWeight: "bold", |
98 |
| - clip |
99 |
| - }) |
100 |
| - ]; |
101 |
| -} |
102 |
| - |
103 |
| -function isPrerelease(version) { |
104 |
| - return /-/.test(version); |
105 |
| -} |
106 |
| - |
107 |
| -function isMajor(version) { |
108 |
| - return /^\d+\.0\.0$/.test(version); |
109 |
| -} |
0 commit comments