@sckyzo/cosmos-charts 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +107 -22
  3. package/THIRD_PARTY_NOTICES.md +81 -0
  4. package/dist/BarChart.cjs +137 -0
  5. package/dist/BarChart.cjs.map +1 -0
  6. package/dist/BarChart.js +135 -0
  7. package/dist/BarChart.js.map +1 -0
  8. package/dist/BoxPlotChart.cjs +214 -0
  9. package/dist/BoxPlotChart.cjs.map +1 -0
  10. package/dist/BoxPlotChart.js +212 -0
  11. package/dist/BoxPlotChart.js.map +1 -0
  12. package/dist/BumpChart.cjs +328 -0
  13. package/dist/BumpChart.cjs.map +1 -0
  14. package/dist/BumpChart.js +326 -0
  15. package/dist/BumpChart.js.map +1 -0
  16. package/dist/CalendarChart.cjs +216 -0
  17. package/dist/CalendarChart.cjs.map +1 -0
  18. package/dist/CalendarChart.js +214 -0
  19. package/dist/CalendarChart.js.map +1 -0
  20. package/dist/DonutChart.cjs +122 -0
  21. package/dist/DonutChart.cjs.map +1 -0
  22. package/dist/DonutChart.js +120 -0
  23. package/dist/DonutChart.js.map +1 -0
  24. package/dist/FunnelChart.cjs +422 -0
  25. package/dist/FunnelChart.cjs.map +1 -0
  26. package/dist/FunnelChart.js +420 -0
  27. package/dist/FunnelChart.js.map +1 -0
  28. package/dist/GradientRadial.cjs +51 -0
  29. package/dist/GradientRadial.cjs.map +1 -0
  30. package/dist/GradientRadial.js +49 -0
  31. package/dist/GradientRadial.js.map +1 -0
  32. package/dist/HeatmapChart.cjs +146 -0
  33. package/dist/HeatmapChart.cjs.map +1 -0
  34. package/dist/HeatmapChart.js +144 -0
  35. package/dist/HeatmapChart.js.map +1 -0
  36. package/dist/LineAreaChart.cjs +98 -0
  37. package/dist/LineAreaChart.cjs.map +1 -0
  38. package/dist/LineAreaChart.js +96 -0
  39. package/dist/LineAreaChart.js.map +1 -0
  40. package/dist/MixedChart.cjs +195 -0
  41. package/dist/MixedChart.cjs.map +1 -0
  42. package/dist/MixedChart.js +193 -0
  43. package/dist/MixedChart.js.map +1 -0
  44. package/dist/RadarChart.cjs +109 -0
  45. package/dist/RadarChart.cjs.map +1 -0
  46. package/dist/RadarChart.js +107 -0
  47. package/dist/RadarChart.js.map +1 -0
  48. package/dist/RadialBarChart.cjs +99 -0
  49. package/dist/RadialBarChart.cjs.map +1 -0
  50. package/dist/RadialBarChart.js +97 -0
  51. package/dist/RadialBarChart.js.map +1 -0
  52. package/dist/RangeBarChart.cjs +218 -0
  53. package/dist/RangeBarChart.cjs.map +1 -0
  54. package/dist/RangeBarChart.js +216 -0
  55. package/dist/RangeBarChart.js.map +1 -0
  56. package/dist/RealtimeChart.cjs +173 -0
  57. package/dist/RealtimeChart.cjs.map +1 -0
  58. package/dist/RealtimeChart.js +171 -0
  59. package/dist/RealtimeChart.js.map +1 -0
  60. package/dist/ScatterChart.cjs +134 -0
  61. package/dist/ScatterChart.cjs.map +1 -0
  62. package/dist/ScatterChart.js +131 -0
  63. package/dist/ScatterChart.js.map +1 -0
  64. package/dist/SemiCircleGauge.cjs +142 -0
  65. package/dist/SemiCircleGauge.cjs.map +1 -0
  66. package/dist/SemiCircleGauge.js +140 -0
  67. package/dist/SemiCircleGauge.js.map +1 -0
  68. package/dist/Sparkline.cjs +117 -0
  69. package/dist/Sparkline.cjs.map +1 -0
  70. package/dist/Sparkline.js +115 -0
  71. package/dist/Sparkline.js.map +1 -0
  72. package/dist/StrokedGauge.cjs +94 -0
  73. package/dist/StrokedGauge.cjs.map +1 -0
  74. package/dist/StrokedGauge.js +92 -0
  75. package/dist/StrokedGauge.js.map +1 -0
  76. package/dist/TreemapChart.cjs +263 -0
  77. package/dist/TreemapChart.cjs.map +1 -0
  78. package/dist/TreemapChart.js +261 -0
  79. package/dist/TreemapChart.js.map +1 -0
  80. package/dist/WaterfallChart.cjs +235 -0
  81. package/dist/WaterfallChart.cjs.map +1 -0
  82. package/dist/WaterfallChart.js +233 -0
  83. package/dist/WaterfallChart.js.map +1 -0
  84. package/dist/WorldMap.cjs +2088 -0
  85. package/dist/WorldMap.cjs.map +1 -0
  86. package/dist/WorldMap.js +603 -0
  87. package/dist/WorldMap.js.map +1 -0
  88. package/dist/chunk-3N43QT36.js +60 -0
  89. package/dist/chunk-3N43QT36.js.map +1 -0
  90. package/dist/chunk-5C2RLJYZ.js +11 -0
  91. package/dist/chunk-5C2RLJYZ.js.map +1 -0
  92. package/dist/chunk-6ALKZLN2.js +127 -0
  93. package/dist/chunk-6ALKZLN2.js.map +1 -0
  94. package/dist/chunk-6BKLL7LZ.cjs +30 -0
  95. package/dist/chunk-6BKLL7LZ.cjs.map +1 -0
  96. package/dist/chunk-6NRRABPF.cjs +64 -0
  97. package/dist/chunk-6NRRABPF.cjs.map +1 -0
  98. package/dist/chunk-AAYHG7YK.cjs +30 -0
  99. package/dist/chunk-AAYHG7YK.cjs.map +1 -0
  100. package/dist/chunk-AOSO5QHL.js +19 -0
  101. package/dist/chunk-AOSO5QHL.js.map +1 -0
  102. package/dist/chunk-BFEDLXVW.js +12 -0
  103. package/dist/chunk-BFEDLXVW.js.map +1 -0
  104. package/dist/chunk-DBZQI4HM.cjs +14 -0
  105. package/dist/chunk-DBZQI4HM.cjs.map +1 -0
  106. package/dist/chunk-F2PMFYJ5.cjs +40 -0
  107. package/dist/chunk-F2PMFYJ5.cjs.map +1 -0
  108. package/dist/chunk-FUZW3H5X.js +38 -0
  109. package/dist/chunk-FUZW3H5X.js.map +1 -0
  110. package/dist/chunk-GDZLYYL2.js +27 -0
  111. package/dist/chunk-GDZLYYL2.js.map +1 -0
  112. package/dist/chunk-GVTMZYOM.cjs +30 -0
  113. package/dist/chunk-GVTMZYOM.cjs.map +1 -0
  114. package/dist/chunk-GZRMVE4X.cjs +131 -0
  115. package/dist/chunk-GZRMVE4X.cjs.map +1 -0
  116. package/dist/chunk-HMH6DI7U.js +27 -0
  117. package/dist/chunk-HMH6DI7U.js.map +1 -0
  118. package/dist/chunk-ICL5K2CW.js +280 -0
  119. package/dist/chunk-ICL5K2CW.js.map +1 -0
  120. package/dist/chunk-IW6EWB26.cjs +21 -0
  121. package/dist/chunk-IW6EWB26.cjs.map +1 -0
  122. package/dist/chunk-K3R7JGOW.cjs +18 -0
  123. package/dist/chunk-K3R7JGOW.cjs.map +1 -0
  124. package/dist/chunk-LT3UC65O.cjs +68 -0
  125. package/dist/chunk-LT3UC65O.cjs.map +1 -0
  126. package/dist/chunk-MN4CDVOS.cjs +63 -0
  127. package/dist/chunk-MN4CDVOS.cjs.map +1 -0
  128. package/dist/chunk-OCD6JIIX.js +23 -0
  129. package/dist/chunk-OCD6JIIX.js.map +1 -0
  130. package/dist/chunk-RILUG7JB.js +44 -0
  131. package/dist/chunk-RILUG7JB.js.map +1 -0
  132. package/dist/chunk-RLHGPHC7.cjs +51 -0
  133. package/dist/chunk-RLHGPHC7.cjs.map +1 -0
  134. package/dist/chunk-SGG7XKOY.js +58 -0
  135. package/dist/chunk-SGG7XKOY.js.map +1 -0
  136. package/dist/chunk-T3K6Q34U.cjs +82 -0
  137. package/dist/chunk-T3K6Q34U.cjs.map +1 -0
  138. package/dist/chunk-TPH5T3DA.cjs +282 -0
  139. package/dist/chunk-TPH5T3DA.cjs.map +1 -0
  140. package/dist/chunk-TYQWZR3S.cjs +13 -0
  141. package/dist/chunk-TYQWZR3S.cjs.map +1 -0
  142. package/dist/chunk-UATB2IRY.js +51 -0
  143. package/dist/chunk-UATB2IRY.js.map +1 -0
  144. package/dist/chunk-UJIV5PVI.js +13 -0
  145. package/dist/chunk-UJIV5PVI.js.map +1 -0
  146. package/dist/chunk-URNXLVSK.js +44 -0
  147. package/dist/chunk-URNXLVSK.js.map +1 -0
  148. package/dist/chunk-VIOSQN4Z.js +79 -0
  149. package/dist/chunk-VIOSQN4Z.js.map +1 -0
  150. package/dist/chunk-X3YZP5WF.cjs +46 -0
  151. package/dist/chunk-X3YZP5WF.cjs.map +1 -0
  152. package/dist/chunk-YWYF5CCJ.js +61 -0
  153. package/dist/chunk-YWYF5CCJ.js.map +1 -0
  154. package/dist/chunk-Z4LZFMDH.cjs +60 -0
  155. package/dist/chunk-Z4LZFMDH.cjs.map +1 -0
  156. package/dist/index.cjs +154 -1166
  157. package/dist/index.cjs.map +1 -1
  158. package/dist/index.d.cts +470 -80
  159. package/dist/index.d.ts +470 -80
  160. package/dist/index.js +23 -1144
  161. package/dist/index.js.map +1 -1
  162. package/dist/theme.cjs +88 -0
  163. package/dist/theme.cjs.map +1 -0
  164. package/dist/theme.js +84 -0
  165. package/dist/theme.js.map +1 -0
  166. package/package.json +23 -12
