@sckyzo/cosmos-charts 0.2.0 → 0.3.1

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 +98 -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 +218 -0
  17. package/dist/CalendarChart.cjs.map +1 -0
  18. package/dist/CalendarChart.js +216 -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 +424 -0
  25. package/dist/FunnelChart.cjs.map +1 -0
  26. package/dist/FunnelChart.js +422 -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 +148 -0
  33. package/dist/HeatmapChart.cjs.map +1 -0
  34. package/dist/HeatmapChart.js +146 -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-4AKHZNWP.js +127 -0
  89. package/dist/chunk-4AKHZNWP.js.map +1 -0
  90. package/dist/chunk-56WD3OHA.js +62 -0
  91. package/dist/chunk-56WD3OHA.js.map +1 -0
  92. package/dist/chunk-5C2RLJYZ.js +11 -0
  93. package/dist/chunk-5C2RLJYZ.js.map +1 -0
  94. package/dist/chunk-6FGJZBTC.js +61 -0
  95. package/dist/chunk-6FGJZBTC.js.map +1 -0
  96. package/dist/chunk-AAYHG7YK.cjs +30 -0
  97. package/dist/chunk-AAYHG7YK.cjs.map +1 -0
  98. package/dist/chunk-AOSO5QHL.js +19 -0
  99. package/dist/chunk-AOSO5QHL.js.map +1 -0
  100. package/dist/chunk-BFEDLXVW.js +12 -0
  101. package/dist/chunk-BFEDLXVW.js.map +1 -0
  102. package/dist/chunk-CMBNNLIV.cjs +63 -0
  103. package/dist/chunk-CMBNNLIV.cjs.map +1 -0
  104. package/dist/chunk-DBZQI4HM.cjs +14 -0
  105. package/dist/chunk-DBZQI4HM.cjs.map +1 -0
  106. package/dist/chunk-DI2FBGKM.js +44 -0
  107. package/dist/chunk-DI2FBGKM.js.map +1 -0
  108. package/dist/chunk-ESVGCUJN.js +58 -0
  109. package/dist/chunk-ESVGCUJN.js.map +1 -0
  110. package/dist/chunk-F2PMFYJ5.cjs +40 -0
  111. package/dist/chunk-F2PMFYJ5.cjs.map +1 -0
  112. package/dist/chunk-FUZW3H5X.js +38 -0
  113. package/dist/chunk-FUZW3H5X.js.map +1 -0
  114. package/dist/chunk-G4WOPX4D.cjs +51 -0
  115. package/dist/chunk-G4WOPX4D.cjs.map +1 -0
  116. package/dist/chunk-GDZLYYL2.js +27 -0
  117. package/dist/chunk-GDZLYYL2.js.map +1 -0
  118. package/dist/chunk-GVTMZYOM.cjs +30 -0
  119. package/dist/chunk-GVTMZYOM.cjs.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-OCD6JIIX.js +23 -0
  127. package/dist/chunk-OCD6JIIX.js.map +1 -0
  128. package/dist/chunk-RCDTBZC2.cjs +131 -0
  129. package/dist/chunk-RCDTBZC2.cjs.map +1 -0
  130. package/dist/chunk-SR2ESX3R.cjs +66 -0
  131. package/dist/chunk-SR2ESX3R.cjs.map +1 -0
  132. package/dist/chunk-T3K6Q34U.cjs +82 -0
  133. package/dist/chunk-T3K6Q34U.cjs.map +1 -0
  134. package/dist/chunk-TYQWZR3S.cjs +13 -0
  135. package/dist/chunk-TYQWZR3S.cjs.map +1 -0
  136. package/dist/chunk-UATB2IRY.js +51 -0
  137. package/dist/chunk-UATB2IRY.js.map +1 -0
  138. package/dist/chunk-UJIV5PVI.js +13 -0
  139. package/dist/chunk-UJIV5PVI.js.map +1 -0
  140. package/dist/chunk-UL3SNXQR.js +280 -0
  141. package/dist/chunk-UL3SNXQR.js.map +1 -0
  142. package/dist/chunk-URNXLVSK.js +44 -0
  143. package/dist/chunk-URNXLVSK.js.map +1 -0
  144. package/dist/chunk-VIOSQN4Z.js +79 -0
  145. package/dist/chunk-VIOSQN4Z.js.map +1 -0
  146. package/dist/chunk-X3YZP5WF.cjs +46 -0
  147. package/dist/chunk-X3YZP5WF.cjs.map +1 -0
  148. package/dist/chunk-XMFBVMW7.cjs +30 -0
  149. package/dist/chunk-XMFBVMW7.cjs.map +1 -0
  150. package/dist/chunk-XUGQ6VXO.cjs +60 -0
  151. package/dist/chunk-XUGQ6VXO.cjs.map +1 -0
  152. package/dist/chunk-YMRNTIOK.js +27 -0
  153. package/dist/chunk-YMRNTIOK.js.map +1 -0
  154. package/dist/chunk-ZWHCUYIN.cjs +282 -0
  155. package/dist/chunk-ZWHCUYIN.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,328 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
