@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.
- package/CHANGELOG.md +91 -0
- package/README.md +107 -22
- package/THIRD_PARTY_NOTICES.md +81 -0
- package/dist/BarChart.cjs +137 -0
- package/dist/BarChart.cjs.map +1 -0
- package/dist/BarChart.js +135 -0
- package/dist/BarChart.js.map +1 -0
- package/dist/BoxPlotChart.cjs +214 -0
- package/dist/BoxPlotChart.cjs.map +1 -0
- package/dist/BoxPlotChart.js +212 -0
- package/dist/BoxPlotChart.js.map +1 -0
- package/dist/BumpChart.cjs +328 -0
- package/dist/BumpChart.cjs.map +1 -0
- package/dist/BumpChart.js +326 -0
- package/dist/BumpChart.js.map +1 -0
- package/dist/CalendarChart.cjs +216 -0
- package/dist/CalendarChart.cjs.map +1 -0
- package/dist/CalendarChart.js +214 -0
- package/dist/CalendarChart.js.map +1 -0
- package/dist/DonutChart.cjs +122 -0
- package/dist/DonutChart.cjs.map +1 -0
- package/dist/DonutChart.js +120 -0
- package/dist/DonutChart.js.map +1 -0
- package/dist/FunnelChart.cjs +422 -0
- package/dist/FunnelChart.cjs.map +1 -0
- package/dist/FunnelChart.js +420 -0
- package/dist/FunnelChart.js.map +1 -0
- package/dist/GradientRadial.cjs +51 -0
- package/dist/GradientRadial.cjs.map +1 -0
- package/dist/GradientRadial.js +49 -0
- package/dist/GradientRadial.js.map +1 -0
- package/dist/HeatmapChart.cjs +146 -0
- package/dist/HeatmapChart.cjs.map +1 -0
- package/dist/HeatmapChart.js +144 -0
- package/dist/HeatmapChart.js.map +1 -0
- package/dist/LineAreaChart.cjs +98 -0
- package/dist/LineAreaChart.cjs.map +1 -0
- package/dist/LineAreaChart.js +96 -0
- package/dist/LineAreaChart.js.map +1 -0
- package/dist/MixedChart.cjs +195 -0
- package/dist/MixedChart.cjs.map +1 -0
- package/dist/MixedChart.js +193 -0
- package/dist/MixedChart.js.map +1 -0
- package/dist/RadarChart.cjs +109 -0
- package/dist/RadarChart.cjs.map +1 -0
- package/dist/RadarChart.js +107 -0
- package/dist/RadarChart.js.map +1 -0
- package/dist/RadialBarChart.cjs +99 -0
- package/dist/RadialBarChart.cjs.map +1 -0
- package/dist/RadialBarChart.js +97 -0
- package/dist/RadialBarChart.js.map +1 -0
- package/dist/RangeBarChart.cjs +218 -0
- package/dist/RangeBarChart.cjs.map +1 -0
- package/dist/RangeBarChart.js +216 -0
- package/dist/RangeBarChart.js.map +1 -0
- package/dist/RealtimeChart.cjs +173 -0
- package/dist/RealtimeChart.cjs.map +1 -0
- package/dist/RealtimeChart.js +171 -0
- package/dist/RealtimeChart.js.map +1 -0
- package/dist/ScatterChart.cjs +134 -0
- package/dist/ScatterChart.cjs.map +1 -0
- package/dist/ScatterChart.js +131 -0
- package/dist/ScatterChart.js.map +1 -0
- package/dist/SemiCircleGauge.cjs +142 -0
- package/dist/SemiCircleGauge.cjs.map +1 -0
- package/dist/SemiCircleGauge.js +140 -0
- package/dist/SemiCircleGauge.js.map +1 -0
- package/dist/Sparkline.cjs +117 -0
- package/dist/Sparkline.cjs.map +1 -0
- package/dist/Sparkline.js +115 -0
- package/dist/Sparkline.js.map +1 -0
- package/dist/StrokedGauge.cjs +94 -0
- package/dist/StrokedGauge.cjs.map +1 -0
- package/dist/StrokedGauge.js +92 -0
- package/dist/StrokedGauge.js.map +1 -0
- package/dist/TreemapChart.cjs +263 -0
- package/dist/TreemapChart.cjs.map +1 -0
- package/dist/TreemapChart.js +261 -0
- package/dist/TreemapChart.js.map +1 -0
- package/dist/WaterfallChart.cjs +235 -0
- package/dist/WaterfallChart.cjs.map +1 -0
- package/dist/WaterfallChart.js +233 -0
- package/dist/WaterfallChart.js.map +1 -0
- package/dist/WorldMap.cjs +2088 -0
- package/dist/WorldMap.cjs.map +1 -0
- package/dist/WorldMap.js +603 -0
- package/dist/WorldMap.js.map +1 -0
- package/dist/chunk-3N43QT36.js +60 -0
- package/dist/chunk-3N43QT36.js.map +1 -0
- package/dist/chunk-5C2RLJYZ.js +11 -0
- package/dist/chunk-5C2RLJYZ.js.map +1 -0
- package/dist/chunk-6ALKZLN2.js +127 -0
- package/dist/chunk-6ALKZLN2.js.map +1 -0
- package/dist/chunk-6BKLL7LZ.cjs +30 -0
- package/dist/chunk-6BKLL7LZ.cjs.map +1 -0
- package/dist/chunk-6NRRABPF.cjs +64 -0
- package/dist/chunk-6NRRABPF.cjs.map +1 -0
- package/dist/chunk-AAYHG7YK.cjs +30 -0
- package/dist/chunk-AAYHG7YK.cjs.map +1 -0
- package/dist/chunk-AOSO5QHL.js +19 -0
- package/dist/chunk-AOSO5QHL.js.map +1 -0
- package/dist/chunk-BFEDLXVW.js +12 -0
- package/dist/chunk-BFEDLXVW.js.map +1 -0
- package/dist/chunk-DBZQI4HM.cjs +14 -0
- package/dist/chunk-DBZQI4HM.cjs.map +1 -0
- package/dist/chunk-F2PMFYJ5.cjs +40 -0
- package/dist/chunk-F2PMFYJ5.cjs.map +1 -0
- package/dist/chunk-FUZW3H5X.js +38 -0
- package/dist/chunk-FUZW3H5X.js.map +1 -0
- package/dist/chunk-GDZLYYL2.js +27 -0
- package/dist/chunk-GDZLYYL2.js.map +1 -0
- package/dist/chunk-GVTMZYOM.cjs +30 -0
- package/dist/chunk-GVTMZYOM.cjs.map +1 -0
- package/dist/chunk-GZRMVE4X.cjs +131 -0
- package/dist/chunk-GZRMVE4X.cjs.map +1 -0
- package/dist/chunk-HMH6DI7U.js +27 -0
- package/dist/chunk-HMH6DI7U.js.map +1 -0
- package/dist/chunk-ICL5K2CW.js +280 -0
- package/dist/chunk-ICL5K2CW.js.map +1 -0
- package/dist/chunk-IW6EWB26.cjs +21 -0
- package/dist/chunk-IW6EWB26.cjs.map +1 -0
- package/dist/chunk-K3R7JGOW.cjs +18 -0
- package/dist/chunk-K3R7JGOW.cjs.map +1 -0
- package/dist/chunk-LT3UC65O.cjs +68 -0
- package/dist/chunk-LT3UC65O.cjs.map +1 -0
- package/dist/chunk-MN4CDVOS.cjs +63 -0
- package/dist/chunk-MN4CDVOS.cjs.map +1 -0
- package/dist/chunk-OCD6JIIX.js +23 -0
- package/dist/chunk-OCD6JIIX.js.map +1 -0
- package/dist/chunk-RILUG7JB.js +44 -0
- package/dist/chunk-RILUG7JB.js.map +1 -0
- package/dist/chunk-RLHGPHC7.cjs +51 -0
- package/dist/chunk-RLHGPHC7.cjs.map +1 -0
- package/dist/chunk-SGG7XKOY.js +58 -0
- package/dist/chunk-SGG7XKOY.js.map +1 -0
- package/dist/chunk-T3K6Q34U.cjs +82 -0
- package/dist/chunk-T3K6Q34U.cjs.map +1 -0
- package/dist/chunk-TPH5T3DA.cjs +282 -0
- package/dist/chunk-TPH5T3DA.cjs.map +1 -0
- package/dist/chunk-TYQWZR3S.cjs +13 -0
- package/dist/chunk-TYQWZR3S.cjs.map +1 -0
- package/dist/chunk-UATB2IRY.js +51 -0
- package/dist/chunk-UATB2IRY.js.map +1 -0
- package/dist/chunk-UJIV5PVI.js +13 -0
- package/dist/chunk-UJIV5PVI.js.map +1 -0
- package/dist/chunk-URNXLVSK.js +44 -0
- package/dist/chunk-URNXLVSK.js.map +1 -0
- package/dist/chunk-VIOSQN4Z.js +79 -0
- package/dist/chunk-VIOSQN4Z.js.map +1 -0
- package/dist/chunk-X3YZP5WF.cjs +46 -0
- package/dist/chunk-X3YZP5WF.cjs.map +1 -0
- package/dist/chunk-YWYF5CCJ.js +61 -0
- package/dist/chunk-YWYF5CCJ.js.map +1 -0
- package/dist/chunk-Z4LZFMDH.cjs +60 -0
- package/dist/chunk-Z4LZFMDH.cjs.map +1 -0
- package/dist/index.cjs +154 -1166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +470 -80
- package/dist/index.d.ts +470 -80
- package/dist/index.js +23 -1144
- package/dist/index.js.map +1 -1
- package/dist/theme.cjs +88 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.js +84 -0
- package/dist/theme.js.map +1 -0
- package/package.json +23 -12
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkDBZQI4HM_cjs = require('./chunk-DBZQI4HM.cjs');
|
|
5
|
+
var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
|
|
6
|
+
var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
|
|
7
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
8
|
+
var react = require('react');
|
|
9
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
+
|
|
11
|
+
var GAP = 3;
|
|
12
|
+
var RADIUS = 5;
|
|
13
|
+
var LABEL_GAP = 6;
|
|
14
|
+
var TIP_GAP = 6;
|
|
15
|
+
var key = (row, column) => `${row}:${column}`;
|
|
16
|
+
var useLabelStride = (probe, gap) => {
|
|
17
|
+
const gridRef = react.useRef(null);
|
|
18
|
+
const probeRef = react.useRef(null);
|
|
19
|
+
const columnRef = react.useRef(null);
|
|
20
|
+
const [stride, setStride] = react.useState(1);
|
|
21
|
+
react.useLayoutEffect(() => {
|
|
22
|
+
const read = () => {
|
|
23
|
+
const label = probeRef.current?.offsetWidth ?? 0;
|
|
24
|
+
const column = columnRef.current?.offsetWidth ?? 0;
|
|
25
|
+
setStride(column > 0 ? Math.max(1, Math.ceil((label + LABEL_GAP) / (column + gap))) : 1);
|
|
26
|
+
};
|
|
27
|
+
read();
|
|
28
|
+
const observer = new ResizeObserver(read);
|
|
29
|
+
for (const el of [gridRef.current, probeRef.current]) if (el) observer.observe(el);
|
|
30
|
+
return () => observer.disconnect();
|
|
31
|
+
}, [probe, gap]);
|
|
32
|
+
return { gridRef, probeRef, columnRef, stride };
|
|
33
|
+
};
|
|
34
|
+
var HeatGrid = ({
|
|
35
|
+
rows,
|
|
36
|
+
columns,
|
|
37
|
+
cells,
|
|
38
|
+
cellHeight,
|
|
39
|
+
ariaLabel,
|
|
40
|
+
xTitle,
|
|
41
|
+
yTitle,
|
|
42
|
+
gap = GAP,
|
|
43
|
+
cellRadius = RADIUS,
|
|
44
|
+
columnWidth,
|
|
45
|
+
labelsAbove = false,
|
|
46
|
+
thinLabels = true
|
|
47
|
+
}) => {
|
|
48
|
+
const frame = react.useRef(null);
|
|
49
|
+
const longest = columns.reduce((a, b) => b.length > a.length ? b : a, "");
|
|
50
|
+
const { gridRef, probeRef, columnRef, stride: measured } = useLabelStride(longest, gap);
|
|
51
|
+
const stride = thinLabels ? measured : 1;
|
|
52
|
+
const byPosition = new Map(cells.map((cell) => [key(cell.row, cell.column), cell]));
|
|
53
|
+
const cellsByRow = /* @__PURE__ */ new Map();
|
|
54
|
+
for (const cell of cells) cellsByRow.set(cell.row, [...cellsByRow.get(cell.row) ?? [], cell]);
|
|
55
|
+
const inReadingOrder = [...cells].sort((a, b) => a.row - b.row || a.column - b.column);
|
|
56
|
+
const [roving, setRoving] = react.useState();
|
|
57
|
+
const first = inReadingOrder[0];
|
|
58
|
+
const tabbable = roving && byPosition.has(roving) ? roving : first && key(first.row, first.column);
|
|
59
|
+
const [hover, setHover] = react.useState();
|
|
60
|
+
const [focus, setFocus] = react.useState();
|
|
61
|
+
const tip = hover ?? focus;
|
|
62
|
+
const tipFor = (cell, element) => {
|
|
63
|
+
const host = frame.current.getBoundingClientRect();
|
|
64
|
+
const box = element.getBoundingClientRect();
|
|
65
|
+
const middle = box.left - host.left + box.width / 2;
|
|
66
|
+
const align = middle < host.width / 3 ? "start" : middle > 2 * host.width / 3 ? "end" : "center";
|
|
67
|
+
return {
|
|
68
|
+
cell,
|
|
69
|
+
x: { start: box.left - host.left, center: middle, end: box.right - host.left }[align],
|
|
70
|
+
top: box.top - host.top,
|
|
71
|
+
bottom: box.bottom - host.top,
|
|
72
|
+
align,
|
|
73
|
+
// Not enough room above the cell for the card: it goes under.
|
|
74
|
+
below: box.top - host.top < 90
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
const move = (event) => {
|
|
78
|
+
const origin = event.target.closest("[data-heat-cell]");
|
|
79
|
+
if (!origin) return;
|
|
80
|
+
const row = Number(origin.dataset.row);
|
|
81
|
+
const column = Number(origin.dataset.column);
|
|
82
|
+
const step = (dRow, dColumn) => {
|
|
83
|
+
for (let r = row + dRow, c = column + dColumn; r >= 0 && r < rows.length && c >= 0 && c < columns.length; r += dRow, c += dColumn) {
|
|
84
|
+
if (byPosition.has(key(r, c))) return key(r, c);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const edge = (last) => {
|
|
88
|
+
const pool = event.ctrlKey ? inReadingOrder : inReadingOrder.filter((cell2) => cell2.row === row);
|
|
89
|
+
const cell = last ? pool.at(-1) : pool[0];
|
|
90
|
+
return cell && key(cell.row, cell.column);
|
|
91
|
+
};
|
|
92
|
+
const targets = {
|
|
93
|
+
ArrowRight: () => step(0, 1),
|
|
94
|
+
ArrowLeft: () => step(0, -1),
|
|
95
|
+
ArrowDown: () => step(1, 0),
|
|
96
|
+
ArrowUp: () => step(-1, 0),
|
|
97
|
+
Home: () => edge(false),
|
|
98
|
+
End: () => edge(true)
|
|
99
|
+
};
|
|
100
|
+
const target = targets[event.key];
|
|
101
|
+
if (!target) return;
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
const next = target();
|
|
104
|
+
if (next) gridRef.current?.querySelector(`[data-position="${next}"]`)?.focus();
|
|
105
|
+
};
|
|
106
|
+
const focusIn = (cell, event) => {
|
|
107
|
+
setRoving(key(cell.row, cell.column));
|
|
108
|
+
if (event.currentTarget.matches(":focus-visible")) {
|
|
109
|
+
setFocus(tipFor(cell, event.currentTarget));
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const focusOut = (event) => {
|
|
113
|
+
if (!event.currentTarget.contains(event.relatedTarget)) setFocus(void 0);
|
|
114
|
+
};
|
|
115
|
+
const rowOffset = yTitle ? 2 : 1;
|
|
116
|
+
const top = labelsAbove ? 1 : 0;
|
|
117
|
+
const labelsRow = labelsAbove ? 1 : rows.length + 1;
|
|
118
|
+
const tipStyle = tip && {
|
|
119
|
+
position: "absolute",
|
|
120
|
+
left: tip.x,
|
|
121
|
+
top: tip.below ? tip.bottom + TIP_GAP : tip.top - TIP_GAP,
|
|
122
|
+
transform: `translate(${{ start: "0", center: "-50%", end: "-100%" }[tip.align]}, ${tip.below ? "0" : "-100%"})`,
|
|
123
|
+
zIndex: 10,
|
|
124
|
+
pointerEvents: "none"
|
|
125
|
+
};
|
|
126
|
+
const grid = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
127
|
+
"div",
|
|
128
|
+
{
|
|
129
|
+
ref: gridRef,
|
|
130
|
+
role: "grid",
|
|
131
|
+
"aria-label": ariaLabel,
|
|
132
|
+
onKeyDown: move,
|
|
133
|
+
onBlur: focusOut,
|
|
134
|
+
style: {
|
|
135
|
+
display: "grid",
|
|
136
|
+
gridTemplateColumns: `${yTitle ? "auto " : ""}${columnWidth ? "auto" : "fit-content(40%)"} repeat(${columns.length}, ${columnWidth ? `${columnWidth}px` : "minmax(0, 1fr)"})`,
|
|
137
|
+
gridTemplateRows: `${labelsAbove ? "auto " : ""}repeat(${rows.length}, ${cellHeight ? `${cellHeight}px` : "minmax(0, 1fr)"})${labelsAbove ? "" : " auto"}${xTitle ? " auto" : ""}`,
|
|
138
|
+
gap,
|
|
139
|
+
width: columnWidth ? "max-content" : "100%",
|
|
140
|
+
height: cellHeight ? void 0 : "100%",
|
|
141
|
+
fontSize: chunkRLHGPHC7_cjs.TEXT_SIZE,
|
|
142
|
+
color: chunkLT3UC65O_cjs.MUTED
|
|
143
|
+
},
|
|
144
|
+
children: [
|
|
145
|
+
yTitle && /* @__PURE__ */ jsxRuntime.jsx(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
"aria-hidden": true,
|
|
149
|
+
style: {
|
|
150
|
+
gridRow: `${1 + top} / ${rows.length + 1 + top}`,
|
|
151
|
+
gridColumn: 1,
|
|
152
|
+
writingMode: "vertical-rl",
|
|
153
|
+
transform: "rotate(180deg)",
|
|
154
|
+
textAlign: "center",
|
|
155
|
+
alignSelf: "center"
|
|
156
|
+
},
|
|
157
|
+
children: yTitle
|
|
158
|
+
}
|
|
159
|
+
),
|
|
160
|
+
rows.map((name, r) => /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "row", style: { display: "contents" }, children: [
|
|
161
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
162
|
+
"div",
|
|
163
|
+
{
|
|
164
|
+
"aria-hidden": true,
|
|
165
|
+
"data-heat-row": "",
|
|
166
|
+
style: {
|
|
167
|
+
gridRow: r + 1 + top,
|
|
168
|
+
gridColumn: rowOffset,
|
|
169
|
+
alignSelf: "center",
|
|
170
|
+
paddingRight: "0.5rem",
|
|
171
|
+
// Stays in view when the grid scrolls sideways under it.
|
|
172
|
+
...columnWidth ? { position: "sticky", left: 0, zIndex: 2, background: chunkLT3UC65O_cjs.PANEL } : {},
|
|
173
|
+
whiteSpace: "nowrap",
|
|
174
|
+
overflow: "hidden",
|
|
175
|
+
textOverflow: "ellipsis"
|
|
176
|
+
},
|
|
177
|
+
children: name
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
(cellsByRow.get(r) ?? []).map((cell) => {
|
|
181
|
+
const position = key(cell.row, cell.column);
|
|
182
|
+
const active = tip?.cell === cell;
|
|
183
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
184
|
+
"div",
|
|
185
|
+
{
|
|
186
|
+
role: "gridcell",
|
|
187
|
+
"data-heat-cell": "",
|
|
188
|
+
"data-position": position,
|
|
189
|
+
"data-row": cell.row,
|
|
190
|
+
"data-column": cell.column,
|
|
191
|
+
tabIndex: position === tabbable ? 0 : -1,
|
|
192
|
+
"aria-label": `${cell.label ? `${cell.label}, ` : ""}${cell.title}: ${cell.value}`,
|
|
193
|
+
onFocus: (event) => focusIn(cell, event),
|
|
194
|
+
onMouseEnter: (event) => setHover(tipFor(cell, event.currentTarget)),
|
|
195
|
+
onMouseLeave: () => setHover(void 0),
|
|
196
|
+
style: {
|
|
197
|
+
gridRow: r + 1 + top,
|
|
198
|
+
gridColumn: cell.column + rowOffset + 1,
|
|
199
|
+
display: "flex",
|
|
200
|
+
alignItems: "center",
|
|
201
|
+
justifyContent: "center",
|
|
202
|
+
minWidth: 0,
|
|
203
|
+
overflow: "hidden",
|
|
204
|
+
borderRadius: cellRadius,
|
|
205
|
+
background: cell.color,
|
|
206
|
+
color: chunkDBZQI4HM_cjs.textOn(cell.color),
|
|
207
|
+
fontSize: "var(--text-2xs, 0.6875rem)",
|
|
208
|
+
fontWeight: 500,
|
|
209
|
+
lineHeight: 1,
|
|
210
|
+
whiteSpace: "nowrap",
|
|
211
|
+
// The same ring for the pointer and the keyboard, in the text color
|
|
212
|
+
// since an accent ring would vanish on the cells that are the accent.
|
|
213
|
+
outline: active ? `2px solid ${chunkLT3UC65O_cjs.TEXT}` : "none",
|
|
214
|
+
zIndex: active ? 1 : void 0
|
|
215
|
+
},
|
|
216
|
+
children: cell.text
|
|
217
|
+
},
|
|
218
|
+
position
|
|
219
|
+
);
|
|
220
|
+
})
|
|
221
|
+
] }, r)),
|
|
222
|
+
columns.map((name, c) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
223
|
+
"div",
|
|
224
|
+
{
|
|
225
|
+
ref: c === 0 ? columnRef : void 0,
|
|
226
|
+
"aria-hidden": true,
|
|
227
|
+
"data-heat-column": "",
|
|
228
|
+
style: {
|
|
229
|
+
gridRow: labelsRow,
|
|
230
|
+
gridColumn: c + rowOffset + 1,
|
|
231
|
+
display: "flex",
|
|
232
|
+
justifyContent: thinLabels ? "center" : "flex-start",
|
|
233
|
+
whiteSpace: "nowrap",
|
|
234
|
+
minWidth: 0
|
|
235
|
+
},
|
|
236
|
+
children: c % stride === 0 ? name : null
|
|
237
|
+
},
|
|
238
|
+
c
|
|
239
|
+
)),
|
|
240
|
+
xTitle && /* @__PURE__ */ jsxRuntime.jsx(
|
|
241
|
+
"div",
|
|
242
|
+
{
|
|
243
|
+
"aria-hidden": true,
|
|
244
|
+
style: {
|
|
245
|
+
gridRow: (labelsAbove ? rows.length + 1 : labelsRow) + 1,
|
|
246
|
+
gridColumn: `${rowOffset + 1} / -1`,
|
|
247
|
+
textAlign: "center"
|
|
248
|
+
},
|
|
249
|
+
children: xTitle
|
|
250
|
+
}
|
|
251
|
+
),
|
|
252
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
253
|
+
"span",
|
|
254
|
+
{
|
|
255
|
+
ref: probeRef,
|
|
256
|
+
"aria-hidden": true,
|
|
257
|
+
style: { position: "absolute", visibility: "hidden", whiteSpace: "nowrap" },
|
|
258
|
+
children: longest
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: frame, style: { position: "relative", width: "100%", height: "100%", minWidth: 0 }, children: [
|
|
265
|
+
columnWidth ? (
|
|
266
|
+
// The padding leaves room for the focus outline of the cells at the edges,
|
|
267
|
+
// which the scrolling box would cut.
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-heat-scroll": "", style: { overflowX: "auto", padding: 3 }, children: grid })
|
|
269
|
+
) : grid,
|
|
270
|
+
tip && tipStyle && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-heat-tooltip": "", "aria-hidden": true, style: tipStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
271
|
+
chunkT3K6Q34U_cjs.TooltipCard,
|
|
272
|
+
{
|
|
273
|
+
title: tip.cell.title,
|
|
274
|
+
rows: [{ name: tip.cell.label, value: tip.cell.value, color: tip.cell.color }]
|
|
275
|
+
}
|
|
276
|
+
) })
|
|
277
|
+
] });
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
exports.HeatGrid = HeatGrid;
|
|
281
|
+
//# sourceMappingURL=chunk-TPH5T3DA.cjs.map
|
|
282
|
+
//# sourceMappingURL=chunk-TPH5T3DA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/HeatGrid.tsx"],"names":["useRef","useState","useLayoutEffect","cell","jsxs","TEXT_SIZE","MUTED","jsx","PANEL","textOn","TEXT","TooltipCard"],"mappings":";;;;;;;;;;AAqEA,IAAM,GAAA,GAAM,CAAA;AACZ,IAAM,MAAA,GAAS,CAAA;AAEf,IAAM,SAAA,GAAY,CAAA;AAElB,IAAM,OAAA,GAAU,CAAA;AAEhB,IAAM,MAAM,CAAC,GAAA,EAAa,WAAmB,CAAA,EAAG,GAAG,IAAI,MAAM,CAAA,CAAA;AAO7D,IAAM,cAAA,GAAiB,CAAC,KAAA,EAAe,GAAA,KAAgB;AACrD,EAAA,MAAM,OAAA,GAAUA,aAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,QAAA,GAAWA,aAAwB,IAAI,CAAA;AAC7C,EAAA,MAAM,SAAA,GAAYA,aAAuB,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,eAAS,CAAC,CAAA;AACtC,EAAAC,qBAAA,CAAgB,MAAM;AACpB,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,EAAS,WAAA,IAAe,CAAA;AAC/C,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,OAAA,EAAS,WAAA,IAAe,CAAA;AACjD,MAAA,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAA,CAAM,KAAA,GAAQ,SAAA,KAAc,MAAA,GAAS,GAAA,CAAI,CAAC,IAAI,CAAC,CAAA;AAAA,IACzF,CAAA;AACA,IAAA,IAAA,EAAK;AACL,IAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,IAAI,CAAA;AACxC,IAAA,KAAA,MAAW,EAAA,IAAM,CAAC,OAAA,CAAQ,OAAA,EAAS,QAAA,CAAS,OAAO,CAAA,EAAG,IAAI,EAAA,EAAI,QAAA,CAAS,OAAA,CAAQ,EAAE,CAAA;AACjF,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,KAAA,EAAO,GAAG,CAAC,CAAA;AACf,EAAA,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,SAAA,EAAW,MAAA,EAAO;AAChD,CAAA;AAwBO,IAAM,WAAW,CAAC;AAAA,EACvB,IAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA,GAAM,GAAA;AAAA,EACN,UAAA,GAAa,MAAA;AAAA,EACb,WAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,UAAA,GAAa;AACf,CAAA,KAAqB;AACnB,EAAA,MAAM,KAAA,GAAQF,aAAuB,IAAI,CAAA;AACzC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAO,CAAA,CAAE,MAAA,GAAS,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,CAAA,EAAI,EAAE,CAAA;AAC1E,EAAA,MAAM,EAAE,SAAS,QAAA,EAAU,SAAA,EAAW,QAAQ,QAAA,EAAS,GAAI,cAAA,CAAe,OAAA,EAAS,GAAG,CAAA;AACtF,EAAA,MAAM,MAAA,GAAS,aAAa,QAAA,GAAW,CAAA;AACvC,EAAA,MAAM,aAAa,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,CAAC,GAAA,CAAI,IAAA,CAAK,KAAK,IAAA,CAAK,MAAM,CAAA,EAAG,IAAI,CAAC,CAAC,CAAA;AAClF,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAwB;AAC/C,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,GAAI,UAAA,CAAW,GAAA,CAAI,KAAK,GAAG,CAAA,IAAK,EAAC,EAAI,IAAI,CAAC,CAAA;AAC9F,EAAA,MAAM,iBAAiB,CAAC,GAAG,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,MAAM,CAAA,CAAE,GAAA,IAAO,CAAA,CAAE,MAAA,GAAS,EAAE,MAAM,CAAA;AACrF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,cAAA,EAAiB;AAE7C,EAAA,MAAM,KAAA,GAAQ,eAAe,CAAC,CAAA;AAC9B,EAAA,MAAM,QAAA,GACJ,MAAA,IAAU,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,GAAI,MAAA,GAAS,KAAA,IAAS,GAAA,CAAI,KAAA,CAAM,GAAA,EAAK,KAAA,CAAM,MAAM,CAAA;AAClF,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,cAAA,EAAc;AACxC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,cAAA,EAAc;AACxC,EAAA,MAAM,MAAM,KAAA,IAAS,KAAA;AAErB,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,EAAgB,OAAA,KAA8B;AAC5D,IAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,OAAA,CAAwB,qBAAA,EAAsB;AAClE,IAAA,MAAM,GAAA,GAAM,QAAQ,qBAAA,EAAsB;AAC1C,IAAA,MAAM,SAAS,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,IAAA,GAAO,IAAI,KAAA,GAAQ,CAAA;AAGlD,IAAA,MAAM,KAAA,GACJ,MAAA,GAAS,IAAA,CAAK,KAAA,GAAQ,CAAA,GAAI,OAAA,GAAU,MAAA,GAAU,CAAA,GAAI,IAAA,CAAK,KAAA,GAAS,CAAA,GAAI,KAAA,GAAQ,QAAA;AAC9E,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,CAAA,EAAG,EAAE,KAAA,EAAO,GAAA,CAAI,OAAO,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,KAAK,GAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,IAAA,GAAO,KAAK,CAAA;AAAA,MACpF,GAAA,EAAK,GAAA,CAAI,GAAA,GAAM,IAAA,CAAK,GAAA;AAAA,MACpB,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,IAAA,CAAK,GAAA;AAAA,MAC1B,KAAA;AAAA;AAAA,MAEA,KAAA,EAAO,GAAA,CAAI,GAAA,GAAM,IAAA,CAAK,GAAA,GAAM;AAAA,KAC9B;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,IAAA,GAAO,CAAC,KAAA,KAAyC;AACrD,IAAA,MAAM,MAAA,GAAU,KAAA,CAAM,MAAA,CAAuB,OAAA,CAAqB,kBAAkB,CAAA;AACpF,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA;AACrC,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AAE3C,IAAA,MAAM,IAAA,GAAO,CAAC,IAAA,EAAc,OAAA,KAAoB;AAC9C,MAAA,KAAA,IACM,IAAI,GAAA,GAAM,IAAA,EAAM,IAAI,MAAA,GAAS,OAAA,EACjC,KAAK,CAAA,IAAK,CAAA,GAAI,KAAK,MAAA,IAAU,CAAA,IAAK,KAAK,CAAA,GAAI,OAAA,CAAQ,QACnD,CAAA,IAAK,IAAA,EAAM,KAAK,OAAA,EAChB;AACA,QAAA,IAAI,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA,EAAG,OAAO,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,MAChD;AAAA,IACF,CAAA;AACA,IAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAAkB;AAC9B,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,GACf,cAAA,GACA,cAAA,CAAe,OAAO,CAACE,KAAAA,KAASA,KAAAA,CAAK,GAAA,KAAQ,GAAG,CAAA;AACpD,MAAA,MAAM,OAAO,IAAA,GAAO,IAAA,CAAK,GAAG,EAAE,CAAA,GAAI,KAAK,CAAC,CAAA;AACxC,MAAA,OAAO,IAAA,IAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,EAAK,KAAK,MAAM,CAAA;AAAA,IAC1C,CAAA;AACA,IAAA,MAAM,OAAA,GAAoD;AAAA,MACxD,UAAA,EAAY,MAAM,IAAA,CAAK,CAAA,EAAG,CAAC,CAAA;AAAA,MAC3B,SAAA,EAAW,MAAM,IAAA,CAAK,CAAA,EAAG,EAAE,CAAA;AAAA,MAC3B,SAAA,EAAW,MAAM,IAAA,CAAK,CAAA,EAAG,CAAC,CAAA;AAAA,MAC1B,OAAA,EAAS,MAAM,IAAA,CAAK,EAAA,EAAI,CAAC,CAAA;AAAA,MACzB,IAAA,EAAM,MAAM,IAAA,CAAK,KAAK,CAAA;AAAA,MACtB,GAAA,EAAK,MAAM,IAAA,CAAK,IAAI;AAAA,KACtB;AACA,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA;AAChC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,KAAA,CAAM,cAAA,EAAe;AACrB,IAAA,MAAM,OAAO,MAAA,EAAO;AACpB,IAAA,IAAI,IAAA,UAAc,OAAA,EAAS,aAAA,CAA2B,mBAAmB,IAAI,CAAA,EAAA,CAAI,GAAG,KAAA,EAAM;AAAA,EAC5F,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,EAAgB,KAAA,KAAmC;AAClE,IAAA,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,MAAM,CAAC,CAAA;AAEpC,IAAA,IAAI,KAAA,CAAM,aAAA,CAAc,OAAA,CAAQ,gBAAgB,CAAA,EAAG;AACjD,MAAA,QAAA,CAAS,MAAA,CAAO,IAAA,EAAM,KAAA,CAAM,aAAa,CAAC,CAAA;AAAA,IAC5C;AAAA,EACF,CAAA;AACA,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAsC;AACtD,IAAA,IAAI,CAAC,MAAM,aAAA,CAAc,QAAA,CAAS,MAAM,aAAa,CAAA,WAAY,MAAS,CAAA;AAAA,EAC5E,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,SAAS,CAAA,GAAI,CAAA;AAE/B,EAAA,MAAM,GAAA,GAAM,cAAc,CAAA,GAAI,CAAA;AAC9B,EAAA,MAAM,SAAA,GAAY,WAAA,GAAc,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,CAAA;AAClD,EAAA,MAAM,WAAsC,GAAA,IAAO;AAAA,IACjD,QAAA,EAAU,UAAA;AAAA,IACV,MAAM,GAAA,CAAI,CAAA;AAAA,IACV,KAAK,GAAA,CAAI,KAAA,GAAQ,IAAI,MAAA,GAAS,OAAA,GAAU,IAAI,GAAA,GAAM,OAAA;AAAA,IAClD,WAAW,CAAA,UAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,MAAA,EAAQ,GAAA,EAAK,OAAA,EAAQ,CAAE,IAAI,KAAK,CAAC,KAAK,GAAA,CAAI,KAAA,GAAQ,MAAM,OAAO,CAAA,CAAA,CAAA;AAAA,IAC7G,MAAA,EAAQ,EAAA;AAAA,IACR,aAAA,EAAe;AAAA,GACjB;AAEA,EAAA,MAAM,IAAA,mBACJC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,OAAA;AAAA,MACL,IAAA,EAAK,MAAA;AAAA,MACL,YAAA,EAAY,SAAA;AAAA,MACZ,SAAA,EAAW,IAAA;AAAA,MACX,MAAA,EAAQ,QAAA;AAAA,MACR,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,qBAAqB,CAAA,EAAG,MAAA,GAAS,OAAA,GAAU,EAAE,GAAG,WAAA,GAAc,MAAA,GAAS,kBAAkB,CAAA,QAAA,EAAW,QAAQ,MAAM,CAAA,EAAA,EAAK,cAAc,CAAA,EAAG,WAAW,OAAO,gBAAgB,CAAA,CAAA,CAAA;AAAA,QAC1K,gBAAA,EAAkB,GAAG,WAAA,GAAc,OAAA,GAAU,EAAE,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,EAAA,EAAK,UAAA,GAAa,GAAG,UAAU,CAAA,EAAA,CAAA,GAAO,gBAAgB,CAAA,CAAA,EAAI,WAAA,GAAc,KAAK,OAAO,CAAA,EAAG,MAAA,GAAS,OAAA,GAAU,EAAE,CAAA,CAAA;AAAA,QAChL,GAAA;AAAA,QACA,KAAA,EAAO,cAAc,aAAA,GAAgB,MAAA;AAAA,QACrC,MAAA,EAAQ,aAAa,MAAA,GAAY,MAAA;AAAA,QACjC,QAAA,EAAUC,2BAAA;AAAA,QACV,KAAA,EAAOC;AAAA,OACT;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,MAAA,oBACCC,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAW,IAAA;AAAA,YACX,KAAA,EAAO;AAAA,cACL,OAAA,EAAS,GAAG,CAAA,GAAI,GAAG,MAAM,IAAA,CAAK,MAAA,GAAS,IAAI,GAAG,CAAA,CAAA;AAAA,cAC9C,UAAA,EAAY,CAAA;AAAA,cACZ,WAAA,EAAa,aAAA;AAAA,cACb,SAAA,EAAW,gBAAA;AAAA,cACX,SAAA,EAAW,QAAA;AAAA,cACX,SAAA,EAAW;AAAA,aACb;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAED,IAAA,CAAK,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,qBACfH,eAAA,CAAC,KAAA,EAAA,EAAY,IAAA,EAAK,KAAA,EAAM,KAAA,EAAO,EAAE,OAAA,EAAS,YAAW,EACnD,QAAA,EAAA;AAAA,0BAAAG,cAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAW,IAAA;AAAA,cACX,eAAA,EAAc,EAAA;AAAA,cACd,KAAA,EAAO;AAAA,gBACL,OAAA,EAAS,IAAI,CAAA,GAAI,GAAA;AAAA,gBACjB,UAAA,EAAY,SAAA;AAAA,gBACZ,SAAA,EAAW,QAAA;AAAA,gBACX,YAAA,EAAc,QAAA;AAAA;AAAA,gBAEd,GAAI,WAAA,GAAc,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA,EAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,UAAA,EAAYC,uBAAA,EAAM,GAAI,EAAC;AAAA,gBACnF,UAAA,EAAY,QAAA;AAAA,gBACZ,QAAA,EAAU,QAAA;AAAA,gBACV,YAAA,EAAc;AAAA,eAChB;AAAA,cAEC,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,UAAA,CACE,UAAA,CAAW,IAAI,CAAC,CAAA,IAAK,EAAC,EAAG,GAAA,CAAI,CAAC,IAAA,KAAS;AACvC,YAAA,MAAM,QAAA,GAAW,GAAA,CAAI,IAAA,CAAK,GAAA,EAAK,KAAK,MAAM,CAAA;AAC1C,YAAA,MAAM,MAAA,GAAS,KAAK,IAAA,KAAS,IAAA;AAC7B,YAAA,uBACED,cAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBAEC,IAAA,EAAK,UAAA;AAAA,gBACL,gBAAA,EAAe,EAAA;AAAA,gBACf,eAAA,EAAe,QAAA;AAAA,gBACf,YAAU,IAAA,CAAK,GAAA;AAAA,gBACf,eAAa,IAAA,CAAK,MAAA;AAAA,gBAClB,QAAA,EAAU,QAAA,KAAa,QAAA,GAAW,CAAA,GAAI,EAAA;AAAA,gBACtC,YAAA,EAAY,CAAA,EAAG,IAAA,CAAK,KAAA,GAAQ,GAAG,IAAA,CAAK,KAAK,CAAA,EAAA,CAAA,GAAO,EAAE,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK,KAAK,KAAK,CAAA,CAAA;AAAA,gBAC9E,OAAA,EAAS,CAAC,KAAA,KAAU,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,gBACvC,YAAA,EAAc,CAAC,KAAA,KAAU,QAAA,CAAS,OAAO,IAAA,EAAM,KAAA,CAAM,aAAa,CAAC,CAAA;AAAA,gBACnE,YAAA,EAAc,MAAM,QAAA,CAAS,MAAS,CAAA;AAAA,gBACtC,KAAA,EAAO;AAAA,kBACL,OAAA,EAAS,IAAI,CAAA,GAAI,GAAA;AAAA,kBACjB,UAAA,EAAY,IAAA,CAAK,MAAA,GAAS,SAAA,GAAY,CAAA;AAAA,kBACtC,OAAA,EAAS,MAAA;AAAA,kBACT,UAAA,EAAY,QAAA;AAAA,kBACZ,cAAA,EAAgB,QAAA;AAAA,kBAChB,QAAA,EAAU,CAAA;AAAA,kBACV,QAAA,EAAU,QAAA;AAAA,kBACV,YAAA,EAAc,UAAA;AAAA,kBACd,YAAY,IAAA,CAAK,KAAA;AAAA,kBACjB,KAAA,EAAOE,wBAAA,CAAO,IAAA,CAAK,KAAK,CAAA;AAAA,kBACxB,QAAA,EAAU,4BAAA;AAAA,kBACV,UAAA,EAAY,GAAA;AAAA,kBACZ,UAAA,EAAY,CAAA;AAAA,kBACZ,UAAA,EAAY,QAAA;AAAA;AAAA;AAAA,kBAGZ,OAAA,EAAS,MAAA,GAAS,CAAA,UAAA,EAAaC,sBAAI,CAAA,CAAA,GAAK,MAAA;AAAA,kBACxC,MAAA,EAAQ,SAAS,CAAA,GAAI;AAAA,iBACvB;AAAA,gBAEC,QAAA,EAAA,IAAA,CAAK;AAAA,eAAA;AAAA,cAhCD;AAAA,aAiCP;AAAA,UAEJ,CAAC;AAAA,SAAA,EAAA,EA1DO,CA2DV,CACD,CAAA;AAAA,QACA,OAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,qBAClBH,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,GAAA,EAAK,CAAA,KAAM,CAAA,GAAI,SAAA,GAAY,MAAA;AAAA,YAC3B,aAAA,EAAW,IAAA;AAAA,YACX,kBAAA,EAAiB,EAAA;AAAA,YACjB,KAAA,EAAO;AAAA,cACL,OAAA,EAAS,SAAA;AAAA,cACT,UAAA,EAAY,IAAI,SAAA,GAAY,CAAA;AAAA,cAC5B,OAAA,EAAS,MAAA;AAAA,cACT,cAAA,EAAgB,aAAa,QAAA,GAAW,YAAA;AAAA,cACxC,UAAA,EAAY,QAAA;AAAA,cACZ,QAAA,EAAU;AAAA,aACZ;AAAA,YAEC,QAAA,EAAA,CAAA,GAAI,MAAA,KAAW,CAAA,GAAI,IAAA,GAAO;AAAA,WAAA;AAAA,UAbtB;AAAA,SAeR,CAAA;AAAA,QACA,MAAA,oBACCA,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAW,IAAA;AAAA,YACX,KAAA,EAAO;AAAA,cACL,OAAA,EAAA,CAAU,WAAA,GAAc,IAAA,CAAK,MAAA,GAAS,IAAI,SAAA,IAAa,CAAA;AAAA,cACvD,UAAA,EAAY,CAAA,EAAG,SAAA,GAAY,CAAC,CAAA,KAAA,CAAA;AAAA,cAC5B,SAAA,EAAW;AAAA,aACb;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBAEFA,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,QAAA;AAAA,YACL,aAAA,EAAW,IAAA;AAAA,YACX,OAAO,EAAE,QAAA,EAAU,YAAY,UAAA,EAAY,QAAA,EAAU,YAAY,QAAA,EAAS;AAAA,YAEzE,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GACF;AAGF,EAAA,uBACEH,eAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,KAAA,EAAO,OAAO,EAAE,QAAA,EAAU,UAAA,EAAY,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,GAAE,EACxF,QAAA,EAAA;AAAA,IAAA,WAAA;AAAA;AAAA;AAAA,sBAGCG,cAAA,CAAC,KAAA,EAAA,EAAI,kBAAA,EAAiB,EAAA,EAAG,KAAA,EAAO,EAAE,SAAA,EAAW,MAAA,EAAQ,OAAA,EAAS,CAAA,EAAE,EAC7D,QAAA,EAAA,IAAA,EACH;AAAA,QAEA,IAAA;AAAA,IAED,GAAA,IAAO,4BACNA,cAAA,CAAC,KAAA,EAAA,EAAI,qBAAkB,EAAA,EAAG,aAAA,EAAW,IAAA,EAAC,KAAA,EAAO,QAAA,EAC3C,QAAA,kBAAAA,cAAA;AAAA,MAACI,6BAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,IAAI,IAAA,CAAK,KAAA;AAAA,QAChB,IAAA,EAAM,CAAC,EAAE,IAAA,EAAM,IAAI,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAA,CAAI,KAAK,KAAA,EAAO,KAAA,EAAO,GAAA,CAAI,IAAA,CAAK,OAAO;AAAA;AAAA,KAC/E,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"chunk-TPH5T3DA.cjs","sourcesContent":["import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type KeyboardEvent,\n} from 'react';\nimport { TEXT_SIZE } from './axes';\nimport { TooltipCard } from './ChartTooltip';\nimport { MUTED, PANEL, TEXT } from './colors';\nimport { textOn } from './readable';\n\n/** One cell of a `HeatGrid`. A slot with no cell stays empty. */\nexport type HeatCell = {\n /** Zero-based position: the index in `rows` and in `columns`. */\n row: number;\n column: number;\n /** Any CSS color. The text printed in the cell reads on it. */\n color: string;\n /** Heads the tooltip, such as the column's category. */\n title: string;\n /** Names the cell in the tooltip, such as the row. May be empty when the value says it all. */\n label: string;\n /** The value, formatted: the tooltip's value, and the end of the cell's accessible name. */\n value: string;\n /** Printed inside the cell. */\n text?: string;\n};\n\ntype HeatGridProps = {\n /** The label of each row, top to bottom. An empty string leaves the row unlabelled. */\n rows: readonly string[];\n /** The label of each column, left to right. Too many for the width: every n-th one is drawn. */\n columns: readonly string[];\n cells: readonly HeatCell[];\n /**\n * Height of a row in px. Without it the rows share the height of the\n * parent, which must then have one.\n */\n cellHeight?: number;\n /** Names the grid for screen readers. */\n ariaLabel: string;\n /** Title under the columns. Drawn as plain text. */\n xTitle?: string;\n /** Title beside the rows. Drawn as plain text. */\n yTitle?: string;\n /** Space between two cells in px. Default 3. */\n gap?: number;\n /** Corner radius of a cell in px. Default 5. */\n cellRadius?: number;\n /**\n * Width of a column in px. Without it the columns share the width of the\n * parent; with it they keep this width, and the grid scrolls sideways inside\n * its own box when it is wider than the parent. The row labels stay in view.\n */\n columnWidth?: number;\n /** Draw the column labels above the rows instead of under them. */\n labelsAbove?: boolean;\n /**\n * Draw every column label, as given. By default the labels are centered on\n * their column and every n-th one is drawn so that none touches the next.\n * Off, each starts at the left of its column and may run over the columns\n * after it, which an empty label leaves free: for labels such as the months\n * of a calendar, where the caller decides which columns carry one.\n */\n thinLabels?: boolean;\n};\n\nconst GAP = 3;\nconst RADIUS = 5;\n// Clear space kept between two column labels.\nconst LABEL_GAP = 6;\n// Room the tooltip card leaves the pointer or the cell.\nconst TIP_GAP = 6;\n\nconst key = (row: number, column: number) => `${row}:${column}`;\n\n/**\n * How many columns apart the labels are drawn so that none touches the next:\n * 1 when they all fit. Measured on the page, since the text size, the font and\n * the width all change it.\n */\nconst useLabelStride = (probe: string, gap: number) => {\n const gridRef = useRef<HTMLDivElement>(null);\n const probeRef = useRef<HTMLSpanElement>(null);\n const columnRef = useRef<HTMLDivElement>(null);\n const [stride, setStride] = useState(1);\n useLayoutEffect(() => {\n const read = () => {\n const label = probeRef.current?.offsetWidth ?? 0;\n const column = columnRef.current?.offsetWidth ?? 0;\n setStride(column > 0 ? Math.max(1, Math.ceil((label + LABEL_GAP) / (column + gap))) : 1);\n };\n read();\n const observer = new ResizeObserver(read);\n for (const el of [gridRef.current, probeRef.current]) if (el) observer.observe(el);\n return () => observer.disconnect();\n }, [probe, gap]);\n return { gridRef, probeRef, columnRef, stride };\n};\n\ntype Tip = {\n cell: HeatCell;\n /** Where the card is anchored, in px from the grid's corner, and on which side of the cell. */\n x: number;\n top: number;\n bottom: number;\n align: 'start' | 'center' | 'end';\n below: boolean;\n};\n\n/**\n * A grid of colored cells with row and column labels: the drawing of\n * `HeatmapChart`, and of any chart laid out as rows and columns. Recharts has\n * no such chart, so it is plain HTML in a CSS grid, which sizes the label\n * column to the text (it follows the text size) and the cells to the width.\n *\n * Keyboard: the grid is one tab stop (a roving tabindex), and the arrow keys\n * move between cells, skipping empty slots; Home and End go to the ends of the\n * row, Ctrl+Home and Ctrl+End to the first and last cell. The cell under the\n * pointer or the keyboard shows its tooltip. Each cell is named\n * `label, title: value`, so a screen reader reads what the tooltip says.\n */\nexport const HeatGrid = ({\n rows,\n columns,\n cells,\n cellHeight,\n ariaLabel,\n xTitle,\n yTitle,\n gap = GAP,\n cellRadius = RADIUS,\n columnWidth,\n labelsAbove = false,\n thinLabels = true,\n}: HeatGridProps) => {\n const frame = useRef<HTMLDivElement>(null);\n const longest = columns.reduce((a, b) => (b.length > a.length ? b : a), '');\n const { gridRef, probeRef, columnRef, stride: measured } = useLabelStride(longest, gap);\n const stride = thinLabels ? measured : 1;\n const byPosition = new Map(cells.map((cell) => [key(cell.row, cell.column), cell]));\n const cellsByRow = new Map<number, HeatCell[]>();\n for (const cell of cells) cellsByRow.set(cell.row, [...(cellsByRow.get(cell.row) ?? []), cell]);\n const inReadingOrder = [...cells].sort((a, b) => a.row - b.row || a.column - b.column);\n const [roving, setRoving] = useState<string>();\n // The cell that takes Tab: the last one focused, while it is still there.\n const first = inReadingOrder[0];\n const tabbable =\n roving && byPosition.has(roving) ? roving : first && key(first.row, first.column);\n const [hover, setHover] = useState<Tip>();\n const [focus, setFocus] = useState<Tip>();\n const tip = hover ?? focus;\n\n const tipFor = (cell: HeatCell, element: HTMLElement): Tip => {\n const host = (frame.current as HTMLElement).getBoundingClientRect();\n const box = element.getBoundingClientRect();\n const middle = box.left - host.left + box.width / 2;\n // The card hangs from the side of the cell nearest the middle of the grid,\n // so it never leaves the grid.\n const align =\n middle < host.width / 3 ? 'start' : middle > (2 * host.width) / 3 ? 'end' : 'center';\n return {\n cell,\n x: { start: box.left - host.left, center: middle, end: box.right - host.left }[align],\n top: box.top - host.top,\n bottom: box.bottom - host.top,\n align,\n // Not enough room above the cell for the card: it goes under.\n below: box.top - host.top < 90,\n };\n };\n\n const move = (event: KeyboardEvent<HTMLDivElement>) => {\n const origin = (event.target as HTMLElement).closest<HTMLElement>('[data-heat-cell]');\n if (!origin) return;\n const row = Number(origin.dataset.row);\n const column = Number(origin.dataset.column);\n // The next cell in a direction: empty slots are skipped, the edge stops.\n const step = (dRow: number, dColumn: number) => {\n for (\n let r = row + dRow, c = column + dColumn;\n r >= 0 && r < rows.length && c >= 0 && c < columns.length;\n r += dRow, c += dColumn\n ) {\n if (byPosition.has(key(r, c))) return key(r, c);\n }\n };\n const edge = (last: boolean) => {\n const pool = event.ctrlKey\n ? inReadingOrder\n : inReadingOrder.filter((cell) => cell.row === row);\n const cell = last ? pool.at(-1) : pool[0];\n return cell && key(cell.row, cell.column);\n };\n const targets: Record<string, () => string | undefined> = {\n ArrowRight: () => step(0, 1),\n ArrowLeft: () => step(0, -1),\n ArrowDown: () => step(1, 0),\n ArrowUp: () => step(-1, 0),\n Home: () => edge(false),\n End: () => edge(true),\n };\n const target = targets[event.key];\n if (!target) return;\n event.preventDefault();\n const next = target();\n if (next) gridRef.current?.querySelector<HTMLElement>(`[data-position=\"${next}\"]`)?.focus();\n };\n\n const focusIn = (cell: HeatCell, event: FocusEvent<HTMLElement>) => {\n setRoving(key(cell.row, cell.column));\n // A click focuses a cell too, and would leave its tooltip up: only the keyboard shows it.\n if (event.currentTarget.matches(':focus-visible')) {\n setFocus(tipFor(cell, event.currentTarget));\n }\n };\n const focusOut = (event: FocusEvent<HTMLDivElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget)) setFocus(undefined);\n };\n\n const rowOffset = yTitle ? 2 : 1;\n // The rows start under the labels when these sit above them.\n const top = labelsAbove ? 1 : 0;\n const labelsRow = labelsAbove ? 1 : rows.length + 1;\n const tipStyle: CSSProperties | undefined = tip && {\n position: 'absolute',\n left: tip.x,\n top: tip.below ? tip.bottom + TIP_GAP : tip.top - TIP_GAP,\n transform: `translate(${{ start: '0', center: '-50%', end: '-100%' }[tip.align]}, ${tip.below ? '0' : '-100%'})`,\n zIndex: 10,\n pointerEvents: 'none',\n };\n\n const grid = (\n <div\n ref={gridRef}\n role=\"grid\"\n aria-label={ariaLabel}\n onKeyDown={move}\n onBlur={focusOut}\n style={{\n display: 'grid',\n gridTemplateColumns: `${yTitle ? 'auto ' : ''}${columnWidth ? 'auto' : 'fit-content(40%)'} repeat(${columns.length}, ${columnWidth ? `${columnWidth}px` : 'minmax(0, 1fr)'})`,\n gridTemplateRows: `${labelsAbove ? 'auto ' : ''}repeat(${rows.length}, ${cellHeight ? `${cellHeight}px` : 'minmax(0, 1fr)'})${labelsAbove ? '' : ' auto'}${xTitle ? ' auto' : ''}`,\n gap,\n width: columnWidth ? 'max-content' : '100%',\n height: cellHeight ? undefined : '100%',\n fontSize: TEXT_SIZE,\n color: MUTED,\n }}\n >\n {yTitle && (\n <div\n aria-hidden\n style={{\n gridRow: `${1 + top} / ${rows.length + 1 + top}`,\n gridColumn: 1,\n writingMode: 'vertical-rl',\n transform: 'rotate(180deg)',\n textAlign: 'center',\n alignSelf: 'center',\n }}\n >\n {yTitle}\n </div>\n )}\n {rows.map((name, r) => (\n <div key={r} role=\"row\" style={{ display: 'contents' }}>\n <div\n aria-hidden\n data-heat-row=\"\"\n style={{\n gridRow: r + 1 + top,\n gridColumn: rowOffset,\n alignSelf: 'center',\n paddingRight: '0.5rem',\n // Stays in view when the grid scrolls sideways under it.\n ...(columnWidth ? { position: 'sticky', left: 0, zIndex: 2, background: PANEL } : {}),\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {name}\n </div>\n {(cellsByRow.get(r) ?? []).map((cell) => {\n const position = key(cell.row, cell.column);\n const active = tip?.cell === cell;\n return (\n <div\n key={position}\n role=\"gridcell\"\n data-heat-cell=\"\"\n data-position={position}\n data-row={cell.row}\n data-column={cell.column}\n tabIndex={position === tabbable ? 0 : -1}\n aria-label={`${cell.label ? `${cell.label}, ` : ''}${cell.title}: ${cell.value}`}\n onFocus={(event) => focusIn(cell, event)}\n onMouseEnter={(event) => setHover(tipFor(cell, event.currentTarget))}\n onMouseLeave={() => setHover(undefined)}\n style={{\n gridRow: r + 1 + top,\n gridColumn: cell.column + rowOffset + 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: 0,\n overflow: 'hidden',\n borderRadius: cellRadius,\n background: cell.color,\n color: textOn(cell.color),\n fontSize: 'var(--text-2xs, 0.6875rem)',\n fontWeight: 500,\n lineHeight: 1,\n whiteSpace: 'nowrap',\n // The same ring for the pointer and the keyboard, in the text color\n // since an accent ring would vanish on the cells that are the accent.\n outline: active ? `2px solid ${TEXT}` : 'none',\n zIndex: active ? 1 : undefined,\n }}\n >\n {cell.text}\n </div>\n );\n })}\n </div>\n ))}\n {columns.map((name, c) => (\n <div\n key={c}\n ref={c === 0 ? columnRef : undefined}\n aria-hidden\n data-heat-column=\"\"\n style={{\n gridRow: labelsRow,\n gridColumn: c + rowOffset + 1,\n display: 'flex',\n justifyContent: thinLabels ? 'center' : 'flex-start',\n whiteSpace: 'nowrap',\n minWidth: 0,\n }}\n >\n {c % stride === 0 ? name : null}\n </div>\n ))}\n {xTitle && (\n <div\n aria-hidden\n style={{\n gridRow: (labelsAbove ? rows.length + 1 : labelsRow) + 1,\n gridColumn: `${rowOffset + 1} / -1`,\n textAlign: 'center',\n }}\n >\n {xTitle}\n </div>\n )}\n <span\n ref={probeRef}\n aria-hidden\n style={{ position: 'absolute', visibility: 'hidden', whiteSpace: 'nowrap' }}\n >\n {longest}\n </span>\n </div>\n );\n\n return (\n <div ref={frame} style={{ position: 'relative', width: '100%', height: '100%', minWidth: 0 }}>\n {columnWidth ? (\n // The padding leaves room for the focus outline of the cells at the edges,\n // which the scrolling box would cut.\n <div data-heat-scroll=\"\" style={{ overflowX: 'auto', padding: 3 }}>\n {grid}\n </div>\n ) : (\n grid\n )}\n {tip && tipStyle && (\n <div data-heat-tooltip=\"\" aria-hidden style={tipStyle}>\n <TooltipCard\n title={tip.cell.title}\n rows={[{ name: tip.cell.label, value: tip.cell.value, color: tip.cell.color }]}\n />\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// src/core/animation.ts
|
|
5
|
+
var ANIMATION = {
|
|
6
|
+
isAnimationActive: "auto",
|
|
7
|
+
animationDuration: 500,
|
|
8
|
+
animationEasing: "ease-out"
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
exports.ANIMATION = ANIMATION;
|
|
12
|
+
//# sourceMappingURL=chunk-TYQWZR3S.cjs.map
|
|
13
|
+
//# sourceMappingURL=chunk-TYQWZR3S.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/animation.ts"],"names":[],"mappings":";;;;AAIO,IAAM,SAAA,GAAY;AAAA,EACvB,iBAAA,EAAmB,MAAA;AAAA,EACnB,iBAAA,EAAmB,GAAA;AAAA,EACnB,eAAA,EAAiB;AACnB","file":"chunk-TYQWZR3S.cjs","sourcesContent":["/**\n * The animation of every series: short, ease-out. `'auto'` is off for\n * `prefers-reduced-motion` and in SSR.\n */\nexport const ANIMATION = {\n isAnimationActive: 'auto' as const,\n animationDuration: 500,\n animationEasing: 'ease-out' as const,\n};\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/core/colors.ts
|
|
3
|
+
var token = (name, fallback) => `var(${name}, ${fallback})`;
|
|
4
|
+
var SERIES_FALLBACKS = [
|
|
5
|
+
"#465fff",
|
|
6
|
+
"#06b6d4",
|
|
7
|
+
"#8b5cf6",
|
|
8
|
+
"#ec4899",
|
|
9
|
+
"#64748b",
|
|
10
|
+
"#f97316",
|
|
11
|
+
"#14b8a6",
|
|
12
|
+
"#84cc16"
|
|
13
|
+
];
|
|
14
|
+
var SERIES_TOKENS = [
|
|
15
|
+
"--color-brand-500",
|
|
16
|
+
...SERIES_FALLBACKS.slice(1).map((_, i) => `--color-chart-${i + 2}`)
|
|
17
|
+
];
|
|
18
|
+
var SERIES = SERIES_TOKENS.map((name, i) => token(name, SERIES_FALLBACKS[i]));
|
|
19
|
+
var seriesColor = (index, colors) => colors?.length ? colors[index % colors.length] : SERIES[index % SERIES.length];
|
|
20
|
+
var SUCCESS = token("--color-success-500", "#12b76a");
|
|
21
|
+
var ERROR = token("--color-error-500", "#f04438");
|
|
22
|
+
var STATUS_WARN = token("--color-status-warn", "#f59e0b");
|
|
23
|
+
var STATUS_CRIT = token("--color-status-crit", "#ef4444");
|
|
24
|
+
var PANEL = token("--color-bg-panel", "#fff");
|
|
25
|
+
var TEXT = token("--color-text-primary", "#101828");
|
|
26
|
+
var MUTED = token("--color-text-muted", "#677185");
|
|
27
|
+
var BORDER = token("--color-border", "#d0d5dd");
|
|
28
|
+
var GRID = `color-mix(in srgb, ${BORDER} 55%, transparent)`;
|
|
29
|
+
var TRACK = `color-mix(in srgb, ${BORDER} 70%, transparent)`;
|
|
30
|
+
var INTENT_COLORS = {
|
|
31
|
+
neutral: MUTED,
|
|
32
|
+
warning: STATUS_WARN,
|
|
33
|
+
danger: STATUS_CRIT,
|
|
34
|
+
success: SUCCESS
|
|
35
|
+
};
|
|
36
|
+
var SEQUENTIAL = [42, 56, 70, 84, 100].map(
|
|
37
|
+
(share) => `color-mix(in oklab, ${SERIES[0]} ${share}%, ${PANEL})`
|
|
38
|
+
);
|
|
39
|
+
var calendarStep = (index, share) => `color-mix(in oklab, ${SERIES[0]} calc(var(--calendar-share-${index}, ${share}) * 1%), ${PANEL})`;
|
|
40
|
+
var CALENDAR_STEPS = [
|
|
41
|
+
TRACK,
|
|
42
|
+
calendarStep(1, 48),
|
|
43
|
+
calendarStep(2, 65),
|
|
44
|
+
calendarStep(3, 82),
|
|
45
|
+
`var(--calendar-top, ${SERIES[0]})`
|
|
46
|
+
];
|
|
47
|
+
var CALENDAR_DARK_CLASS = "dark:[--calendar-share-1:50] dark:[--calendar-share-2:70] dark:[--calendar-share-3:100] dark:[--calendar-top:var(--color-brand-400)]";
|
|
48
|
+
|
|
49
|
+
export { BORDER, CALENDAR_DARK_CLASS, CALENDAR_STEPS, ERROR, GRID, INTENT_COLORS, MUTED, PANEL, SEQUENTIAL, SERIES, STATUS_CRIT, STATUS_WARN, SUCCESS, TEXT, TRACK, seriesColor };
|
|
50
|
+
//# sourceMappingURL=chunk-UATB2IRY.js.map
|
|
51
|
+
//# sourceMappingURL=chunk-UATB2IRY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/colors.ts"],"names":[],"mappings":";;AASA,IAAM,QAAQ,CAAC,IAAA,EAAc,aAAqB,CAAA,IAAA,EAAO,IAAI,KAAK,QAAQ,CAAA,CAAA,CAAA;AAGnE,IAAM,gBAAA,GAAmB;AAAA,EAC9B,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,aAAA,GAAgB;AAAA,EACpB,mBAAA;AAAA,EACA,GAAG,gBAAA,CAAiB,KAAA,CAAM,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,cAAA,EAAiB,CAAA,GAAI,CAAC,CAAA,CAAE;AACrE,CAAA;AAOO,IAAM,MAAA,GAAS,aAAA,CAAc,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM,KAAA,CAAM,IAAA,EAAM,gBAAA,CAAiB,CAAC,CAAC,CAAC;AAG9E,IAAM,WAAA,GAAc,CAAC,KAAA,EAAe,MAAA,KACzC,QAAQ,MAAA,GAAS,MAAA,CAAO,KAAA,GAAQ,MAAA,CAAO,MAAM,CAAA,GAAI,MAAA,CAAO,KAAA,GAAQ,OAAO,MAAM;AAGxE,IAAM,OAAA,GAAU,KAAA,CAAM,qBAAA,EAAuB,SAAS;AAEtD,IAAM,KAAA,GAAQ,KAAA,CAAM,mBAAA,EAAqB,SAAS;AAElD,IAAM,WAAA,GAAc,KAAA,CAAM,qBAAA,EAAuB,SAAS;AAC1D,IAAM,WAAA,GAAc,KAAA,CAAM,qBAAA,EAAuB,SAAS;AAG1D,IAAM,KAAA,GAAQ,KAAA,CAAM,kBAAA,EAAoB,MAAM;AAC9C,IAAM,IAAA,GAAO,KAAA,CAAM,sBAAA,EAAwB,SAAS;AACpD,IAAM,KAAA,GAAQ,KAAA,CAAM,oBAAA,EAAsB,SAAS;AACnD,IAAM,MAAA,GAAS,KAAA,CAAM,gBAAA,EAAkB,SAAS;AAGhD,IAAM,IAAA,GAAO,sBAAsB,MAAM,CAAA,kBAAA;AACzC,IAAM,KAAA,GAAQ,sBAAsB,MAAM,CAAA,kBAAA;AAG1C,IAAM,aAAA,GAA6C;AAAA,EACxD,OAAA,EAAS,KAAA;AAAA,EACT,OAAA,EAAS,WAAA;AAAA,EACT,MAAA,EAAQ,WAAA;AAAA,EACR,OAAA,EAAS;AACX;AASO,IAAM,aAAa,CAAC,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,GAAG,CAAA,CAAE,GAAA;AAAA,EAC9C,CAAC,UAAU,CAAA,oBAAA,EAAuB,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA,EAAI,KAAK,CAAA,GAAA,EAAM,KAAK,CAAA,CAAA;AACjE;AAKA,IAAM,YAAA,GAAe,CAAC,KAAA,EAAe,KAAA,KACnC,CAAA,oBAAA,EAAuB,MAAA,CAAO,CAAC,CAAC,CAAA,2BAAA,EAA8B,KAAK,CAAA,EAAA,EAAK,KAAK,YAAY,KAAK,CAAA,CAAA,CAAA;AAUzF,IAAM,cAAA,GAAiB;AAAA,EAC5B,KAAA;AAAA,EACA,YAAA,CAAa,GAAG,EAAE,CAAA;AAAA,EAClB,YAAA,CAAa,GAAG,EAAE,CAAA;AAAA,EAClB,YAAA,CAAa,GAAG,EAAE,CAAA;AAAA,EAClB,CAAA,oBAAA,EAAuB,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAClC;AAGO,IAAM,mBAAA,GACX","file":"chunk-UATB2IRY.js","sourcesContent":["import type { ChartIntent } from '../types';\n\n// The colors every Recharts-based chart draws with. Each one is a CSS variable\n// string handed straight to the SVG (`fill`, `stroke`, `stopColor`, `cursor`):\n// a theme, accent or text size switch on <html> repaints the chart with no\n// observer and no `getComputedStyle`. The hex after the comma is the fallback\n// when the theme CSS isn't loaded or during SSR; with the theme it is never\n// used, since `@sckyzo/cosmos-theme` always emits these variables.\n\nconst token = (name: string, fallback: string) => `var(${name}, ${fallback})`;\n\n/** The hex of each series color in the default theme, series 1 first: the blue accent, then the hues of `--color-chart-2` to `--color-chart-8`. */\nexport const SERIES_FALLBACKS = [\n '#465fff',\n '#06b6d4',\n '#8b5cf6',\n '#ec4899',\n '#64748b',\n '#f97316',\n '#14b8a6',\n '#84cc16',\n];\n\nconst SERIES_TOKENS = [\n '--color-brand-500',\n ...SERIES_FALLBACKS.slice(1).map((_, i) => `--color-chart-${i + 2}`),\n];\n\n/**\n * The categorical palette: the accent, then seven hues. Which hues is decided\n * in the theme CSS: each accent skips the ones that look like it. None of the\n * first four reads as a status (green, amber, red).\n */\nexport const SERIES = SERIES_TOKENS.map((name, i) => token(name, SERIES_FALLBACKS[i]));\n\n/** The color of series `index`: `colors[index]` when given (cycling), the palette otherwise. */\nexport const seriesColor = (index: number, colors?: readonly string[]): string =>\n colors?.length ? colors[index % colors.length] : SERIES[index % SERIES.length];\n\n// A chart whose series are statuses passes these as `colors`.\nexport const SUCCESS = token('--color-success-500', '#12b76a');\nexport const WARNING = token('--color-warning-500', '#f79009');\nexport const ERROR = token('--color-error-500', '#f04438');\n/** The monitoring statuses, for thresholds. */\nexport const STATUS_WARN = token('--color-status-warn', '#f59e0b');\nexport const STATUS_CRIT = token('--color-status-crit', '#ef4444');\n\n/** The card the chart sits on. */\nexport const PANEL = token('--color-bg-panel', '#fff');\nexport const TEXT = token('--color-text-primary', '#101828');\nexport const MUTED = token('--color-text-muted', '#677185');\nexport const BORDER = token('--color-border', '#d0d5dd');\n// One semantic border variable reads right on every theme; the grid and the\n// empty part of a gauge are lighter steps of it.\nexport const GRID = `color-mix(in srgb, ${BORDER} 55%, transparent)`;\nexport const TRACK = `color-mix(in srgb, ${BORDER} 70%, transparent)`;\n\n/** The color of a reference line or band by its meaning: muted text for `neutral`, the status colors otherwise. */\nexport const INTENT_COLORS: Record<ChartIntent, string> = {\n neutral: MUTED,\n warning: STATUS_WARN,\n danger: STATUS_CRIT,\n success: SUCCESS,\n};\n\n/**\n * Five sequential steps of the accent over the card, low to high, on any\n * theme. Mixed in OKLab, which spaces the steps evenly to the eye: against the\n * card, the lowest step stays at 1.5:1 or more in the dark themes whatever the\n * accent (where a 24% share sat at 1.2:1), and two neighbors differ by 1.19:1\n * or more.\n */\nexport const SEQUENTIAL = [42, 56, 70, 84, 100].map(\n (share) => `color-mix(in oklab, ${SERIES[0]} ${share}%, ${PANEL})`\n);\n\n// A calendar step: a share of the accent over the card. The shares and the top\n// step are variables so that the dark themes can set their own on the chart's\n// root (`CalendarChart`); the fallbacks are the light themes' values.\nconst calendarStep = (index: number, share: number) =>\n `color-mix(in oklab, ${SERIES[0]} calc(var(--calendar-share-${index}, ${share}) * 1%), ${PANEL})`;\n\n/**\n * Five steps for a calendar of days: the neutral track for a day with no\n * value, then four of the accent. A day without activity is a cell of its own,\n * not a hole, and the four steps stay apart on any theme and accent. In the\n * light themes they are 48, 65, 82 and 100% of the accent over the card; the\n * dark themes set lower shares and a light accent for the top step through\n * `--calendar-share-1` to `-3` and `--calendar-top`.\n */\nexport const CALENDAR_STEPS = [\n TRACK,\n calendarStep(1, 48),\n calendarStep(2, 65),\n calendarStep(3, 82),\n `var(--calendar-top, ${SERIES[0]})`,\n];\n\n/** Sets the dark themes' calendar scale on the chart's root: Tailwind's `dark:` covers both of them. */\nexport const CALENDAR_DARK_CLASS =\n 'dark:[--calendar-share-1:50] dark:[--calendar-share-2:70] dark:[--calendar-share-3:100] dark:[--calendar-top:var(--color-brand-400)]';\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/core/data.ts
|
|
3
|
+
var seriesKey = (index) => `s${index}`;
|
|
4
|
+
var toRows = (categories, series) => categories.map((category, i) => ({
|
|
5
|
+
category,
|
|
6
|
+
...Object.fromEntries(series.map((s, k) => [seriesKey(k), s.data[i]]))
|
|
7
|
+
}));
|
|
8
|
+
var hasNoData = (series) => series.every((s) => s.data.length === 0);
|
|
9
|
+
var safeId = (id) => id.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
10
|
+
|
|
11
|
+
export { hasNoData, safeId, seriesKey, toRows };
|
|
12
|
+
//# sourceMappingURL=chunk-UJIV5PVI.js.map
|
|
13
|
+
//# sourceMappingURL=chunk-UJIV5PVI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/data.ts"],"names":[],"mappings":";;AAGO,IAAM,SAAA,GAAY,CAAC,KAAA,KAAkB,CAAA,CAAA,EAAI,KAAK,CAAA;AAG9C,IAAM,MAAA,GAAS,CAAC,UAAA,EAA0C,MAAA,KAC/D,WAAW,GAAA,CAAI,CAAC,UAAU,CAAA,MAAO;AAAA,EAC/B,QAAA;AAAA,EACA,GAAG,MAAA,CAAO,WAAA,CAAY,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,CAAC,SAAA,CAAU,CAAC,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACvE,CAAA,CAAE;AAGG,IAAM,SAAA,GAAY,CAAC,MAAA,KACxB,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,MAAA,KAAW,CAAC;AAGlC,IAAM,SAAS,CAAC,EAAA,KAAe,EAAA,CAAG,OAAA,CAAQ,mBAAmB,EAAE","file":"chunk-UJIV5PVI.js","sourcesContent":["export type SeriesInput = { name: string; data: number[] };\n\n/** The data key of series `index`. Series are keyed by position: a name may hold dots, which Recharts reads as a path. */\nexport const seriesKey = (index: number) => `s${index}`;\n\n/** One row per category, with a value under each series key. */\nexport const toRows = (categories: readonly (string | number)[], series: readonly SeriesInput[]) =>\n categories.map((category, i) => ({\n category,\n ...Object.fromEntries(series.map((s, k) => [seriesKey(k), s.data[i]])),\n }));\n\n/** Whether there is nothing to draw: no series, or only series without a point. */\nexport const hasNoData = (series: readonly { data: readonly unknown[] }[]): boolean =>\n series.every((s) => s.data.length === 0);\n\n/** An id safe in `url(#…)`, from React's `useId` (`:r1:`). */\nexport const safeId = (id: string) => id.replace(/[^a-zA-Z0-9_-]/g, '');\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { TEXT, MUTED } from './chunk-UATB2IRY.js';
|
|
3
|
+
import { usePlotArea } from 'recharts';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var CenterText = ({
|
|
7
|
+
value,
|
|
8
|
+
label,
|
|
9
|
+
valueSize = "var(--text-2xl, 1.5rem)"
|
|
10
|
+
}) => {
|
|
11
|
+
const area = usePlotArea();
|
|
12
|
+
if (!area) return null;
|
|
13
|
+
const cx = area.x + area.width / 2;
|
|
14
|
+
const cy = area.y + area.height / 2;
|
|
15
|
+
return /* @__PURE__ */ jsxs(
|
|
16
|
+
"text",
|
|
17
|
+
{
|
|
18
|
+
"data-chart-center": "",
|
|
19
|
+
x: cx,
|
|
20
|
+
y: cy,
|
|
21
|
+
textAnchor: "middle",
|
|
22
|
+
dominantBaseline: "central",
|
|
23
|
+
pointerEvents: "none",
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsx(
|
|
26
|
+
"tspan",
|
|
27
|
+
{
|
|
28
|
+
x: cx,
|
|
29
|
+
dy: label ? "-0.35em" : 0,
|
|
30
|
+
fill: TEXT,
|
|
31
|
+
fontWeight: 700,
|
|
32
|
+
style: { fontSize: valueSize },
|
|
33
|
+
children: value
|
|
34
|
+
}
|
|
35
|
+
),
|
|
36
|
+
label && /* @__PURE__ */ jsx("tspan", { x: cx, dy: "1.9em", fill: MUTED, style: { fontSize: "var(--text-xs, 0.75rem)" }, children: label })
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { CenterText };
|
|
43
|
+
//# sourceMappingURL=chunk-URNXLVSK.js.map
|
|
44
|
+
//# sourceMappingURL=chunk-URNXLVSK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/radial.tsx"],"names":[],"mappings":";;;;;AASO,IAAM,aAAa,CAAC;AAAA,EACzB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,KAKM;AACJ,EAAA,MAAM,OAAO,WAAA,EAAY;AACzB,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,CAAA;AACjC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,CAAA;AAClC,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,mBAAA,EAAkB,EAAA;AAAA,MAClB,CAAA,EAAG,EAAA;AAAA,MACH,CAAA,EAAG,EAAA;AAAA,MACH,UAAA,EAAW,QAAA;AAAA,MACX,gBAAA,EAAiB,SAAA;AAAA,MACjB,aAAA,EAAc,MAAA;AAAA,MAEd,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAG,EAAA;AAAA,YACH,EAAA,EAAI,QAAQ,SAAA,GAAY,CAAA;AAAA,YACxB,IAAA,EAAM,IAAA;AAAA,YACN,UAAA,EAAY,GAAA;AAAA,YACZ,KAAA,EAAO,EAAE,QAAA,EAAU,SAAA,EAAU;AAAA,YAE5B,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QACC,KAAA,oBACC,GAAA,CAAC,OAAA,EAAA,EAAM,CAAA,EAAG,IAAI,EAAA,EAAG,OAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,EAAE,QAAA,EAAU,yBAAA,IACtD,QAAA,EAAA,KAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ","file":"chunk-URNXLVSK.js","sourcesContent":["import { usePlotArea } from 'recharts';\nimport { MUTED, TEXT } from './colors';\n\n/**\n * The value, and under it a smaller label, drawn as SVG text in the middle of\n * the plot area of a polar chart. The plot area is what the legend leaves, so\n * the text stays in the middle of the rings on any `legendPosition`. Plain\n * text: markup in `value` or `label` shows as written.\n */\nexport const CenterText = ({\n value,\n label,\n valueSize = 'var(--text-2xl, 1.5rem)',\n}: {\n value: string;\n label?: string;\n /** A CSS font size, from the text tokens. */\n valueSize?: string;\n}) => {\n const area = usePlotArea();\n if (!area) return null;\n const cx = area.x + area.width / 2;\n const cy = area.y + area.height / 2;\n return (\n <text\n data-chart-center=\"\"\n x={cx}\n y={cy}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n pointerEvents=\"none\"\n >\n <tspan\n x={cx}\n dy={label ? '-0.35em' : 0}\n fill={TEXT}\n fontWeight={700}\n style={{ fontSize: valueSize }}\n >\n {value}\n </tspan>\n {label && (\n <tspan x={cx} dy=\"1.9em\" fill={MUTED} style={{ fontSize: 'var(--text-xs, 0.75rem)' }}>\n {label}\n </tspan>\n )}\n </text>\n );\n};\n"]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { BORDER, PANEL, TEXT, MUTED } from './chunk-UATB2IRY.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var card = {
|
|
6
|
+
minWidth: "9rem",
|
|
7
|
+
padding: "0.625rem 0.75rem",
|
|
8
|
+
fontSize: "var(--text-xs, 0.75rem)",
|
|
9
|
+
color: TEXT,
|
|
10
|
+
background: PANEL,
|
|
11
|
+
border: `1px solid ${BORDER}`,
|
|
12
|
+
borderRadius: "var(--radius-xl, 0.75rem)",
|
|
13
|
+
boxShadow: "var(--shadow-theme-md, 0 4px 8px -2px rgb(16 24 40 / 10%))"
|
|
14
|
+
};
|
|
15
|
+
var TooltipCard = ({ title, rows }) => /* @__PURE__ */ jsxs("div", { role: "status", "aria-live": "polite", style: card, children: [
|
|
16
|
+
title !== void 0 && title !== "" && /* @__PURE__ */ jsx("p", { style: { margin: "0 0 0.375rem", fontWeight: 600 }, children: title }),
|
|
17
|
+
/* @__PURE__ */ jsx(
|
|
18
|
+
"ul",
|
|
19
|
+
{
|
|
20
|
+
style: {
|
|
21
|
+
display: "flex",
|
|
22
|
+
flexDirection: "column",
|
|
23
|
+
gap: "0.25rem",
|
|
24
|
+
margin: 0,
|
|
25
|
+
padding: 0,
|
|
26
|
+
listStyle: "none"
|
|
27
|
+
},
|
|
28
|
+
children: rows.map((row, i) => /* @__PURE__ */ jsxs("li", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
29
|
+
/* @__PURE__ */ jsx(
|
|
30
|
+
"span",
|
|
31
|
+
{
|
|
32
|
+
"aria-hidden": true,
|
|
33
|
+
style: {
|
|
34
|
+
flexShrink: 0,
|
|
35
|
+
width: "0.625rem",
|
|
36
|
+
height: "0.625rem",
|
|
37
|
+
borderRadius: "50%",
|
|
38
|
+
background: row.color
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ jsx("span", { style: { color: MUTED }, children: row.name }),
|
|
43
|
+
/* @__PURE__ */ jsx(
|
|
44
|
+
"span",
|
|
45
|
+
{
|
|
46
|
+
style: {
|
|
47
|
+
marginLeft: "auto",
|
|
48
|
+
paddingLeft: "1rem",
|
|
49
|
+
fontWeight: 600,
|
|
50
|
+
fontVariantNumeric: "tabular-nums"
|
|
51
|
+
},
|
|
52
|
+
children: row.value
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
] }, i))
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
] });
|
|
59
|
+
var ChartTooltip = ({
|
|
60
|
+
active,
|
|
61
|
+
payload,
|
|
62
|
+
label,
|
|
63
|
+
format = String,
|
|
64
|
+
hideTitle,
|
|
65
|
+
colorOf,
|
|
66
|
+
activeIndex
|
|
67
|
+
}) => {
|
|
68
|
+
if (!active || !payload?.length) return null;
|
|
69
|
+
const rows = payload.map((item) => ({
|
|
70
|
+
name: String(item.name),
|
|
71
|
+
value: format(Number(item.value)),
|
|
72
|
+
color: colorOf?.(Number(item.value), Number(activeIndex)) ?? String(item.color ?? item.payload?.fill ?? item.fill)
|
|
73
|
+
}));
|
|
74
|
+
return /* @__PURE__ */ jsx(TooltipCard, { title: hideTitle ? void 0 : label, rows });
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { ChartTooltip, TooltipCard };
|
|
78
|
+
//# sourceMappingURL=chunk-VIOSQN4Z.js.map
|
|
79
|
+
//# sourceMappingURL=chunk-VIOSQN4Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/ChartTooltip.tsx"],"names":[],"mappings":"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","file":"chunk-VIOSQN4Z.js","sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport type { TooltipContentProps } from 'recharts';\nimport { BORDER, MUTED, PANEL, TEXT } from './colors';\n\nconst card: CSSProperties = {\n minWidth: '9rem',\n padding: '0.625rem 0.75rem',\n fontSize: 'var(--text-xs, 0.75rem)',\n color: TEXT,\n background: PANEL,\n border: `1px solid ${BORDER}`,\n borderRadius: 'var(--radius-xl, 0.75rem)',\n boxShadow: 'var(--shadow-theme-md, 0 4px 8px -2px rgb(16 24 40 / 10%))',\n};\n\n/** A tooltip row: a chip, a name, a value. */\nexport type TooltipRow = { name: string; value: ReactNode; color: string };\n\n/**\n * The tooltip card of every chart. A polite live region, as Recharts\n * recommends for a custom tooltip, so a screen reader announces the point the\n * keyboard or the pointer is on. Every part is React text: markup in a name or\n * a value shows as written.\n */\nexport const TooltipCard = ({ title, rows }: { title?: ReactNode; rows: TooltipRow[] }) => (\n <div role=\"status\" aria-live=\"polite\" style={card}>\n {title !== undefined && title !== '' && (\n <p style={{ margin: '0 0 0.375rem', fontWeight: 600 }}>{title}</p>\n )}\n <ul\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.25rem',\n margin: 0,\n padding: 0,\n listStyle: 'none',\n }}\n >\n {rows.map((row, i) => (\n <li key={i} style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <span\n aria-hidden\n style={{\n flexShrink: 0,\n width: '0.625rem',\n height: '0.625rem',\n borderRadius: '50%',\n background: row.color,\n }}\n />\n <span style={{ color: MUTED }}>{row.name}</span>\n <span\n style={{\n marginLeft: 'auto',\n paddingLeft: '1rem',\n fontWeight: 600,\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {row.value}\n </span>\n </li>\n ))}\n </ul>\n </div>\n);\n\ntype ChartTooltipProps = Partial<TooltipContentProps> & {\n /** Formats each value (default `String`). */\n format?: (value: number) => string;\n /** Leave out the title (the category), for a chart that has no axis to read it from. */\n hideTitle?: boolean;\n /** The color of a row's chip from its value and the index of the point, when a bar has a color of its own. `undefined` keeps the series color. */\n colorOf?: (value: number, index: number) => string | undefined;\n};\n\n/** `<Tooltip content={<ChartTooltip />} />`: the card for the series at the point under the cursor. */\nexport const ChartTooltip = ({\n active,\n payload,\n label,\n format = String,\n hideTitle,\n colorOf,\n activeIndex,\n}: ChartTooltipProps) => {\n if (!active || !payload?.length) return null;\n const rows = payload.map((item) => ({\n name: String(item.name),\n value: format(Number(item.value)),\n color:\n colorOf?.(Number(item.value), Number(activeIndex)) ??\n String(item.color ?? item.payload?.fill ?? item.fill),\n }));\n return <TooltipCard title={hideTitle ? undefined : label} rows={rows} />;\n};\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
5
|
+
var recharts = require('recharts');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
var CenterText = ({
|
|
9
|
+
value,
|
|
10
|
+
label,
|
|
11
|
+
valueSize = "var(--text-2xl, 1.5rem)"
|
|
12
|
+
}) => {
|
|
13
|
+
const area = recharts.usePlotArea();
|
|
14
|
+
if (!area) return null;
|
|
15
|
+
const cx = area.x + area.width / 2;
|
|
16
|
+
const cy = area.y + area.height / 2;
|
|
17
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18
|
+
"text",
|
|
19
|
+
{
|
|
20
|
+
"data-chart-center": "",
|
|
21
|
+
x: cx,
|
|
22
|
+
y: cy,
|
|
23
|
+
textAnchor: "middle",
|
|
24
|
+
dominantBaseline: "central",
|
|
25
|
+
pointerEvents: "none",
|
|
26
|
+
children: [
|
|
27
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28
|
+
"tspan",
|
|
29
|
+
{
|
|
30
|
+
x: cx,
|
|
31
|
+
dy: label ? "-0.35em" : 0,
|
|
32
|
+
fill: chunkLT3UC65O_cjs.TEXT,
|
|
33
|
+
fontWeight: 700,
|
|
34
|
+
style: { fontSize: valueSize },
|
|
35
|
+
children: value
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("tspan", { x: cx, dy: "1.9em", fill: chunkLT3UC65O_cjs.MUTED, style: { fontSize: "var(--text-xs, 0.75rem)" }, children: label })
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
exports.CenterText = CenterText;
|
|
45
|
+
//# sourceMappingURL=chunk-X3YZP5WF.cjs.map
|
|
46
|
+
//# sourceMappingURL=chunk-X3YZP5WF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/radial.tsx"],"names":["usePlotArea","jsxs","jsx","TEXT","MUTED"],"mappings":";;;;;;;AASO,IAAM,aAAa,CAAC;AAAA,EACzB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,KAKM;AACJ,EAAA,MAAM,OAAOA,oBAAA,EAAY;AACzB,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,CAAA;AACjC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,CAAA;AAClC,EAAA,uBACEC,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,mBAAA,EAAkB,EAAA;AAAA,MAClB,CAAA,EAAG,EAAA;AAAA,MACH,CAAA,EAAG,EAAA;AAAA,MACH,UAAA,EAAW,QAAA;AAAA,MACX,gBAAA,EAAiB,SAAA;AAAA,MACjB,aAAA,EAAc,MAAA;AAAA,MAEd,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAG,EAAA;AAAA,YACH,EAAA,EAAI,QAAQ,SAAA,GAAY,CAAA;AAAA,YACxB,IAAA,EAAMC,sBAAA;AAAA,YACN,UAAA,EAAY,GAAA;AAAA,YACZ,KAAA,EAAO,EAAE,QAAA,EAAU,SAAA,EAAU;AAAA,YAE5B,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QACC,KAAA,oBACCD,cAAA,CAAC,OAAA,EAAA,EAAM,CAAA,EAAG,IAAI,EAAA,EAAG,OAAA,EAAQ,IAAA,EAAME,uBAAA,EAAO,KAAA,EAAO,EAAE,QAAA,EAAU,yBAAA,IACtD,QAAA,EAAA,KAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ","file":"chunk-X3YZP5WF.cjs","sourcesContent":["import { usePlotArea } from 'recharts';\nimport { MUTED, TEXT } from './colors';\n\n/**\n * The value, and under it a smaller label, drawn as SVG text in the middle of\n * the plot area of a polar chart. The plot area is what the legend leaves, so\n * the text stays in the middle of the rings on any `legendPosition`. Plain\n * text: markup in `value` or `label` shows as written.\n */\nexport const CenterText = ({\n value,\n label,\n valueSize = 'var(--text-2xl, 1.5rem)',\n}: {\n value: string;\n label?: string;\n /** A CSS font size, from the text tokens. */\n valueSize?: string;\n}) => {\n const area = usePlotArea();\n if (!area) return null;\n const cx = area.x + area.width / 2;\n const cy = area.y + area.height / 2;\n return (\n <text\n data-chart-center=\"\"\n x={cx}\n y={cy}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n pointerEvents=\"none\"\n >\n <tspan\n x={cx}\n dy={label ? '-0.35em' : 0}\n fill={TEXT}\n fontWeight={700}\n style={{ fontSize: valueSize }}\n >\n {value}\n </tspan>\n {label && (\n <tspan x={cx} dy=\"1.9em\" fill={MUTED} style={{ fontSize: 'var(--text-xs, 0.75rem)' }}>\n {label}\n </tspan>\n )}\n </text>\n );\n};\n"]}
|