@@ -0,0 +1,326 @@
1
+ "use client";
2
+ import { categoryAxis } from './chunk-HMH6DI7U.js';
3
+ import { useElementWidth } from './chunk-AOSO5QHL.js';
4
+ import { ANIMATION } from './chunk-5C2RLJYZ.js';
5
+ import { AXIS } from './chunk-RILUG7JB.js';
6
+ import { TooltipCard } from './chunk-VIOSQN4Z.js';
7
+ import { seriesKey, hasNoData } from './chunk-UJIV5PVI.js';
8
+ import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
9
+ import { BORDER, seriesColor, MUTED, PANEL, TEXT } from './chunk-UATB2IRY.js';
10
+ import { useState, useMemo } from 'react';
11
+ import { LineChart, XAxis, YAxis, Tooltip, Line } from 'recharts';
12
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
13
+
14
+ // src/core/bump.ts
15
+ var periodsOf = (series) => {
16
+ const seen = /* @__PURE__ */ new Set();
17
+ for (const s of series) for (const point of s.data) seen.add(point.x);
18
+ return [...seen];
19
+ };
20
+ var ranksOf = (series, periods) => {
21
+ const index = new Map(periods.map((period, i) => [period, i]));
22
+ return series.map((s) => {
23
+ const ranks = periods.map(() => void 0);
24
+ for (const point of s.data) {
25
+ const at = index.get(point.x);
26
+ if (at !== void 0 && Number.isFinite(point.rank)) ranks[at] = point.rank;
27
+ }
28
+ return ranks;
29
+ });
30
+ };
31
+ var TIE_SPREAD = 0.5;
32
+ var plottedRanks = (ranks) => {
33
+ const plotted = ranks.map((r) => [...r]);
34
+ const periods = Math.max(0, ...ranks.map((r) => r.length));
35
+ for (let p = 0; p < periods; p++) {
36
+ const groups = /* @__PURE__ */ new Map();
37
+ ranks.forEach((r, s) => {
38
+ const rank = r[p];
39
+ if (rank !== void 0) groups.set(rank, [...groups.get(rank) ?? [], s]);
40
+ });
41
+ for (const [rank, members] of groups) {
42
+ members.forEach((s, k) => {
43
+ plotted[s][p] = rank + (k - (members.length - 1) / 2) * TIE_SPREAD;
44
+ });
45
+ }
46
+ }
47
+ return plotted;
48
+ };
49
+ var rankChange = (ranks, periods, index) => {
50
+ const rank = ranks[index];
51
+ if (index === 0 || rank === void 0) return void 0;
52
+ const before = ranks[index - 1];
53
+ if (before === void 0) return { direction: "new" };
54
+ const versus = periods[index - 1];
55
+ if (rank === before) return { direction: "same", versus };
56
+ return rank < before ? { direction: "up", by: before - rank, versus } : { direction: "down", by: rank - before, versus };
57
+ };
58
+ var describeChange = (change) => {
59
+ switch (change.direction) {
60
+ case "same":
61
+ return `unchanged vs ${change.versus}`;
62
+ case "new":
63
+ return "new entry";
64
+ default:
65
+ return `${change.direction} ${change.by} vs ${change.versus}`;
66
+ }
67
+ };
68
+ var rankSpan = (ranks) => {
69
+ const first = ranks.findIndex((r) => r !== void 0);
70
+ if (first === -1) return void 0;
71
+ let last = ranks.length - 1;
72
+ while (ranks[last] === void 0) last--;
73
+ return { first, last };
74
+ };
75
+ var shortName = (name, max) => name.length > max ? `${name.slice(0, Math.max(1, max - 1))}\u2026` : name;
76
+ var defaultFormat = (rank) => `#${rank}`;
77
+ var COMPACT_BELOW = 560;
78
+ var NAME_CHARS = { wide: 12, compact: 8 };
79
+ var NAME_GAP = 32;
80
+ var CHAR_WIDTH = 9;
81
+ var DOT_OFFSET = 18;
82
+ var RANK_STROKE = 2.5;
83
+ var MIN_DISC_STEP = 26;
84
+ var RANK_RADIUS = 12 - RANK_STROKE / 2;
85
+ var DOT_RADIUS = 4;
86
+ var BumpTooltip = ({
87
+ active,
88
+ label,
89
+ series,
90
+ periods,
91
+ ranks,
92
+ colors,
93
+ focus,
94
+ format
95
+ }) => {
96
+ const period = periods.indexOf(String(label));
97
+ if (!active || period === -1) return null;
98
+ const indexes = focus === null ? series.map((_, i) => i) : [focus];
99
+ const rows = indexes.map((i) => ({ i, rank: ranks[i][period] })).filter(({ i, rank }) => rank !== void 0 || i === focus).sort((a, b) => (a.rank ?? Infinity) - (b.rank ?? Infinity) || a.i - b.i).map(({ i, rank }) => {
100
+ const change = rank === void 0 ? void 0 : rankChange(ranks[i], periods, period);
101
+ return {
102
+ name: series[i].name,
103
+ color: seriesColor(i, colors),
104
+ value: rank === void 0 ? "not ranked" : /* @__PURE__ */ jsxs(Fragment, { children: [
105
+ format(rank),
106
+ change && /* @__PURE__ */ jsx("span", { style: { marginLeft: "0.5rem", fontWeight: 400, color: MUTED }, children: describeChange(change) })
107
+ ] })
108
+ };
109
+ });
110
+ return /* @__PURE__ */ jsx(TooltipCard, { title: periods[period], rows });
111
+ };
112
+ var BumpChart = ({
113
+ series,
114
+ colors,
115
+ formatValue = defaultFormat,
116
+ points = "rank",
117
+ emptyMessage = "No data",
118
+ ariaLabel,
119
+ children,
120
+ height = 320,
121
+ width
122
+ }) => {
123
+ const [focus, setFocus] = useState(null);
124
+ const { ref, width: measured } = useElementWidth();
125
+ const name = ariaLabel ?? `Bump chart: ${series.map((s) => s.name).join(", ")}`;
126
+ const periods = useMemo(() => periodsOf(series), [series]);
127
+ const ranks = useMemo(() => ranksOf(series, periods), [series, periods]);
128
+ const plotted = useMemo(() => plottedRanks(ranks), [ranks]);
129
+ const rows = useMemo(
130
+ () => periods.map((period, p) => ({
131
+ category: period,
132
+ ...Object.fromEntries(plotted.map((r, i) => [seriesKey(i), r[p]]))
133
+ })),
134
+ [periods, plotted]
135
+ );
136
+ if (hasNoData(series) || periods.length === 0) {
137
+ return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
138
+ }
139
+ const compact = measured !== void 0 && measured < COMPACT_BELOW;
140
+ const chars = compact ? NAME_CHARS.compact : NAME_CHARS.wide;
141
+ const room = Math.min(chars, Math.max(...series.map((s) => s.name.length))) * CHAR_WIDTH + NAME_GAP;
142
+ const margin = {
143
+ top: 8,
144
+ right: room,
145
+ bottom: 0,
146
+ // The first disc hangs out of the plot by its radius.
147
+ left: compact ? 12 + 4 : room
148
+ };
149
+ const step = measured === void 0 ? Infinity : (measured - margin.left - margin.right) / Math.max(1, periods.length - 1);
150
+ const asRank = points === "rank" && step >= MIN_DISC_STEP;
151
+ const flat = plotted.flat().filter((v) => v !== void 0);
152
+ const spare = TIE_SPREAD + 0.05;
153
+ const domain = [Math.min(...flat) - spare, Math.max(...flat) + spare];
154
+ const spans = ranks.map(rankSpan);
155
+ const onKeyDown = (event) => {
156
+ const step2 = { ArrowDown: 1, ArrowUp: -1 }[event.key];
157
+ if (step2 !== void 0) {
158
+ event.preventDefault();
159
+ setFocus(
160
+ (current) => current === null ? step2 === 1 ? 0 : series.length - 1 : (current + step2 + series.length) % series.length
161
+ );
162
+ } else if (event.key === "Escape" && focus !== null) {
163
+ event.preventDefault();
164
+ setFocus(null);
165
+ }
166
+ };
167
+ const onBlur = (event) => {
168
+ if (!event.currentTarget.contains(event.relatedTarget)) setFocus(null);
169
+ };
170
+ const pointer = (i) => ({
171
+ onMouseEnter: () => setFocus(i),
172
+ onMouseLeave: () => setFocus(null)
173
+ });
174
+ const renderDot = (i) => {
175
+ const color = seriesColor(i, colors);
176
+ const Dot = ({ cx, cy, index }) => {
177
+ const rank = ranks[i][index];
178
+ if (rank === void 0 || cx === void 0 || cy === void 0) return null;
179
+ return /* @__PURE__ */ jsx(
180
+ "g",
181
+ {
182
+ "data-bump-point": "",
183
+ opacity: focus !== null && focus !== i ? 0.3 : 1,
184
+ ...pointer(i),
185
+ style: { transition: "opacity 150ms" },
186
+ children: asRank ? /* @__PURE__ */ jsxs(Fragment, { children: [
187
+ /* @__PURE__ */ jsx(
188
+ "circle",
189
+ {
190
+ cx,
191
+ cy,
192
+ r: RANK_RADIUS,
193
+ fill: PANEL,
194
+ stroke: color,
195
+ strokeWidth: 2.5
196
+ }
197
+ ),
198
+ /* @__PURE__ */ jsx(
199
+ "text",
200
+ {
201
+ x: cx,
202
+ y: cy,
203
+ textAnchor: "middle",
204
+ dominantBaseline: "central",
205
+ fill: TEXT,
206
+ style: { fontSize: "var(--text-2xs, 0.6875rem)", fontWeight: 700 },
207
+ children: rank
208
+ }
209
+ )
210
+ ] }) : /* @__PURE__ */ jsx("circle", { cx, cy, r: DOT_RADIUS, fill: color, stroke: PANEL, strokeWidth: 2 })
211
+ },
212
+ index
213
+ );
214
+ };
215
+ return Dot;
216
+ };
217
+ const renderName = (i) => {
218
+ const color = seriesColor(i, colors);
219
+ const span = spans[i];
220
+ const text = shortName(series[i].name, chars);
221
+ const Name = ({
222
+ x,
223
+ y,
224
+ index
225
+ }) => {
226
+ if (!span || typeof x !== "number" || typeof y !== "number") return null;
227
+ const end = index === span.last;
228
+ const start = index === span.first && !compact && span.first !== span.last;
229
+ if (!end && !start) return null;
230
+ const side = end ? 1 : -1;
231
+ return /* @__PURE__ */ jsxs(
232
+ "g",
233
+ {
234
+ "data-bump-name": "",
235
+ opacity: focus !== null && focus !== i ? 0.3 : 1,
236
+ ...pointer(i),
237
+ style: { transition: "opacity 150ms" },
238
+ children: [
239
+ /* @__PURE__ */ jsx("circle", { cx: x + side * DOT_OFFSET, cy: y, r: 4, fill: color }),
240
+ /* @__PURE__ */ jsx(
241
+ "text",
242
+ {
243
+ x: x + side * (DOT_OFFSET + 10),
244
+ y,
245
+ textAnchor: end ? "start" : "end",
246
+ dominantBaseline: "central",
247
+ fill: TEXT,
248
+ stroke: PANEL,
249
+ strokeWidth: 3,
250
+ strokeLinejoin: "round",
251
+ paintOrder: "stroke",
252
+ style: { fontSize: "var(--text-sm, 0.875rem)", fontWeight: 600 },
253
+ children: text
254
+ }
255
+ )
256
+ ]
257
+ },
258
+ `${index}`
259
+ );
260
+ };
261
+ return Name;
262
+ };
263
+ return /* @__PURE__ */ jsx(
264
+ "div",
265
+ {
266
+ ref,
267
+ onKeyDown,
268
+ onBlur,
269
+ style: { width: width ?? "100%", maxWidth: "100%" },
270
+ children: /* @__PURE__ */ jsxs(
271
+ LineChart,
272
+ {
273
+ ...frameProps({ height, width: "100%", ariaLabel: name }),
274
+ data: rows,
275
+ margin,
276
+ children: [
277
+ /* @__PURE__ */ jsx(XAxis, { dataKey: "category", ...AXIS, ...categoryAxis(periods) }),
278
+ /* @__PURE__ */ jsx(YAxis, { hide: true, type: "number", reversed: true, domain }),
279
+ /* @__PURE__ */ jsx(
280
+ Tooltip,
281
+ {
282
+ content: /* @__PURE__ */ jsx(
283
+ BumpTooltip,
284
+ {
285
+ series,
286
+ periods,
287
+ ranks,
288
+ colors,
289
+ focus,
290
+ format: formatValue
291
+ }
292
+ ),
293
+ cursor: { stroke: BORDER, strokeDasharray: "4 4" },
294
+ animationDuration: 150
295
+ }
296
+ ),
297
+ series.map((s, i) => /* @__PURE__ */ jsx(
298
+ Line,
299
+ {
300
+ name: s.name,
301
+ dataKey: seriesKey(i),
302
+ type: "bumpX",
303
+ stroke: seriesColor(i, colors),
304
+ strokeWidth: focus === i ? 4 : 3,
305
+ strokeOpacity: focus !== null && focus !== i ? 0.2 : 1,
306
+ strokeLinecap: "round",
307
+ connectNulls: false,
308
+ dot: renderDot(i),
309
+ activeDot: false,
310
+ label: renderName(i),
311
+ ...pointer(i),
312
+ ...ANIMATION
313
+ },
314
+ seriesKey(i)
315
+ )),
316
+ children
317
+ ]
318
+ }
319
+ )
320
+ }
321
+ );
322
+ };
323
+
324
+ export { BumpChart };
325
+ //# sourceMappingURL=BumpChart.js.map
326
+ //# sourceMappingURL=BumpChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/bump.ts","../src/BumpChart.tsx"],"names":["step"],"mappings":"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","file":"BumpChart.js","sourcesContent":["// The pure part of `BumpChart`: periods, ranks, ties and the change in rank\n// from one period to the previous, in words.\n\nexport type BumpPoint = { x: string; rank: number };\nexport type BumpSeries = { name: string; data: BumpPoint[] };\n\n/** A rank per period, `undefined` where the series is not in the ranking. */\nexport type RanksByPeriod = (number | undefined)[];\n\n/**\n * The periods of the chart, left to right: every `x` once, in the order they\n * first appear. A series that enters late adds no period of its own as long as\n * an earlier series lists it.\n */\nexport const periodsOf = (series: readonly BumpSeries[]): string[] => {\n const seen = new Set<string>();\n for (const s of series) for (const point of s.data) seen.add(point.x);\n return [...seen];\n};\n\n/**\n * The rank of each series in each period, `ranks[series][period]`. A series\n * without a point in a period (it has not entered yet, or left) has\n * `undefined` there. A period listed twice keeps its last rank; a rank that is\n * not a finite number counts as missing.\n */\nexport const ranksOf = (series: readonly BumpSeries[], periods: readonly string[]) => {\n const index = new Map(periods.map((period, i) => [period, i]));\n return series.map((s) => {\n const ranks: RanksByPeriod = periods.map(() => undefined);\n for (const point of s.data) {\n const at = index.get(point.x);\n if (at !== undefined && Number.isFinite(point.rank)) ranks[at] = point.rank;\n }\n return ranks;\n });\n};\n\n/** How far apart, in ranks, series tied on one rank are drawn. */\nexport const TIE_SPREAD = 0.5;\n\n/**\n * Where each rank is drawn. Series tied on a rank in a period are spread\n * around it, in series order, so that their points do not sit on one another;\n * everything else is drawn on its rank. The tooltip and the point labels keep\n * the real rank.\n */\nexport const plottedRanks = (ranks: readonly RanksByPeriod[]): RanksByPeriod[] => {\n const plotted = ranks.map((r) => [...r]);\n const periods = Math.max(0, ...ranks.map((r) => r.length));\n for (let p = 0; p < periods; p++) {\n const groups = new Map<number, number[]>();\n ranks.forEach((r, s) => {\n const rank = r[p];\n if (rank !== undefined) groups.set(rank, [...(groups.get(rank) ?? []), s]);\n });\n for (const [rank, members] of groups) {\n members.forEach((s, k) => {\n plotted[s][p] = rank + (k - (members.length - 1) / 2) * TIE_SPREAD;\n });\n }\n }\n return plotted;\n};\n\n/** The change in rank of a series in a period, against the period before. */\nexport type RankChange =\n | { direction: 'up' | 'down'; by: number; versus: string }\n | { direction: 'same'; versus: string }\n | { direction: 'new' };\n\n/**\n * The change in rank in period `index`: `up` when the rank number got smaller\n * (closer to 1), `down` when it got larger. `undefined` for the first period,\n * which has nothing to compare with, and for a period the series is not in. A\n * series with no rank in the previous period is `new`.\n */\nexport const rankChange = (\n ranks: RanksByPeriod,\n periods: readonly string[],\n index: number\n): RankChange | undefined => {\n const rank = ranks[index];\n if (index === 0 || rank === undefined) return undefined;\n const before = ranks[index - 1];\n if (before === undefined) return { direction: 'new' };\n const versus = periods[index - 1];\n if (rank === before) return { direction: 'same', versus };\n return rank < before\n ? { direction: 'up', by: before - rank, versus }\n : { direction: 'down', by: rank - before, versus };\n};\n\n/**\n * The change in words, so that it never rests on a color or an arrow:\n * \"unchanged vs May\", \"up 2 vs Apr\", \"down 1 vs Mar\", \"new entry\".\n */\nexport const describeChange = (change: RankChange): string => {\n switch (change.direction) {\n case 'same':\n return `unchanged vs ${change.versus}`;\n case 'new':\n return 'new entry';\n default:\n return `${change.direction} ${change.by} vs ${change.versus}`;\n }\n};\n\n/** The first and last period a series has a rank in, or `undefined` when it has none. */\nexport const rankSpan = (ranks: RanksByPeriod): { first: number; last: number } | undefined => {\n const first = ranks.findIndex((r) => r !== undefined);\n if (first === -1) return undefined;\n let last = ranks.length - 1;\n while (ranks[last] === undefined) last--;\n return { first, last };\n};\n\n/** A name cut to `max` characters with an ellipsis; the tooltip keeps the full name. */\nexport const shortName = (name: string, max: number): string =>\n name.length > max ? `${name.slice(0, Math.max(1, max - 1))}…` : name;\n","import { useMemo, useState, type FocusEvent, type KeyboardEvent, type ReactNode } from 'react';\nimport { Line, LineChart, Tooltip, XAxis, YAxis, type DotItemDotProps } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { AXIS } from './core/axes';\nimport {\n describeChange,\n periodsOf,\n plottedRanks,\n rankChange,\n rankSpan,\n ranksOf,\n shortName,\n TIE_SPREAD,\n type BumpSeries,\n} from './core/bump';\nimport { categoryAxis } from './core/categoryAxis';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { BORDER, MUTED, PANEL, TEXT, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { useElementWidth } from './core/useElementWidth';\nimport type { ChartEmptyProps, ChartProps } from './types';\n\nexport type { BumpPoint, BumpSeries } from './core/bump';\n\nexport type BumpChartPoints = 'rank' | 'dot';\n\nexport type BumpChartProps = ChartProps &\n ChartEmptyProps & {\n /**\n * One entry per ranked item. `data` lists the rank (1 is the top) of the\n * item in each period. The periods are every `x` once, in the order they\n * first appear, so list them in order in the series that has them all. A\n * period an item has no point in (it enters late, or leaves) is a gap in\n * its line. Ties are allowed: items tied on a rank are drawn apart around it.\n */\n series: BumpSeries[];\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format a rank in the tooltip. Default `#1`, `#2`…; the points keep the bare number. */\n formatValue?: (rank: number) => string;\n /**\n * `rank` (default) draws a disc ringed with the series color with the rank\n * written in it; `dot` draws a small filled dot.\n */\n points?: BumpChartPoints;\n };\n\nconst defaultFormat = (rank: number) => `#${rank}`;\n\n// Below this width the plot gets the room: only the right-hand names stay, cut shorter.\nconst COMPACT_BELOW = 560;\nconst NAME_CHARS = { wide: 12, compact: 8 };\n// Room taken by a name, beside its point: the gap to the point, the color dot, the gap to the text.\nconst NAME_GAP = 32;\n// The width of a character at the size of the names, rounded up: the text size setting is not known here.\nconst CHAR_WIDTH = 9;\n// The point's distance to the color dot of its name.\nconst DOT_OFFSET = 18;\n// The disc is 24px across with its ring: the ring is centered on the radius.\nconst RANK_STROKE = 2.5;\n// The least room between two periods for the discs to stay apart; below it the points are dots.\nconst MIN_DISC_STEP = 26;\nconst RANK_RADIUS = 12 - RANK_STROKE / 2;\nconst DOT_RADIUS = 4;\n\ntype Focus = number | null;\n\n/** The tooltip: the period, then the rank and its change of the focused series, or of all of them. */\nconst BumpTooltip = ({\n active,\n label,\n series,\n periods,\n ranks,\n colors,\n focus,\n format,\n}: {\n active?: boolean;\n label?: string | number;\n series: BumpSeries[];\n periods: string[];\n ranks: (number | undefined)[][];\n colors?: string[];\n focus: Focus;\n format: (rank: number) => string;\n}) => {\n const period = periods.indexOf(String(label));\n if (!active || period === -1) return null;\n const indexes = focus === null ? series.map((_, i) => i) : [focus];\n const rows = indexes\n .map((i) => ({ i, rank: ranks[i][period] }))\n .filter(({ i, rank }) => rank !== undefined || i === focus)\n .sort((a, b) => (a.rank ?? Infinity) - (b.rank ?? Infinity) || a.i - b.i)\n .map(({ i, rank }) => {\n const change = rank === undefined ? undefined : rankChange(ranks[i], periods, period);\n return {\n name: series[i].name,\n color: seriesColor(i, colors),\n value:\n rank === undefined ? (\n 'not ranked'\n ) : (\n <>\n {format(rank)}\n {change && (\n <span style={{ marginLeft: '0.5rem', fontWeight: 400, color: MUTED }}>\n {describeChange(change)}\n </span>\n )}\n </>\n ),\n };\n });\n return <TooltipCard title={periods[period]} rows={rows} />;\n};\n\nexport const BumpChart = ({\n series,\n colors,\n formatValue = defaultFormat,\n points = 'rank',\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: BumpChartProps) => {\n const [focus, setFocus] = useState<Focus>(null);\n const { ref, width: measured } = useElementWidth();\n const name = ariaLabel ?? `Bump chart: ${series.map((s) => s.name).join(', ')}`;\n const periods = useMemo(() => periodsOf(series), [series]);\n const ranks = useMemo(() => ranksOf(series, periods), [series, periods]);\n const plotted = useMemo(() => plottedRanks(ranks), [ranks]);\n const rows = useMemo(\n () =>\n periods.map((period, p) => ({\n category: period,\n ...Object.fromEntries(plotted.map((r, i) => [seriesKey(i), r[p]])),\n })),\n [periods, plotted]\n );\n if (hasNoData(series) || periods.length === 0) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n\n const compact = measured !== undefined && measured < COMPACT_BELOW;\n const chars = compact ? NAME_CHARS.compact : NAME_CHARS.wide;\n const room =\n Math.min(chars, Math.max(...series.map((s) => s.name.length))) * CHAR_WIDTH + NAME_GAP;\n const margin = {\n top: 8,\n right: room,\n bottom: 0,\n // The first disc hangs out of the plot by its radius.\n left: compact ? 12 + 4 : room,\n };\n const step =\n measured === undefined\n ? Infinity\n : (measured - margin.left - margin.right) / Math.max(1, periods.length - 1);\n const asRank = points === 'rank' && step >= MIN_DISC_STEP;\n const flat = plotted.flat().filter((v): v is number => v !== undefined);\n const spare = TIE_SPREAD + 0.05;\n const domain: [number, number] = [Math.min(...flat) - spare, Math.max(...flat) + spare];\n const spans = ranks.map(rankSpan);\n\n // Up and Down walk the series, Escape lets go; Left and Right (Recharts) walk the periods.\n const onKeyDown = (event: KeyboardEvent) => {\n const step = { ArrowDown: 1, ArrowUp: -1 }[event.key];\n if (step !== undefined) {\n event.preventDefault();\n setFocus((current) =>\n current === null\n ? step === 1\n ? 0\n : series.length - 1\n : (current + step + series.length) % series.length\n );\n } else if (event.key === 'Escape' && focus !== null) {\n event.preventDefault();\n setFocus(null);\n }\n };\n const onBlur = (event: FocusEvent) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setFocus(null);\n };\n const pointer = (i: number) => ({\n onMouseEnter: () => setFocus(i),\n onMouseLeave: () => setFocus(null),\n });\n\n const renderDot = (i: number) => {\n const color = seriesColor(i, colors);\n const Dot = ({ cx, cy, index }: DotItemDotProps): ReactNode => {\n const rank = ranks[i][index];\n if (rank === undefined || cx === undefined || cy === undefined) return null;\n return (\n <g\n key={index}\n data-bump-point=\"\"\n opacity={focus !== null && focus !== i ? 0.3 : 1}\n {...pointer(i)}\n style={{ transition: 'opacity 150ms' }}\n >\n {asRank ? (\n <>\n <circle\n cx={cx}\n cy={cy}\n r={RANK_RADIUS}\n fill={PANEL}\n stroke={color}\n strokeWidth={2.5}\n />\n <text\n x={cx}\n y={cy}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill={TEXT}\n style={{ fontSize: 'var(--text-2xs, 0.6875rem)', fontWeight: 700 }}\n >\n {rank}\n </text>\n </>\n ) : (\n <circle cx={cx} cy={cy} r={DOT_RADIUS} fill={color} stroke={PANEL} strokeWidth={2} />\n )}\n </g>\n );\n };\n return Dot;\n };\n\n // A name sits beside the first and last point of its line, with the color dot toward the line.\n const renderName = (i: number) => {\n const color = seriesColor(i, colors);\n const span = spans[i];\n const text = shortName(series[i].name, chars);\n const Name = ({\n x,\n y,\n index,\n }: {\n x?: number | string;\n y?: number | string;\n index?: number;\n }) => {\n if (!span || typeof x !== 'number' || typeof y !== 'number') return null;\n const end = index === span.last;\n const start = index === span.first && !compact && span.first !== span.last;\n if (!end && !start) return null;\n const side = end ? 1 : -1;\n return (\n <g\n key={`${index}`}\n data-bump-name=\"\"\n opacity={focus !== null && focus !== i ? 0.3 : 1}\n {...pointer(i)}\n style={{ transition: 'opacity 150ms' }}\n >\n <circle cx={x + side * DOT_OFFSET} cy={y} r={4} fill={color} />\n <text\n x={x + side * (DOT_OFFSET + 10)}\n y={y}\n textAnchor={end ? 'start' : 'end'}\n dominantBaseline=\"central\"\n fill={TEXT}\n stroke={PANEL}\n strokeWidth={3}\n strokeLinejoin=\"round\"\n paintOrder=\"stroke\"\n style={{ fontSize: 'var(--text-sm, 0.875rem)', fontWeight: 600 }}\n >\n {text}\n </text>\n </g>\n );\n };\n return Name;\n };\n\n return (\n <div\n ref={ref}\n onKeyDown={onKeyDown}\n onBlur={onBlur}\n style={{ width: width ?? '100%', maxWidth: '100%' }}\n >\n <LineChart\n {...frameProps({ height, width: '100%', ariaLabel: name })}\n data={rows}\n margin={margin}\n >\n <XAxis dataKey=\"category\" {...AXIS} {...categoryAxis(periods)} />\n <YAxis hide type=\"number\" reversed domain={domain} />\n <Tooltip\n content={\n <BumpTooltip\n series={series}\n periods={periods}\n ranks={ranks}\n colors={colors}\n focus={focus}\n format={formatValue}\n />\n }\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={150}\n />\n {series.map((s, i) => (\n <Line\n key={seriesKey(i)}\n name={s.name}\n dataKey={seriesKey(i)}\n type=\"bumpX\"\n stroke={seriesColor(i, colors)}\n strokeWidth={focus === i ? 4 : 3}\n strokeOpacity={focus !== null && focus !== i ? 0.2 : 1}\n strokeLinecap=\"round\"\n connectNulls={false}\n dot={renderDot(i)}\n activeDot={false}\n label={renderName(i)}\n {...pointer(i)}\n {...ANIMATION}\n />\n ))}\n {children}\n </LineChart>\n </div>\n );\n};\n"]}
@@ -0,0 +1,216 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkTPH5T3DA_cjs = require('./chunk-TPH5T3DA.cjs');
5
+ require('./chunk-DBZQI4HM.cjs');
6
+ var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
7
+ require('./chunk-T3K6Q34U.cjs');
8
+ var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
9
+ var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
10
+ var jsxRuntime = require('react/jsx-runtime');
11
+
12
+ // src/calendarGrid.ts
13
+ var DAY_MS = 864e5;
14
+ var mod = (n, by) => (n % by + by) % by;
15
+ var parseDay = (iso) => {
16
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
17
+ if (!match) return void 0;
18
+ const [year, month, date] = [Number(match[1]), Number(match[2]), Number(match[3])];
19
+ const time = Date.UTC(year, month - 1, date);
20
+ const check = new Date(time);
21
+ return check.getUTCFullYear() === year && check.getUTCMonth() === month - 1 && check.getUTCDate() === date ? time / DAY_MS : void 0;
22
+ };
23
+ var dayOf = (year, month, date) => Date.UTC(year, month, date) / DAY_MS;
24
+ var weekdayOf = (day) => mod(day + 4, 7);
25
+ var partsOf = (day) => {
26
+ const date = new Date(day * DAY_MS);
27
+ return { year: date.getUTCFullYear(), month: date.getUTCMonth(), date: date.getUTCDate() };
28
+ };
29
+ var rowOf = (day, weekStart) => mod(weekdayOf(day) - weekStart, 7);
30
+ var weekGrid = (from, to, weekStart) => {
31
+ if (to < from) return { start: from, weeks: 0, days: [] };
32
+ const start = from - rowOf(from, weekStart);
33
+ const days = Array.from({ length: to - from + 1 }, (_, i) => {
34
+ const day = from + i;
35
+ return { day, row: rowOf(day, weekStart), column: Math.floor((day - start) / 7) };
36
+ });
37
+ return { start, weeks: Math.floor((to - start) / 7) + 1, days };
38
+ };
39
+ var yearSpans = (from, to) => {
40
+ const spans = [];
41
+ if (to < from) return spans;
42
+ for (let year = partsOf(from).year; year <= partsOf(to).year; year++) {
43
+ spans.push({
44
+ year,
45
+ from: Math.max(from, dayOf(year, 0, 1)),
46
+ to: Math.min(to, dayOf(year, 11, 31))
47
+ });
48
+ }
49
+ return spans;
50
+ };
51
+ var MIN_MARK_GAP = 3;
52
+ var monthMarks = (grid) => {
53
+ if (grid.weeks === 0) return [];
54
+ const marks = [];
55
+ for (let column = 0; column < grid.weeks; column++) {
56
+ const { month, date } = partsOf(grid.start + column * 7);
57
+ if (date <= 7) marks.push({ column, month });
58
+ }
59
+ const first = grid.days[0];
60
+ const leading = partsOf(first.day).month;
61
+ const next = marks[0];
62
+ if (!next || next.month !== leading && next.column >= MIN_MARK_GAP) {
63
+ marks.unshift({ column: 0, month: leading });
64
+ }
65
+ return marks;
66
+ };
67
+ var stepOf = (value, max, steps = 4) => !(value > 0) || !(max > 0) ? 0 : Math.min(steps, Math.max(1, Math.ceil(value / max * steps)));
68
+ var cellMetrics = (weeks) => weeks <= 26 ? { size: 18, gap: 4, radius: 4 } : { size: 12, gap: 3, radius: 3 };
69
+ var collectDays = (data) => {
70
+ const values = /* @__PURE__ */ new Map();
71
+ for (const { day, value } of data) {
72
+ const n = parseDay(day);
73
+ if (n === void 0 || !Number.isFinite(value)) continue;
74
+ values.set(n, (values.get(n) ?? 0) + value);
75
+ }
76
+ if (values.size === 0) return void 0;
77
+ const days = [...values.keys()];
78
+ return { values, first: Math.min(...days), last: Math.max(...days) };
79
+ };
80
+ var EMPTY_HEIGHT = 120;
81
+ var NAMED_WEEKDAYS = [1, 3, 5];
82
+ var CalendarChart = ({
83
+ data,
84
+ from,
85
+ to,
86
+ layout = "calendar",
87
+ weekStart = 1,
88
+ formatValue = String,
89
+ locale = "en-US",
90
+ lessLabel = "Less",
91
+ moreLabel = "More",
92
+ emptyMessage = "No data",
93
+ ariaLabel,
94
+ width
95
+ }) => {
96
+ const name = ariaLabel ?? "Calendar chart";
97
+ const days = collectDays(data);
98
+ if (!days) {
99
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height: EMPTY_HEIGHT, width });
100
+ }
101
+ const given = {
102
+ from: from === void 0 ? void 0 : parseDay(from),
103
+ to: to === void 0 ? void 0 : parseDay(to)
104
+ };
105
+ const calendar = layout === "calendar";
106
+ const start = given.from ?? (calendar ? dayOf(partsOf(days.first).year, 0, 1) : days.first);
107
+ const end = given.to ?? (calendar ? dayOf(partsOf(days.last).year, 11, 31) : days.last);
108
+ const blocks = calendar ? yearSpans(start, end) : end >= start ? [{ year: void 0, from: start, to: end }] : [];
109
+ if (blocks.length === 0) {
110
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height: EMPTY_HEIGHT, width });
111
+ }
112
+ const month = new Intl.DateTimeFormat(locale, { month: "short", timeZone: "UTC" });
113
+ const date = new Intl.DateTimeFormat(locale, { dateStyle: "full", timeZone: "UTC" });
114
+ const weekday = new Intl.DateTimeFormat(locale, { weekday: "short", timeZone: "UTC" });
115
+ const monthName = (m) => month.format(Date.UTC(2024, m, 1));
116
+ const weekdayName = (d) => weekday.format(Date.UTC(2024, 0, 7 + d));
117
+ const rows = Array.from({ length: 7 }, (_, row) => {
118
+ const d = (row + weekStart) % 7;
119
+ return NAMED_WEEKDAYS.includes(d) ? weekdayName(d) : "";
120
+ });
121
+ const max = Math.max(0, ...days.values.values());
122
+ const color = (value) => chunkLT3UC65O_cjs.CALENDAR_STEPS[stepOf(value, max)];
123
+ const grids = blocks.map((block) => {
124
+ const grid = weekGrid(block.from, block.to, weekStart);
125
+ const metrics2 = cellMetrics(grid.weeks);
126
+ const columns = Array.from({ length: grid.weeks }, () => "");
127
+ for (const mark of monthMarks(grid)) columns[mark.column] = monthName(mark.month);
128
+ const cells = grid.days.map((d) => {
129
+ const value = days.values.get(d.day) ?? 0;
130
+ return {
131
+ row: d.row,
132
+ column: d.column,
133
+ color: color(value),
134
+ title: date.format(d.day * DAY_MS),
135
+ label: "",
136
+ value: formatValue(value)
137
+ };
138
+ });
139
+ const label = block.year !== void 0 && blocks.length > 1 ? `${name}, ${block.year}` : name;
140
+ return { block, grid, metrics: metrics2, columns, cells, label };
141
+ });
142
+ const metrics = grids[0].metrics;
143
+ return /* @__PURE__ */ jsxRuntime.jsxs(
144
+ "div",
145
+ {
146
+ className: chunkLT3UC65O_cjs.CALENDAR_DARK_CLASS,
147
+ style: {
148
+ display: "flex",
149
+ flexDirection: "column",
150
+ gap: "0.75rem",
151
+ // As wide as the grid, so the scale lines up with its right edge.
152
+ width: width ?? "fit-content",
153
+ maxWidth: "100%",
154
+ minWidth: 0,
155
+ fontSize: chunkRLHGPHC7_cjs.TEXT_SIZE,
156
+ color: chunkLT3UC65O_cjs.MUTED
157
+ },
158
+ children: [
159
+ grids.map(({ block, metrics: m, columns, cells, label }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-calendar-block": "", style: { minWidth: 0 }, children: [
160
+ blocks.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0 0 0.25rem", fontWeight: 600, color: chunkLT3UC65O_cjs.TEXT }, children: block.year }),
161
+ /* @__PURE__ */ jsxRuntime.jsx(
162
+ chunkTPH5T3DA_cjs.HeatGrid,
163
+ {
164
+ rows,
165
+ columns,
166
+ cells,
167
+ cellHeight: m.size,
168
+ columnWidth: m.size,
169
+ gap: m.gap,
170
+ cellRadius: m.radius,
171
+ labelsAbove: true,
172
+ thinLabels: false,
173
+ ariaLabel: label
174
+ }
175
+ )
176
+ ] }, block.year ?? "range")),
177
+ /* @__PURE__ */ jsxRuntime.jsxs(
178
+ "div",
179
+ {
180
+ "data-calendar-legend": "",
181
+ "aria-hidden": true,
182
+ style: {
183
+ display: "flex",
184
+ alignItems: "center",
185
+ justifyContent: "flex-end",
186
+ // The grid sits in a box padded by 3px, room for its focus rings.
187
+ paddingRight: 3,
188
+ gap: metrics.gap
189
+ },
190
+ children: [
191
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginRight: 4 }, children: lessLabel }),
192
+ chunkLT3UC65O_cjs.CALENDAR_STEPS.map((step, i) => /* @__PURE__ */ jsxRuntime.jsx(
193
+ "span",
194
+ {
195
+ "data-calendar-step": "",
196
+ style: {
197
+ width: metrics.size,
198
+ height: metrics.size,
199
+ borderRadius: metrics.radius,
200
+ background: step
201
+ }
202
+ },
203
+ i
204
+ )),
205
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: 4 }, children: moreLabel })
206
+ ]
207
+ }
208
+ )
209
+ ]
210
+ }
211
+ );
212
+ };
213
+
214
+ exports.CalendarChart = CalendarChart;
215
+ //# sourceMappingURL=CalendarChart.cjs.map
216
+ //# sourceMappingURL=CalendarChart.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/calendarGrid.ts","../src/CalendarChart.tsx"],"names":["jsx","ChartEmpty","CALENDAR_STEPS","metrics","jsxs","CALENDAR_DARK_CLASS","TEXT_SIZE","MUTED","TEXT","HeatGrid"],"mappings":"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","file":"CalendarChart.cjs","sourcesContent":["// The date maths of `CalendarChart`. A day is a whole number: the days since\n// 1970-01-01 in UTC, so nothing here reads the time zone of the machine or the\n// date of today.\n\nexport const DAY_MS = 86_400_000;\n\n/** The weekday a week starts on: 0 is Sunday, 1 is Monday. */\nexport type WeekStart = 0 | 1;\n\nconst mod = (n: number, by: number) => ((n % by) + by) % by;\n\n/** The day number of an ISO date (`2026-03-14`), or `undefined` when it is not a real date. */\nexport const parseDay = (iso: string): number | undefined => {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(iso);\n if (!match) return undefined;\n const [year, month, date] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const time = Date.UTC(year, month - 1, date);\n const check = new Date(time);\n // `Date.UTC` rolls 02-30 over to 03-02: a date that moved is not a date.\n return check.getUTCFullYear() === year &&\n check.getUTCMonth() === month - 1 &&\n check.getUTCDate() === date\n ? time / DAY_MS\n : undefined;\n};\n\n/** The day number of a date: `month` is 0 to 11. */\nexport const dayOf = (year: number, month: number, date: number): number =>\n Date.UTC(year, month, date) / DAY_MS;\n\n/** The ISO date of a day number. */\nexport const formatDay = (day: number): string => new Date(day * DAY_MS).toISOString().slice(0, 10);\n\n/** The weekday of a day number, 0 (Sunday) to 6. 1970-01-01 was a Thursday. */\nexport const weekdayOf = (day: number): number => mod(day + 4, 7);\n\n/** The year, month (0 to 11) and day of the month of a day number. */\nexport const partsOf = (day: number) => {\n const date = new Date(day * DAY_MS);\n return { year: date.getUTCFullYear(), month: date.getUTCMonth(), date: date.getUTCDate() };\n};\n\n/** The row of a day in a week that starts on `weekStart`: 0 for the first day of the week. */\nexport const rowOf = (day: number, weekStart: WeekStart): number =>\n mod(weekdayOf(day) - weekStart, 7);\n\nexport type GridDay = { day: number; row: number; column: number };\n\nexport type WeekGrid = {\n /** The first day of the first column: on or before `from`. */\n start: number;\n /** The number of columns. 0 when the range is empty. */\n weeks: number;\n /** Every day of the range, in order. The slots before `from` and after `to` have no day. */\n days: GridDay[];\n};\n\n/** The days from `from` to `to` (inclusive) laid out as weeks in columns and weekdays in rows. */\nexport const weekGrid = (from: number, to: number, weekStart: WeekStart): WeekGrid => {\n if (to < from) return { start: from, weeks: 0, days: [] };\n const start = from - rowOf(from, weekStart);\n const days = Array.from({ length: to - from + 1 }, (_, i): GridDay => {\n const day = from + i;\n return { day, row: rowOf(day, weekStart), column: Math.floor((day - start) / 7) };\n });\n return { start, weeks: Math.floor((to - start) / 7) + 1, days };\n};\n\nexport type YearSpan = { year: number; from: number; to: number };\n\n/** `from` to `to` cut at the turn of each year: one block of the `calendar` layout per span. */\nexport const yearSpans = (from: number, to: number): YearSpan[] => {\n const spans: YearSpan[] = [];\n if (to < from) return spans;\n for (let year = partsOf(from).year; year <= partsOf(to).year; year++) {\n spans.push({\n year,\n from: Math.max(from, dayOf(year, 0, 1)),\n to: Math.min(to, dayOf(year, 11, 31)),\n });\n }\n return spans;\n};\n\nexport type MonthMark = { column: number; month: number };\n\n// Room a month name needs, in columns: two months closer than this would\n// print over each other.\nconst MIN_MARK_GAP = 3;\n\n/**\n * Where the month names go: above the first full week of each month, that is\n * the first column whose first day falls in the first seven days of the\n * month. A range that starts in the middle of a month also names that month\n * above its first column, unless the next name is too close to leave room.\n */\nexport const monthMarks = (grid: WeekGrid): MonthMark[] => {\n if (grid.weeks === 0) return [];\n const marks: MonthMark[] = [];\n for (let column = 0; column < grid.weeks; column++) {\n const { month, date } = partsOf(grid.start + column * 7);\n if (date <= 7) marks.push({ column, month });\n }\n const first = grid.days[0];\n const leading = partsOf(first.day).month;\n const next = marks[0];\n if (!next || (next.month !== leading && next.column >= MIN_MARK_GAP)) {\n marks.unshift({ column: 0, month: leading });\n }\n return marks;\n};\n\n/** The 0-based step a value takes on the scale: 0 is empty, 1 to `steps` split `(0, max]` evenly. */\nexport const stepOf = (value: number, max: number, steps = 4): number =>\n !(value > 0) || !(max > 0) ? 0 : Math.min(steps, Math.max(1, Math.ceil((value / max) * steps)));\n\n/** How big the cells are: a short range gets larger ones, a long one fits more weeks on screen. */\nexport const cellMetrics = (weeks: number) =>\n weeks <= 26 ? { size: 18, gap: 4, radius: 4 } : { size: 12, gap: 3, radius: 3 };\n\nexport type DayValues = {\n /** The summed value of each valid day. */\n values: Map<number, number>;\n first: number;\n last: number;\n};\n\n/** The valid days of `data` by day number, a day listed twice summed. `undefined` when none is valid. */\nexport const collectDays = (\n data: readonly { day: string; value: number }[]\n): DayValues | undefined => {\n const values = new Map<number, number>();\n for (const { day, value } of data) {\n const n = parseDay(day);\n if (n === undefined || !Number.isFinite(value)) continue;\n values.set(n, (values.get(n) ?? 0) + value);\n }\n if (values.size === 0) return undefined;\n const days = [...values.keys()];\n return { values, first: Math.min(...days), last: Math.max(...days) };\n};\n","import { TEXT_SIZE } from './core/axes';\nimport { CALENDAR_DARK_CLASS, CALENDAR_STEPS, MUTED, TEXT } from './core/colors';\nimport { ChartEmpty } from './core/frame';\nimport { HeatGrid, type HeatCell } from './core/HeatGrid';\nimport {\n cellMetrics,\n collectDays,\n DAY_MS,\n dayOf,\n monthMarks,\n parseDay,\n partsOf,\n stepOf,\n weekGrid,\n yearSpans,\n type WeekStart,\n} from './calendarGrid';\nimport type { ChartEmptyProps, ChartProps } from './types';\n\nexport type CalendarDay = {\n /** The date, `YYYY-MM-DD`. A day listed twice adds up; anything else is ignored. */\n day: string;\n value: number;\n};\n\nexport type CalendarChartProps = Omit<ChartProps, 'children' | 'height'> &\n ChartEmptyProps & {\n data: CalendarDay[];\n /**\n * First day shown, `YYYY-MM-DD`. Default: the first day of the earliest\n * year of `data` in the `calendar` layout, the earliest day in `range`.\n */\n from?: string;\n /** Last day shown, `YYYY-MM-DD`. Default: the end of the latest year, or the latest day in `range`. */\n to?: string;\n /**\n * `calendar` draws one block per year, with the months named above their\n * first full week. `range` draws one continuous grid from `from` to `to`,\n * with larger cells when the range is short. Default `calendar`.\n */\n layout?: 'calendar' | 'range';\n /** The weekday a week starts on: 1 for Monday (default), 0 for Sunday. */\n weekStart?: WeekStart;\n /** Format the value in the tooltip and in the name of each day. */\n formatValue?: (value: number) => string;\n /** Text at the low end of the scale under the grid. Default `Less`. */\n lessLabel?: string;\n /** Text at the high end of the scale under the grid. Default `More`. */\n moreLabel?: string;\n /** The language of the month, weekday and date names (BCP 47). Default `en-US`. */\n locale?: string;\n };\n\n// Height of the empty state, which has no grid to take one from.\nconst EMPTY_HEIGHT = 120;\n\n// Tuesday, Thursday and the weekend carry no name: a name every second row\n// leaves each one room.\nconst NAMED_WEEKDAYS = [1, 3, 5];\n\ntype Block = { year: number | undefined; from: number; to: number };\n\nexport const CalendarChart = ({\n data,\n from,\n to,\n layout = 'calendar',\n weekStart = 1,\n formatValue = String,\n locale = 'en-US',\n lessLabel = 'Less',\n moreLabel = 'More',\n emptyMessage = 'No data',\n ariaLabel,\n width,\n}: CalendarChartProps) => {\n const name = ariaLabel ?? 'Calendar chart';\n const days = collectDays(data);\n if (!days) {\n return (\n <ChartEmpty message={emptyMessage} ariaLabel={name} height={EMPTY_HEIGHT} width={width} />\n );\n }\n const given = {\n from: from === undefined ? undefined : parseDay(from),\n to: to === undefined ? undefined : parseDay(to),\n };\n const calendar = layout === 'calendar';\n const start = given.from ?? (calendar ? dayOf(partsOf(days.first).year, 0, 1) : days.first);\n const end = given.to ?? (calendar ? dayOf(partsOf(days.last).year, 11, 31) : days.last);\n const blocks: Block[] = calendar\n ? yearSpans(start, end)\n : end >= start\n ? [{ year: undefined, from: start, to: end }]\n : [];\n if (blocks.length === 0) {\n return (\n <ChartEmpty message={emptyMessage} ariaLabel={name} height={EMPTY_HEIGHT} width={width} />\n );\n }\n\n const month = new Intl.DateTimeFormat(locale, { month: 'short', timeZone: 'UTC' });\n const date = new Intl.DateTimeFormat(locale, { dateStyle: 'full', timeZone: 'UTC' });\n const weekday = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' });\n const monthName = (m: number) => month.format(Date.UTC(2024, m, 1));\n // 2024-01-07 was a Sunday.\n const weekdayName = (d: number) => weekday.format(Date.UTC(2024, 0, 7 + d));\n const rows = Array.from({ length: 7 }, (_, row) => {\n const d = (row + weekStart) % 7;\n return NAMED_WEEKDAYS.includes(d) ? weekdayName(d) : '';\n });\n\n // One scale for every block, so two years compare.\n const max = Math.max(0, ...days.values.values());\n const color = (value: number) => CALENDAR_STEPS[stepOf(value, max)];\n\n const grids = blocks.map((block) => {\n const grid = weekGrid(block.from, block.to, weekStart);\n const metrics = cellMetrics(grid.weeks);\n const columns = Array.from({ length: grid.weeks }, () => '');\n for (const mark of monthMarks(grid)) columns[mark.column] = monthName(mark.month);\n const cells = grid.days.map((d): HeatCell => {\n const value = days.values.get(d.day) ?? 0;\n return {\n row: d.row,\n column: d.column,\n color: color(value),\n title: date.format(d.day * DAY_MS),\n label: '',\n value: formatValue(value),\n };\n });\n const label = block.year !== undefined && blocks.length > 1 ? `${name}, ${block.year}` : name;\n return { block, grid, metrics, columns, cells, label };\n });\n\n const metrics = grids[0].metrics;\n return (\n <div\n className={CALENDAR_DARK_CLASS}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.75rem',\n // As wide as the grid, so the scale lines up with its right edge.\n width: width ?? 'fit-content',\n maxWidth: '100%',\n minWidth: 0,\n fontSize: TEXT_SIZE,\n color: MUTED,\n }}\n >\n {grids.map(({ block, metrics: m, columns, cells, label }) => (\n <div key={block.year ?? 'range'} data-calendar-block=\"\" style={{ minWidth: 0 }}>\n {blocks.length > 1 && (\n <p style={{ margin: '0 0 0.25rem', fontWeight: 600, color: TEXT }}>{block.year}</p>\n )}\n <HeatGrid\n rows={rows}\n columns={columns}\n cells={cells}\n cellHeight={m.size}\n columnWidth={m.size}\n gap={m.gap}\n cellRadius={m.radius}\n labelsAbove\n thinLabels={false}\n ariaLabel={label}\n />\n </div>\n ))}\n <div\n data-calendar-legend=\"\"\n aria-hidden\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n // The grid sits in a box padded by 3px, room for its focus rings.\n paddingRight: 3,\n gap: metrics.gap,\n }}\n >\n <span style={{ marginRight: 4 }}>{lessLabel}</span>\n {CALENDAR_STEPS.map((step, i) => (\n <span\n key={i}\n data-calendar-step=\"\"\n style={{\n width: metrics.size,\n height: metrics.size,\n borderRadius: metrics.radius,\n background: step,\n }}\n />\n ))}\n <span style={{ marginLeft: 4 }}>{moreLabel}</span>\n </div>\n </div>\n );\n};\n"]}