5
+ var chunkIW6EWB26_cjs = require('./chunk-IW6EWB26.cjs');
6
+ var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
7
+ var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
8
+ var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
9
+ var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
10
+ var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
11
+ var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
12
+ var react = require('react');
13
+ var recharts = require('recharts');
14
+ var jsxRuntime = require('react/jsx-runtime');
15
+
16
+ // src/core/bump.ts
17
+ var periodsOf = (series) => {
18
+ const seen = /* @__PURE__ */ new Set();
19
+ for (const s of series) for (const point of s.data) seen.add(point.x);
20
+ return [...seen];
21
+ };
22
+ var ranksOf = (series, periods) => {
23
+ const index = new Map(periods.map((period, i) => [period, i]));
24
+ return series.map((s) => {
25
+ const ranks = periods.map(() => void 0);
26
+ for (const point of s.data) {
27
+ const at = index.get(point.x);
28
+ if (at !== void 0 && Number.isFinite(point.rank)) ranks[at] = point.rank;
29
+ }
30
+ return ranks;
31
+ });
32
+ };
33
+ var TIE_SPREAD = 0.5;
34
+ var plottedRanks = (ranks) => {
35
+ const plotted = ranks.map((r) => [...r]);
36
+ const periods = Math.max(0, ...ranks.map((r) => r.length));
37
+ for (let p = 0; p < periods; p++) {
38
+ const groups = /* @__PURE__ */ new Map();
39
+ ranks.forEach((r, s) => {
40
+ const rank = r[p];
41
+ if (rank !== void 0) groups.set(rank, [...groups.get(rank) ?? [], s]);
42
+ });
43
+ for (const [rank, members] of groups) {
44
+ members.forEach((s, k) => {
45
+ plotted[s][p] = rank + (k - (members.length - 1) / 2) * TIE_SPREAD;
46
+ });
47
+ }
48
+ }
49
+ return plotted;
50
+ };
51
+ var rankChange = (ranks, periods, index) => {
52
+ const rank = ranks[index];
53
+ if (index === 0 || rank === void 0) return void 0;
54
+ const before = ranks[index - 1];
55
+ if (before === void 0) return { direction: "new" };
56
+ const versus = periods[index - 1];
57
+ if (rank === before) return { direction: "same", versus };
58
+ return rank < before ? { direction: "up", by: before - rank, versus } : { direction: "down", by: rank - before, versus };
59
+ };
60
+ var describeChange = (change) => {
61
+ switch (change.direction) {
62
+ case "same":
63
+ return `unchanged vs ${change.versus}`;
64
+ case "new":
65
+ return "new entry";
66
+ default:
67
+ return `${change.direction} ${change.by} vs ${change.versus}`;
68
+ }
69
+ };
70
+ var rankSpan = (ranks) => {
71
+ const first = ranks.findIndex((r) => r !== void 0);
72
+ if (first === -1) return void 0;
73
+ let last = ranks.length - 1;
74
+ while (ranks[last] === void 0) last--;
75
+ return { first, last };
76
+ };
77
+ var shortName = (name, max) => name.length > max ? `${name.slice(0, Math.max(1, max - 1))}\u2026` : name;
78
+ var defaultFormat = (rank) => `#${rank}`;
79
+ var COMPACT_BELOW = 560;
80
+ var NAME_CHARS = { wide: 12, compact: 8 };
81
+ var NAME_GAP = 32;
82
+ var CHAR_WIDTH = 9;
83
+ var DOT_OFFSET = 18;
84
+ var RANK_STROKE = 2.5;
85
+ var MIN_DISC_STEP = 26;
86
+ var RANK_RADIUS = 12 - RANK_STROKE / 2;
87
+ var DOT_RADIUS = 4;
88
+ var BumpTooltip = ({
89
+ active,
90
+ label,
91
+ series,
92
+ periods,
93
+ ranks,
94
+ colors,
95
+ focus,
96
+ format
97
+ }) => {
98
+ const period = periods.indexOf(String(label));
99
+ if (!active || period === -1) return null;
100
+ const indexes = focus === null ? series.map((_, i) => i) : [focus];
101
+ 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 }) => {
102
+ const change = rank === void 0 ? void 0 : rankChange(ranks[i], periods, period);
103
+ return {
104
+ name: series[i].name,
105
+ color: chunkLT3UC65O_cjs.seriesColor(i, colors),
106
+ value: rank === void 0 ? "not ranked" : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
107
+ format(rank),
108
+ change && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: "0.5rem", fontWeight: 400, color: chunkLT3UC65O_cjs.MUTED }, children: describeChange(change) })
109
+ ] })
110
+ };
111
+ });
112
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkT3K6Q34U_cjs.TooltipCard, { title: periods[period], rows });
113
+ };
114
+ var BumpChart = ({
115
+ series,
116
+ colors,
117
+ formatValue = defaultFormat,
118
+ points = "rank",
119
+ emptyMessage = "No data",
120
+ ariaLabel,
121
+ children,
122
+ height = 320,
123
+ width
124
+ }) => {
125
+ const [focus, setFocus] = react.useState(null);
126
+ const { ref, width: measured } = chunkIW6EWB26_cjs.useElementWidth();
127
+ const name = ariaLabel ?? `Bump chart: ${series.map((s) => s.name).join(", ")}`;
128
+ const periods = react.useMemo(() => periodsOf(series), [series]);
129
+ const ranks = react.useMemo(() => ranksOf(series, periods), [series, periods]);
130
+ const plotted = react.useMemo(() => plottedRanks(ranks), [ranks]);
131
+ const rows = react.useMemo(
132
+ () => periods.map((period, p) => ({
133
+ category: period,
134
+ ...Object.fromEntries(plotted.map((r, i) => [chunkK3R7JGOW_cjs.seriesKey(i), r[p]]))
135
+ })),
136
+ [periods, plotted]
137
+ );
138
+ if (chunkK3R7JGOW_cjs.hasNoData(series) || periods.length === 0) {
139
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
140
+ }
141
+ const compact = measured !== void 0 && measured < COMPACT_BELOW;
142
+ const chars = compact ? NAME_CHARS.compact : NAME_CHARS.wide;
143
+ const room = Math.min(chars, Math.max(...series.map((s) => s.name.length))) * CHAR_WIDTH + NAME_GAP;
144
+ const margin = {
145
+ top: 8,
146
+ right: room,
147
+ bottom: 0,
148
+ // The first disc hangs out of the plot by its radius.
149
+ left: compact ? 12 + 4 : room
150
+ };
151
+ const step = measured === void 0 ? Infinity : (measured - margin.left - margin.right) / Math.max(1, periods.length - 1);
152
+ const asRank = points === "rank" && step >= MIN_DISC_STEP;
153
+ const flat = plotted.flat().filter((v) => v !== void 0);
154
+ const spare = TIE_SPREAD + 0.05;
155
+ const domain = [Math.min(...flat) - spare, Math.max(...flat) + spare];
156
+ const spans = ranks.map(rankSpan);
157
+ const onKeyDown = (event) => {
158
+ const step2 = { ArrowDown: 1, ArrowUp: -1 }[event.key];
159
+ if (step2 !== void 0) {
160
+ event.preventDefault();
161
+ setFocus(
162
+ (current) => current === null ? step2 === 1 ? 0 : series.length - 1 : (current + step2 + series.length) % series.length
163
+ );
164
+ } else if (event.key === "Escape" && focus !== null) {
165
+ event.preventDefault();
166
+ setFocus(null);
167
+ }
168
+ };
169
+ const onBlur = (event) => {
170
+ if (!event.currentTarget.contains(event.relatedTarget)) setFocus(null);
171
+ };
172
+ const pointer = (i) => ({
173
+ onMouseEnter: () => setFocus(i),
174
+ onMouseLeave: () => setFocus(null)
175
+ });
176
+ const renderDot = (i) => {
177
+ const color = chunkLT3UC65O_cjs.seriesColor(i, colors);
178
+ const Dot = ({ cx, cy, index }) => {
179
+ const rank = ranks[i][index];
180
+ if (rank === void 0 || cx === void 0 || cy === void 0) return null;
181
+ return /* @__PURE__ */ jsxRuntime.jsx(
182
+ "g",
183
+ {
184
+ "data-bump-point": "",
185
+ opacity: focus !== null && focus !== i ? 0.3 : 1,
186
+ ...pointer(i),
187
+ style: { transition: "opacity 150ms" },
188
+ children: asRank ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
189
+ /* @__PURE__ */ jsxRuntime.jsx(
190
+ "circle",
191
+ {
192
+ cx,
193
+ cy,
194
+ r: RANK_RADIUS,
195
+ fill: chunkLT3UC65O_cjs.PANEL,
196
+ stroke: color,
197
+ strokeWidth: 2.5
198
+ }
199
+ ),
200
+ /* @__PURE__ */ jsxRuntime.jsx(
201
+ "text",
202
+ {
203
+ x: cx,
204
+ y: cy,
205
+ textAnchor: "middle",
206
+ dominantBaseline: "central",
207
+ fill: chunkLT3UC65O_cjs.TEXT,
208
+ style: { fontSize: "var(--text-2xs, 0.6875rem)", fontWeight: 700 },
209
+ children: rank
210
+ }
211
+ )
212
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: DOT_RADIUS, fill: color, stroke: chunkLT3UC65O_cjs.PANEL, strokeWidth: 2 })
213
+ },
214
+ index
215
+ );
216
+ };
217
+ return Dot;
218
+ };
219
+ const renderName = (i) => {
220
+ const color = chunkLT3UC65O_cjs.seriesColor(i, colors);
221
+ const span = spans[i];
222
+ const text = shortName(series[i].name, chars);
223
+ const Name = ({
224
+ x,
225
+ y,
226
+ index
227
+ }) => {
228
+ if (!span || typeof x !== "number" || typeof y !== "number") return null;
229
+ const end = index === span.last;
230
+ const start = index === span.first && !compact && span.first !== span.last;
231
+ if (!end && !start) return null;
232
+ const side = end ? 1 : -1;
233
+ return /* @__PURE__ */ jsxRuntime.jsxs(
234
+ "g",
235
+ {
236
+ "data-bump-name": "",
237
+ opacity: focus !== null && focus !== i ? 0.3 : 1,
238
+ ...pointer(i),
239
+ style: { transition: "opacity 150ms" },
240
+ children: [
241
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x + side * DOT_OFFSET, cy: y, r: 4, fill: color }),
242
+ /* @__PURE__ */ jsxRuntime.jsx(
243
+ "text",
244
+ {
245
+ x: x + side * (DOT_OFFSET + 10),
246
+ y,
247
+ textAnchor: end ? "start" : "end",
248
+ dominantBaseline: "central",
249
+ fill: chunkLT3UC65O_cjs.TEXT,
250
+ stroke: chunkLT3UC65O_cjs.PANEL,
251
+ strokeWidth: 3,
252
+ strokeLinejoin: "round",
253
+ paintOrder: "stroke",
254
+ style: { fontSize: "var(--text-sm, 0.875rem)", fontWeight: 600 },
255
+ children: text
256
+ }
257
+ )
258
+ ]
259
+ },
260
+ `${index}`
261
+ );
262
+ };
263
+ return Name;
264
+ };
265
+ return /* @__PURE__ */ jsxRuntime.jsx(
266
+ "div",
267
+ {
268
+ ref,
269
+ onKeyDown,
270
+ onBlur,
271
+ style: { width: width ?? "100%", maxWidth: "100%" },
272
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
273
+ recharts.LineChart,
274
+ {
275
+ ...chunkSR2ESX3R_cjs.frameProps({ height, width: "100%", ariaLabel: name }),
276
+ data: rows,
277
+ margin,
278
+ children: [
279
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: "category", ...chunkG4WOPX4D_cjs.AXIS, ...chunkXMFBVMW7_cjs.categoryAxis(periods) }),
280
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { hide: true, type: "number", reversed: true, domain }),
281
+ /* @__PURE__ */ jsxRuntime.jsx(
282
+ recharts.Tooltip,
283
+ {
284
+ content: /* @__PURE__ */ jsxRuntime.jsx(
285
+ BumpTooltip,
286
+ {
287
+ series,
288
+ periods,
289
+ ranks,
290
+ colors,
291
+ focus,
292
+ format: formatValue
293
+ }
294
+ ),
295
+ cursor: { stroke: chunkLT3UC65O_cjs.BORDER, strokeDasharray: "4 4" },
296
+ animationDuration: 150
297
+ }
298
+ ),
299
+ series.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
300
+ recharts.Line,
301
+ {
302
+ name: s.name,
303
+ dataKey: chunkK3R7JGOW_cjs.seriesKey(i),
304
+ type: "bumpX",
305
+ stroke: chunkLT3UC65O_cjs.seriesColor(i, colors),
306
+ strokeWidth: focus === i ? 4 : 3,
307
+ strokeOpacity: focus !== null && focus !== i ? 0.2 : 1,
308
+ strokeLinecap: "round",
309
+ connectNulls: false,
310
+ dot: renderDot(i),
311
+ activeDot: false,
312
+ label: renderName(i),
313
+ ...pointer(i),
314
+ ...chunkTYQWZR3S_cjs.ANIMATION
315
+ },
316
+ chunkK3R7JGOW_cjs.seriesKey(i)
317
+ )),
318
+ children
319
+ ]
320
+ }
321
+ )
322
+ }
323
+ );
324
+ };
325
+
326
+ exports.BumpChart = BumpChart;
327
+ //# sourceMappingURL=BumpChart.cjs.map
328
+ //# sourceMappingURL=BumpChart.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/bump.ts","../src/BumpChart.tsx"],"names":["seriesColor","jsxs","Fragment","jsx","MUTED","TooltipCard","useState","useElementWidth","useMemo","seriesKey","hasNoData","ChartEmpty","step","PANEL","TEXT","LineChart","frameProps","XAxis","AXIS","categoryAxis","YAxis","Tooltip","BORDER","Line","ANIMATION"],"mappings":"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","file":"BumpChart.cjs","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"]}