@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,263 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
5
|
+
var chunkDBZQI4HM_cjs = require('./chunk-DBZQI4HM.cjs');
|
|
6
|
+
var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
|
|
7
|
+
var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
|
|
8
|
+
var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
|
|
9
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
10
|
+
var react = require('react');
|
|
11
|
+
var recharts = require('recharts');
|
|
12
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
13
|
+
|
|
14
|
+
var PAD = 8;
|
|
15
|
+
var MIN_LABEL = { width: 44, height: 28 };
|
|
16
|
+
var TITLE_HEIGHT = 24;
|
|
17
|
+
var asTile = (node) => node.tile === void 0 ? void 0 : {
|
|
18
|
+
name: node.name,
|
|
19
|
+
value: node.value,
|
|
20
|
+
tile: node.tile,
|
|
21
|
+
color: node.color,
|
|
22
|
+
group: node.group
|
|
23
|
+
};
|
|
24
|
+
var ellipsis = { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" };
|
|
25
|
+
var TileView = ({
|
|
26
|
+
node,
|
|
27
|
+
titled,
|
|
28
|
+
tabbable,
|
|
29
|
+
ring,
|
|
30
|
+
showValues,
|
|
31
|
+
format,
|
|
32
|
+
onFocusTile,
|
|
33
|
+
onBlurTile
|
|
34
|
+
}) => {
|
|
35
|
+
const tile = asTile(node);
|
|
36
|
+
if (!tile) return /* @__PURE__ */ jsxRuntime.jsx("g", {});
|
|
37
|
+
const { x, y, width, height } = node;
|
|
38
|
+
const label = tile.group ? `${tile.group}, ${tile.name}` : tile.name;
|
|
39
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
40
|
+
"g",
|
|
41
|
+
{
|
|
42
|
+
"data-tile": tile.tile,
|
|
43
|
+
role: "img",
|
|
44
|
+
"aria-label": `${label}: ${format(tile.value)}`,
|
|
45
|
+
tabIndex: tabbable ? 0 : -1,
|
|
46
|
+
onFocus: (event) => onFocusTile(event, tile.tile),
|
|
47
|
+
onBlur: onBlurTile,
|
|
48
|
+
style: { outline: "none" },
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
51
|
+
"rect",
|
|
52
|
+
{
|
|
53
|
+
x,
|
|
54
|
+
y,
|
|
55
|
+
width,
|
|
56
|
+
height,
|
|
57
|
+
rx: 5,
|
|
58
|
+
fill: tile.color,
|
|
59
|
+
stroke: chunkLT3UC65O_cjs.PANEL,
|
|
60
|
+
strokeWidth: 2
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
ring && /* @__PURE__ */ jsxRuntime.jsx(
|
|
64
|
+
"rect",
|
|
65
|
+
{
|
|
66
|
+
x: x + 3,
|
|
67
|
+
y: y + 3,
|
|
68
|
+
width: Math.max(width - 6, 0),
|
|
69
|
+
height: Math.max(height - 6, 0),
|
|
70
|
+
rx: 3,
|
|
71
|
+
fill: "none",
|
|
72
|
+
stroke: chunkLT3UC65O_cjs.TEXT,
|
|
73
|
+
strokeWidth: 2,
|
|
74
|
+
pointerEvents: "none"
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
width >= MIN_LABEL.width && height >= MIN_LABEL.height + (titled ? TITLE_HEIGHT : 0) && // HTML in the SVG: the browser clips the text to the tile and sizes it
|
|
78
|
+
// with the text size setting.
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx("foreignObject", { x, y, width, height, pointerEvents: "none", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
80
|
+
"div",
|
|
81
|
+
{
|
|
82
|
+
style: {
|
|
83
|
+
boxSizing: "border-box",
|
|
84
|
+
width: "100%",
|
|
85
|
+
height: "100%",
|
|
86
|
+
padding: titled ? `${PAD + TITLE_HEIGHT}px ${PAD}px ${PAD}px` : PAD,
|
|
87
|
+
overflow: "hidden",
|
|
88
|
+
color: chunkDBZQI4HM_cjs.textOn(tile.color),
|
|
89
|
+
fontSize: "var(--text-xs, 0.75rem)",
|
|
90
|
+
lineHeight: 1.35,
|
|
91
|
+
fontWeight: 500
|
|
92
|
+
},
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: ellipsis, children: tile.name }),
|
|
95
|
+
showValues && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...ellipsis, opacity: 0.85, fontVariantNumeric: "tabular-nums" }, children: format(tile.value) })
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
) }),
|
|
99
|
+
titled && tile.group && // The name of a group, on the corner of its first tile, in the card's colors.
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
101
|
+
"foreignObject",
|
|
102
|
+
{
|
|
103
|
+
x,
|
|
104
|
+
y,
|
|
105
|
+
width: Math.min(width, 180),
|
|
106
|
+
height: TITLE_HEIGHT + 2,
|
|
107
|
+
pointerEvents: "none",
|
|
108
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
style: {
|
|
112
|
+
...ellipsis,
|
|
113
|
+
display: "inline-block",
|
|
114
|
+
maxWidth: "100%",
|
|
115
|
+
boxSizing: "border-box",
|
|
116
|
+
padding: "2px 8px",
|
|
117
|
+
color: chunkLT3UC65O_cjs.TEXT,
|
|
118
|
+
background: chunkLT3UC65O_cjs.PANEL,
|
|
119
|
+
border: `1px solid ${chunkLT3UC65O_cjs.TRACK}`,
|
|
120
|
+
borderRadius: "0 0 5px 0",
|
|
121
|
+
fontSize: "var(--text-xs, 0.75rem)",
|
|
122
|
+
fontWeight: 600,
|
|
123
|
+
lineHeight: 1.35
|
|
124
|
+
},
|
|
125
|
+
children: tile.group
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
var TreemapTooltip = ({
|
|
135
|
+
active,
|
|
136
|
+
payload,
|
|
137
|
+
format
|
|
138
|
+
}) => {
|
|
139
|
+
const tile = active && payload?.length ? asTile(payload[0].payload) : void 0;
|
|
140
|
+
if (!tile) return null;
|
|
141
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
142
|
+
chunkT3K6Q34U_cjs.TooltipCard,
|
|
143
|
+
{
|
|
144
|
+
title: tile.group,
|
|
145
|
+
rows: [{ name: tile.name, value: format(tile.value), color: tile.color }]
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
var pointerOver = (element) => element.dispatchEvent(new MouseEvent("mouseover", { bubbles: true }));
|
|
150
|
+
var pointerOut = (element) => element.dispatchEvent(new MouseEvent("mouseout", { bubbles: true }));
|
|
151
|
+
var TreemapChart = ({
|
|
152
|
+
series,
|
|
153
|
+
colors,
|
|
154
|
+
formatValue = String,
|
|
155
|
+
showValues = false,
|
|
156
|
+
emptyMessage = "No data",
|
|
157
|
+
ariaLabel,
|
|
158
|
+
children,
|
|
159
|
+
height = 320,
|
|
160
|
+
width = "100%"
|
|
161
|
+
}) => {
|
|
162
|
+
const frame = react.useRef(null);
|
|
163
|
+
const [roving, setRoving] = react.useState(0);
|
|
164
|
+
const [ringed, setRinged] = react.useState();
|
|
165
|
+
const name = ariaLabel ?? `Treemap: ${series.flatMap((s) => s.data.map((d) => d.x)).join(", ")}`;
|
|
166
|
+
const drawn = series.map((s) => ({ ...s, data: s.data.filter((d) => d.y > 0) }));
|
|
167
|
+
if (chunkK3R7JGOW_cjs.hasNoData(drawn)) {
|
|
168
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
169
|
+
}
|
|
170
|
+
const colorByName = /* @__PURE__ */ new Map();
|
|
171
|
+
for (const { data: data2 } of drawn) {
|
|
172
|
+
for (const { x } of data2) {
|
|
173
|
+
if (!colorByName.has(x)) colorByName.set(x, chunkLT3UC65O_cjs.seriesColor(colorByName.size, colors));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
let count = 0;
|
|
177
|
+
const toTile = (group) => (datum) => ({
|
|
178
|
+
name: datum.x,
|
|
179
|
+
value: datum.y,
|
|
180
|
+
tile: count++,
|
|
181
|
+
color: colorByName.get(datum.x),
|
|
182
|
+
group
|
|
183
|
+
});
|
|
184
|
+
const grouped = drawn.length > 1;
|
|
185
|
+
const groups = grouped ? drawn.map((s, i) => {
|
|
186
|
+
const group = s.name ?? `Series ${i + 1}`;
|
|
187
|
+
return { name: group, children: s.data.map(toTile(group)) };
|
|
188
|
+
}) : [];
|
|
189
|
+
const data = grouped ? groups : drawn[0].data.map(toTile());
|
|
190
|
+
const firstOfGroup = new Set(grouped ? groups.map((group) => group.children[0].tile) : []);
|
|
191
|
+
const tabbable = Math.min(roving, count - 1);
|
|
192
|
+
const onKeyDown = (event) => {
|
|
193
|
+
const next = {
|
|
194
|
+
ArrowRight: tabbable + 1,
|
|
195
|
+
ArrowDown: tabbable + 1,
|
|
196
|
+
ArrowLeft: tabbable - 1,
|
|
197
|
+
ArrowUp: tabbable - 1,
|
|
198
|
+
Home: 0,
|
|
199
|
+
End: count - 1
|
|
200
|
+
}[event.key];
|
|
201
|
+
if (next === void 0) return;
|
|
202
|
+
event.preventDefault();
|
|
203
|
+
const index = Math.min(Math.max(next, 0), count - 1);
|
|
204
|
+
frame.current?.querySelector(`[data-tile="${index}"]`)?.focus();
|
|
205
|
+
};
|
|
206
|
+
const onFocusTile = (event, index) => {
|
|
207
|
+
setRoving(index);
|
|
208
|
+
if (event.currentTarget.matches(":focus-visible")) {
|
|
209
|
+
setRinged(index);
|
|
210
|
+
pointerOver(event.currentTarget);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const onBlurTile = (event) => {
|
|
214
|
+
setRinged(void 0);
|
|
215
|
+
pointerOut(event.currentTarget);
|
|
216
|
+
};
|
|
217
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
218
|
+
"div",
|
|
219
|
+
{
|
|
220
|
+
ref: frame,
|
|
221
|
+
role: "group",
|
|
222
|
+
"aria-label": name,
|
|
223
|
+
onKeyDown,
|
|
224
|
+
style: { width, height, maxWidth: "100%", color: chunkLT3UC65O_cjs.MUTED },
|
|
225
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
226
|
+
recharts.Treemap,
|
|
227
|
+
{
|
|
228
|
+
width: "100%",
|
|
229
|
+
height: "100%",
|
|
230
|
+
data,
|
|
231
|
+
dataKey: "value",
|
|
232
|
+
nameKey: "name",
|
|
233
|
+
aspectRatio: 1.4,
|
|
234
|
+
content: (node) => {
|
|
235
|
+
const tileNode = node;
|
|
236
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
237
|
+
TileView,
|
|
238
|
+
{
|
|
239
|
+
node: tileNode,
|
|
240
|
+
titled: firstOfGroup.has(tileNode.tile ?? -1),
|
|
241
|
+
tabbable: tileNode.tile === tabbable,
|
|
242
|
+
ring: tileNode.tile === ringed,
|
|
243
|
+
showValues,
|
|
244
|
+
format: formatValue,
|
|
245
|
+
onFocusTile,
|
|
246
|
+
onBlurTile
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
},
|
|
250
|
+
...chunkTYQWZR3S_cjs.ANIMATION,
|
|
251
|
+
children: [
|
|
252
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(TreemapTooltip, { format: formatValue }), animationDuration: 150 }),
|
|
253
|
+
children
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
exports.TreemapChart = TreemapChart;
|
|
262
|
+
//# sourceMappingURL=TreemapChart.cjs.map
|
|
263
|
+
//# sourceMappingURL=TreemapChart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/TreemapChart.tsx"],"names":["jsx","jsxs","PANEL","TEXT","textOn","TRACK","TooltipCard","useRef","useState","hasNoData","ChartEmpty","data","seriesColor","MUTED","Treemap","ANIMATION","Tooltip"],"mappings":"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","file":"TreemapChart.cjs","sourcesContent":["import { useRef, useState, type FocusEvent, type KeyboardEvent } from 'react';\nimport { Tooltip, Treemap, type TooltipContentProps, type TreemapNode } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { MUTED, PANEL, TEXT, TRACK, seriesColor } from './core/colors';\nimport { hasNoData } from './core/data';\nimport { ChartEmpty } from './core/frame';\nimport { textOn } from './core/readable';\nimport type { ChartEmptyProps, ChartProps } from './types';\n\nexport type TreemapDatum = { x: string; y: number };\n\nexport type TreemapChartProps = ChartProps &\n ChartEmptyProps & {\n series: { name?: string; data: TreemapDatum[] }[];\n /**\n * Override the default Cosmos palette. Tiles are colored by name, in the\n * order the names first appear: one name keeps its color in every group.\n */\n colors?: string[];\n /** Format the values in the tooltip and on the tiles. */\n formatValue?: (value: number) => string;\n /**\n * Write each tile's value, formatted, under its name. Default off: the name alone, and the\n * value in the tooltip.\n */\n showValues?: boolean;\n };\n\n/** What a tile carries from the data to the content that draws it. */\ntype Tile = {\n name: string;\n value: number;\n /** Zero-based position among the tiles, in the order of the data: the order of the arrow keys. */\n tile: number;\n color: string;\n /** The group it sits in, when there are several series. */\n group?: string;\n};\n\ntype TileNode = TreemapNode & Partial<Tile>;\n\n// Room the label leaves around its text, and the smallest tile that has one.\nconst PAD = 8;\nconst MIN_LABEL = { width: 44, height: 28 };\n// The group title sits on the corner of its first tile, over the top of its label.\nconst TITLE_HEIGHT = 24;\n\nconst asTile = (node: TileNode): Tile | undefined =>\n node.tile === undefined\n ? undefined\n : {\n name: node.name,\n value: node.value,\n tile: node.tile,\n color: node.color as string,\n group: node.group,\n };\n\ntype TileViewProps = {\n node: TileNode;\n /** Whether the group title sits on this tile: the first of its group. */\n titled: boolean;\n tabbable: boolean;\n ring: boolean;\n showValues: boolean;\n format: (value: number) => string;\n onFocusTile: (event: FocusEvent<SVGGElement>, tile: number) => void;\n onBlurTile: (event: FocusEvent<SVGGElement>) => void;\n};\n\nconst ellipsis = { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } as const;\n\n/**\n * One tile: a rounded rectangle with the card's color for an outline (the gap\n * between tiles), the name and the value in the text color that reads on it,\n * and a focus ring in the theme's text color, since an accent ring would\n * vanish on the accent tile.\n */\nconst TileView = ({\n node,\n titled,\n tabbable,\n ring,\n showValues,\n format,\n onFocusTile,\n onBlurTile,\n}: TileViewProps) => {\n const tile = asTile(node);\n // A group draws nothing of its own: its tiles are drawn over it.\n if (!tile) return <g />;\n const { x, y, width, height } = node;\n const label = tile.group ? `${tile.group}, ${tile.name}` : tile.name;\n return (\n <g\n data-tile={tile.tile}\n role=\"img\"\n aria-label={`${label}: ${format(tile.value)}`}\n tabIndex={tabbable ? 0 : -1}\n onFocus={(event) => onFocusTile(event, tile.tile)}\n onBlur={onBlurTile}\n style={{ outline: 'none' }}\n >\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n rx={5}\n fill={tile.color}\n stroke={PANEL}\n strokeWidth={2}\n />\n {ring && (\n <rect\n x={x + 3}\n y={y + 3}\n width={Math.max(width - 6, 0)}\n height={Math.max(height - 6, 0)}\n rx={3}\n fill=\"none\"\n stroke={TEXT}\n strokeWidth={2}\n pointerEvents=\"none\"\n />\n )}\n {width >= MIN_LABEL.width && height >= MIN_LABEL.height + (titled ? TITLE_HEIGHT : 0) && (\n // HTML in the SVG: the browser clips the text to the tile and sizes it\n // with the text size setting.\n <foreignObject x={x} y={y} width={width} height={height} pointerEvents=\"none\">\n <div\n style={{\n boxSizing: 'border-box',\n width: '100%',\n height: '100%',\n padding: titled ? `${PAD + TITLE_HEIGHT}px ${PAD}px ${PAD}px` : PAD,\n overflow: 'hidden',\n color: textOn(tile.color),\n fontSize: 'var(--text-xs, 0.75rem)',\n lineHeight: 1.35,\n fontWeight: 500,\n }}\n >\n <div style={ellipsis}>{tile.name}</div>\n {showValues && (\n <div style={{ ...ellipsis, opacity: 0.85, fontVariantNumeric: 'tabular-nums' }}>\n {format(tile.value)}\n </div>\n )}\n </div>\n </foreignObject>\n )}\n {titled && tile.group && (\n // The name of a group, on the corner of its first tile, in the card's colors.\n <foreignObject\n x={x}\n y={y}\n width={Math.min(width, 180)}\n height={TITLE_HEIGHT + 2}\n pointerEvents=\"none\"\n >\n <div\n style={{\n ...ellipsis,\n display: 'inline-block',\n maxWidth: '100%',\n boxSizing: 'border-box',\n padding: '2px 8px',\n color: TEXT,\n background: PANEL,\n border: `1px solid ${TRACK}`,\n borderRadius: '0 0 5px 0',\n fontSize: 'var(--text-xs, 0.75rem)',\n fontWeight: 600,\n lineHeight: 1.35,\n }}\n >\n {tile.group}\n </div>\n </foreignObject>\n )}\n </g>\n );\n};\n\n/** The tooltip card: the group (if any) for the title, the tile for the row. */\nconst TreemapTooltip = ({\n active,\n payload,\n format,\n}: Partial<TooltipContentProps> & { format: (value: number) => string }) => {\n const tile = active && payload?.length ? asTile(payload[0].payload as TileNode) : undefined;\n if (!tile) return null;\n return (\n <TooltipCard\n title={tile.group}\n rows={[{ name: tile.name, value: format(tile.value), color: tile.color }]}\n />\n );\n};\n\n// A Treemap has no keyboard layer. It shows a tile's tooltip when the pointer\n// enters the tile and hides it when the pointer leaves the chart, so the tile\n// that takes the keyboard focus sends those two events to itself.\nconst pointerOver = (element: Element) =>\n element.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));\nconst pointerOut = (element: Element) =>\n element.dispatchEvent(new MouseEvent('mouseout', { bubbles: true }));\n\nexport const TreemapChart = ({\n series,\n colors,\n formatValue = String,\n showValues = false,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width = '100%',\n}: TreemapChartProps) => {\n const frame = useRef<HTMLDivElement>(null);\n const [roving, setRoving] = useState(0);\n const [ringed, setRinged] = useState<number>();\n const name = ariaLabel ?? `Treemap: ${series.flatMap((s) => s.data.map((d) => d.x)).join(', ')}`;\n // A tile with no area cannot be seen, hovered or focused.\n const drawn = series.map((s) => ({ ...s, data: s.data.filter((d) => d.y > 0) }));\n if (hasNoData(drawn)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n // One color per name, so a name has the same color in every group.\n const colorByName = new Map<string, string>();\n for (const { data } of drawn) {\n for (const { x } of data) {\n if (!colorByName.has(x)) colorByName.set(x, seriesColor(colorByName.size, colors));\n }\n }\n let count = 0;\n const toTile =\n (group?: string) =>\n (datum: TreemapDatum): Tile => ({\n name: datum.x,\n value: datum.y,\n tile: count++,\n color: colorByName.get(datum.x) as string,\n group,\n });\n // Several series are groups, each a block of its own; a single one is just its tiles.\n const grouped = drawn.length > 1;\n const groups = grouped\n ? drawn.map((s, i) => {\n const group = s.name ?? `Series ${i + 1}`;\n return { name: group, children: s.data.map(toTile(group)) };\n })\n : [];\n const data = grouped ? groups : drawn[0].data.map(toTile());\n const firstOfGroup = new Set(grouped ? groups.map((group) => group.children[0].tile) : []);\n // The tab stop stays on a tile that exists when the data shrinks.\n const tabbable = Math.min(roving, count - 1);\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const next = {\n ArrowRight: tabbable + 1,\n ArrowDown: tabbable + 1,\n ArrowLeft: tabbable - 1,\n ArrowUp: tabbable - 1,\n Home: 0,\n End: count - 1,\n }[event.key];\n if (next === undefined) return;\n event.preventDefault();\n const index = Math.min(Math.max(next, 0), count - 1);\n frame.current?.querySelector<SVGGElement>(`[data-tile=\"${index}\"]`)?.focus();\n };\n const onFocusTile = (event: FocusEvent<SVGGElement>, index: number) => {\n setRoving(index);\n // A click focuses a tile too, and the pointer already shows its tooltip: only the keyboard needs this.\n if (event.currentTarget.matches(':focus-visible')) {\n setRinged(index);\n pointerOver(event.currentTarget);\n }\n };\n const onBlurTile = (event: FocusEvent<SVGGElement>) => {\n setRinged(undefined);\n pointerOut(event.currentTarget);\n };\n\n return (\n <div\n ref={frame}\n role=\"group\"\n aria-label={name}\n onKeyDown={onKeyDown}\n style={{ width, height, maxWidth: '100%', color: MUTED }}\n >\n <Treemap\n width=\"100%\"\n height=\"100%\"\n data={data}\n dataKey=\"value\"\n nameKey=\"name\"\n aspectRatio={1.4}\n content={(node) => {\n const tileNode = node as TileNode;\n return (\n <TileView\n node={tileNode}\n titled={firstOfGroup.has(tileNode.tile ?? -1)}\n tabbable={tileNode.tile === tabbable}\n ring={tileNode.tile === ringed}\n showValues={showValues}\n format={formatValue}\n onFocusTile={onFocusTile}\n onBlurTile={onBlurTile}\n />\n );\n }}\n {...ANIMATION}\n >\n <Tooltip content={<TreemapTooltip format={formatValue} />} animationDuration={150} />\n {children}\n </Treemap>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
3
|
+
import { textOn } from './chunk-BFEDLXVW.js';
|
|
4
|
+
import { TooltipCard } from './chunk-VIOSQN4Z.js';
|
|
5
|
+
import { hasNoData } from './chunk-UJIV5PVI.js';
|
|
6
|
+
import { ChartEmpty } from './chunk-3N43QT36.js';
|
|
7
|
+
import { seriesColor, MUTED, PANEL, TEXT, TRACK } from './chunk-UATB2IRY.js';
|
|
8
|
+
import { useRef, useState } from 'react';
|
|
9
|
+
import { Treemap, Tooltip } from 'recharts';
|
|
10
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
var PAD = 8;
|
|
13
|
+
var MIN_LABEL = { width: 44, height: 28 };
|
|
14
|
+
var TITLE_HEIGHT = 24;
|
|
15
|
+
var asTile = (node) => node.tile === void 0 ? void 0 : {
|
|
16
|
+
name: node.name,
|
|
17
|
+
value: node.value,
|
|
18
|
+
tile: node.tile,
|
|
19
|
+
color: node.color,
|
|
20
|
+
group: node.group
|
|
21
|
+
};
|
|
22
|
+
var ellipsis = { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" };
|
|
23
|
+
var TileView = ({
|
|
24
|
+
node,
|
|
25
|
+
titled,
|
|
26
|
+
tabbable,
|
|
27
|
+
ring,
|
|
28
|
+
showValues,
|
|
29
|
+
format,
|
|
30
|
+
onFocusTile,
|
|
31
|
+
onBlurTile
|
|
32
|
+
}) => {
|
|
33
|
+
const tile = asTile(node);
|
|
34
|
+
if (!tile) return /* @__PURE__ */ jsx("g", {});
|
|
35
|
+
const { x, y, width, height } = node;
|
|
36
|
+
const label = tile.group ? `${tile.group}, ${tile.name}` : tile.name;
|
|
37
|
+
return /* @__PURE__ */ jsxs(
|
|
38
|
+
"g",
|
|
39
|
+
{
|
|
40
|
+
"data-tile": tile.tile,
|
|
41
|
+
role: "img",
|
|
42
|
+
"aria-label": `${label}: ${format(tile.value)}`,
|
|
43
|
+
tabIndex: tabbable ? 0 : -1,
|
|
44
|
+
onFocus: (event) => onFocusTile(event, tile.tile),
|
|
45
|
+
onBlur: onBlurTile,
|
|
46
|
+
style: { outline: "none" },
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
"rect",
|
|
50
|
+
{
|
|
51
|
+
x,
|
|
52
|
+
y,
|
|
53
|
+
width,
|
|
54
|
+
height,
|
|
55
|
+
rx: 5,
|
|
56
|
+
fill: tile.color,
|
|
57
|
+
stroke: PANEL,
|
|
58
|
+
strokeWidth: 2
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
ring && /* @__PURE__ */ jsx(
|
|
62
|
+
"rect",
|
|
63
|
+
{
|
|
64
|
+
x: x + 3,
|
|
65
|
+
y: y + 3,
|
|
66
|
+
width: Math.max(width - 6, 0),
|
|
67
|
+
height: Math.max(height - 6, 0),
|
|
68
|
+
rx: 3,
|
|
69
|
+
fill: "none",
|
|
70
|
+
stroke: TEXT,
|
|
71
|
+
strokeWidth: 2,
|
|
72
|
+
pointerEvents: "none"
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
width >= MIN_LABEL.width && height >= MIN_LABEL.height + (titled ? TITLE_HEIGHT : 0) && // HTML in the SVG: the browser clips the text to the tile and sizes it
|
|
76
|
+
// with the text size setting.
|
|
77
|
+
/* @__PURE__ */ jsx("foreignObject", { x, y, width, height, pointerEvents: "none", children: /* @__PURE__ */ jsxs(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
style: {
|
|
81
|
+
boxSizing: "border-box",
|
|
82
|
+
width: "100%",
|
|
83
|
+
height: "100%",
|
|
84
|
+
padding: titled ? `${PAD + TITLE_HEIGHT}px ${PAD}px ${PAD}px` : PAD,
|
|
85
|
+
overflow: "hidden",
|
|
86
|
+
color: textOn(tile.color),
|
|
87
|
+
fontSize: "var(--text-xs, 0.75rem)",
|
|
88
|
+
lineHeight: 1.35,
|
|
89
|
+
fontWeight: 500
|
|
90
|
+
},
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx("div", { style: ellipsis, children: tile.name }),
|
|
93
|
+
showValues && /* @__PURE__ */ jsx("div", { style: { ...ellipsis, opacity: 0.85, fontVariantNumeric: "tabular-nums" }, children: format(tile.value) })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
) }),
|
|
97
|
+
titled && tile.group && // The name of a group, on the corner of its first tile, in the card's colors.
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
"foreignObject",
|
|
100
|
+
{
|
|
101
|
+
x,
|
|
102
|
+
y,
|
|
103
|
+
width: Math.min(width, 180),
|
|
104
|
+
height: TITLE_HEIGHT + 2,
|
|
105
|
+
pointerEvents: "none",
|
|
106
|
+
children: /* @__PURE__ */ jsx(
|
|
107
|
+
"div",
|
|
108
|
+
{
|
|
109
|
+
style: {
|
|
110
|
+
...ellipsis,
|
|
111
|
+
display: "inline-block",
|
|
112
|
+
maxWidth: "100%",
|
|
113
|
+
boxSizing: "border-box",
|
|
114
|
+
padding: "2px 8px",
|
|
115
|
+
color: TEXT,
|
|
116
|
+
background: PANEL,
|
|
117
|
+
border: `1px solid ${TRACK}`,
|
|
118
|
+
borderRadius: "0 0 5px 0",
|
|
119
|
+
fontSize: "var(--text-xs, 0.75rem)",
|
|
120
|
+
fontWeight: 600,
|
|
121
|
+
lineHeight: 1.35
|
|
122
|
+
},
|
|
123
|
+
children: tile.group
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
var TreemapTooltip = ({
|
|
133
|
+
active,
|
|
134
|
+
payload,
|
|
135
|
+
format
|
|
136
|
+
}) => {
|
|
137
|
+
const tile = active && payload?.length ? asTile(payload[0].payload) : void 0;
|
|
138
|
+
if (!tile) return null;
|
|
139
|
+
return /* @__PURE__ */ jsx(
|
|
140
|
+
TooltipCard,
|
|
141
|
+
{
|
|
142
|
+
title: tile.group,
|
|
143
|
+
rows: [{ name: tile.name, value: format(tile.value), color: tile.color }]
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
var pointerOver = (element) => element.dispatchEvent(new MouseEvent("mouseover", { bubbles: true }));
|
|
148
|
+
var pointerOut = (element) => element.dispatchEvent(new MouseEvent("mouseout", { bubbles: true }));
|
|
149
|
+
var TreemapChart = ({
|
|
150
|
+
series,
|
|
151
|
+
colors,
|
|
152
|
+
formatValue = String,
|
|
153
|
+
showValues = false,
|
|
154
|
+
emptyMessage = "No data",
|
|
155
|
+
ariaLabel,
|
|
156
|
+
children,
|
|
157
|
+
height = 320,
|
|
158
|
+
width = "100%"
|
|
159
|
+
}) => {
|
|
160
|
+
const frame = useRef(null);
|
|
161
|
+
const [roving, setRoving] = useState(0);
|
|
162
|
+
const [ringed, setRinged] = useState();
|
|
163
|
+
const name = ariaLabel ?? `Treemap: ${series.flatMap((s) => s.data.map((d) => d.x)).join(", ")}`;
|
|
164
|
+
const drawn = series.map((s) => ({ ...s, data: s.data.filter((d) => d.y > 0) }));
|
|
165
|
+
if (hasNoData(drawn)) {
|
|
166
|
+
return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
167
|
+
}
|
|
168
|
+
const colorByName = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const { data: data2 } of drawn) {
|
|
170
|
+
for (const { x } of data2) {
|
|
171
|
+
if (!colorByName.has(x)) colorByName.set(x, seriesColor(colorByName.size, colors));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
let count = 0;
|
|
175
|
+
const toTile = (group) => (datum) => ({
|
|
176
|
+
name: datum.x,
|
|
177
|
+
value: datum.y,
|
|
178
|
+
tile: count++,
|
|
179
|
+
color: colorByName.get(datum.x),
|
|
180
|
+
group
|
|
181
|
+
});
|
|
182
|
+
const grouped = drawn.length > 1;
|
|
183
|
+
const groups = grouped ? drawn.map((s, i) => {
|
|
184
|
+
const group = s.name ?? `Series ${i + 1}`;
|
|
185
|
+
return { name: group, children: s.data.map(toTile(group)) };
|
|
186
|
+
}) : [];
|
|
187
|
+
const data = grouped ? groups : drawn[0].data.map(toTile());
|
|
188
|
+
const firstOfGroup = new Set(grouped ? groups.map((group) => group.children[0].tile) : []);
|
|
189
|
+
const tabbable = Math.min(roving, count - 1);
|
|
190
|
+
const onKeyDown = (event) => {
|
|
191
|
+
const next = {
|
|
192
|
+
ArrowRight: tabbable + 1,
|
|
193
|
+
ArrowDown: tabbable + 1,
|
|
194
|
+
ArrowLeft: tabbable - 1,
|
|
195
|
+
ArrowUp: tabbable - 1,
|
|
196
|
+
Home: 0,
|
|
197
|
+
End: count - 1
|
|
198
|
+
}[event.key];
|
|
199
|
+
if (next === void 0) return;
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
const index = Math.min(Math.max(next, 0), count - 1);
|
|
202
|
+
frame.current?.querySelector(`[data-tile="${index}"]`)?.focus();
|
|
203
|
+
};
|
|
204
|
+
const onFocusTile = (event, index) => {
|
|
205
|
+
setRoving(index);
|
|
206
|
+
if (event.currentTarget.matches(":focus-visible")) {
|
|
207
|
+
setRinged(index);
|
|
208
|
+
pointerOver(event.currentTarget);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const onBlurTile = (event) => {
|
|
212
|
+
setRinged(void 0);
|
|
213
|
+
pointerOut(event.currentTarget);
|
|
214
|
+
};
|
|
215
|
+
return /* @__PURE__ */ jsx(
|
|
216
|
+
"div",
|
|
217
|
+
{
|
|
218
|
+
ref: frame,
|
|
219
|
+
role: "group",
|
|
220
|
+
"aria-label": name,
|
|
221
|
+
onKeyDown,
|
|
222
|
+
style: { width, height, maxWidth: "100%", color: MUTED },
|
|
223
|
+
children: /* @__PURE__ */ jsxs(
|
|
224
|
+
Treemap,
|
|
225
|
+
{
|
|
226
|
+
width: "100%",
|
|
227
|
+
height: "100%",
|
|
228
|
+
data,
|
|
229
|
+
dataKey: "value",
|
|
230
|
+
nameKey: "name",
|
|
231
|
+
aspectRatio: 1.4,
|
|
232
|
+
content: (node) => {
|
|
233
|
+
const tileNode = node;
|
|
234
|
+
return /* @__PURE__ */ jsx(
|
|
235
|
+
TileView,
|
|
236
|
+
{
|
|
237
|
+
node: tileNode,
|
|
238
|
+
titled: firstOfGroup.has(tileNode.tile ?? -1),
|
|
239
|
+
tabbable: tileNode.tile === tabbable,
|
|
240
|
+
ring: tileNode.tile === ringed,
|
|
241
|
+
showValues,
|
|
242
|
+
format: formatValue,
|
|
243
|
+
onFocusTile,
|
|
244
|
+
onBlurTile
|
|
245
|
+
}
|
|
246
|
+
);
|
|
247
|
+
},
|
|
248
|
+
...ANIMATION,
|
|
249
|
+
children: [
|
|
250
|
+
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(TreemapTooltip, { format: formatValue }), animationDuration: 150 }),
|
|
251
|
+
children
|
|
252
|
+
]
|
|
253
|
+
}
|
|
254
|
+
)
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export { TreemapChart };
|
|
260
|
+
//# sourceMappingURL=TreemapChart.js.map
|
|
261
|
+
//# sourceMappingURL=TreemapChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/TreemapChart.tsx"],"names":["data"],"mappings":"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","file":"TreemapChart.js","sourcesContent":["import { useRef, useState, type FocusEvent, type KeyboardEvent } from 'react';\nimport { Tooltip, Treemap, type TooltipContentProps, type TreemapNode } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { MUTED, PANEL, TEXT, TRACK, seriesColor } from './core/colors';\nimport { hasNoData } from './core/data';\nimport { ChartEmpty } from './core/frame';\nimport { textOn } from './core/readable';\nimport type { ChartEmptyProps, ChartProps } from './types';\n\nexport type TreemapDatum = { x: string; y: number };\n\nexport type TreemapChartProps = ChartProps &\n ChartEmptyProps & {\n series: { name?: string; data: TreemapDatum[] }[];\n /**\n * Override the default Cosmos palette. Tiles are colored by name, in the\n * order the names first appear: one name keeps its color in every group.\n */\n colors?: string[];\n /** Format the values in the tooltip and on the tiles. */\n formatValue?: (value: number) => string;\n /**\n * Write each tile's value, formatted, under its name. Default off: the name alone, and the\n * value in the tooltip.\n */\n showValues?: boolean;\n };\n\n/** What a tile carries from the data to the content that draws it. */\ntype Tile = {\n name: string;\n value: number;\n /** Zero-based position among the tiles, in the order of the data: the order of the arrow keys. */\n tile: number;\n color: string;\n /** The group it sits in, when there are several series. */\n group?: string;\n};\n\ntype TileNode = TreemapNode & Partial<Tile>;\n\n// Room the label leaves around its text, and the smallest tile that has one.\nconst PAD = 8;\nconst MIN_LABEL = { width: 44, height: 28 };\n// The group title sits on the corner of its first tile, over the top of its label.\nconst TITLE_HEIGHT = 24;\n\nconst asTile = (node: TileNode): Tile | undefined =>\n node.tile === undefined\n ? undefined\n : {\n name: node.name,\n value: node.value,\n tile: node.tile,\n color: node.color as string,\n group: node.group,\n };\n\ntype TileViewProps = {\n node: TileNode;\n /** Whether the group title sits on this tile: the first of its group. */\n titled: boolean;\n tabbable: boolean;\n ring: boolean;\n showValues: boolean;\n format: (value: number) => string;\n onFocusTile: (event: FocusEvent<SVGGElement>, tile: number) => void;\n onBlurTile: (event: FocusEvent<SVGGElement>) => void;\n};\n\nconst ellipsis = { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } as const;\n\n/**\n * One tile: a rounded rectangle with the card's color for an outline (the gap\n * between tiles), the name and the value in the text color that reads on it,\n * and a focus ring in the theme's text color, since an accent ring would\n * vanish on the accent tile.\n */\nconst TileView = ({\n node,\n titled,\n tabbable,\n ring,\n showValues,\n format,\n onFocusTile,\n onBlurTile,\n}: TileViewProps) => {\n const tile = asTile(node);\n // A group draws nothing of its own: its tiles are drawn over it.\n if (!tile) return <g />;\n const { x, y, width, height } = node;\n const label = tile.group ? `${tile.group}, ${tile.name}` : tile.name;\n return (\n <g\n data-tile={tile.tile}\n role=\"img\"\n aria-label={`${label}: ${format(tile.value)}`}\n tabIndex={tabbable ? 0 : -1}\n onFocus={(event) => onFocusTile(event, tile.tile)}\n onBlur={onBlurTile}\n style={{ outline: 'none' }}\n >\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n rx={5}\n fill={tile.color}\n stroke={PANEL}\n strokeWidth={2}\n />\n {ring && (\n <rect\n x={x + 3}\n y={y + 3}\n width={Math.max(width - 6, 0)}\n height={Math.max(height - 6, 0)}\n rx={3}\n fill=\"none\"\n stroke={TEXT}\n strokeWidth={2}\n pointerEvents=\"none\"\n />\n )}\n {width >= MIN_LABEL.width && height >= MIN_LABEL.height + (titled ? TITLE_HEIGHT : 0) && (\n // HTML in the SVG: the browser clips the text to the tile and sizes it\n // with the text size setting.\n <foreignObject x={x} y={y} width={width} height={height} pointerEvents=\"none\">\n <div\n style={{\n boxSizing: 'border-box',\n width: '100%',\n height: '100%',\n padding: titled ? `${PAD + TITLE_HEIGHT}px ${PAD}px ${PAD}px` : PAD,\n overflow: 'hidden',\n color: textOn(tile.color),\n fontSize: 'var(--text-xs, 0.75rem)',\n lineHeight: 1.35,\n fontWeight: 500,\n }}\n >\n <div style={ellipsis}>{tile.name}</div>\n {showValues && (\n <div style={{ ...ellipsis, opacity: 0.85, fontVariantNumeric: 'tabular-nums' }}>\n {format(tile.value)}\n </div>\n )}\n </div>\n </foreignObject>\n )}\n {titled && tile.group && (\n // The name of a group, on the corner of its first tile, in the card's colors.\n <foreignObject\n x={x}\n y={y}\n width={Math.min(width, 180)}\n height={TITLE_HEIGHT + 2}\n pointerEvents=\"none\"\n >\n <div\n style={{\n ...ellipsis,\n display: 'inline-block',\n maxWidth: '100%',\n boxSizing: 'border-box',\n padding: '2px 8px',\n color: TEXT,\n background: PANEL,\n border: `1px solid ${TRACK}`,\n borderRadius: '0 0 5px 0',\n fontSize: 'var(--text-xs, 0.75rem)',\n fontWeight: 600,\n lineHeight: 1.35,\n }}\n >\n {tile.group}\n </div>\n </foreignObject>\n )}\n </g>\n );\n};\n\n/** The tooltip card: the group (if any) for the title, the tile for the row. */\nconst TreemapTooltip = ({\n active,\n payload,\n format,\n}: Partial<TooltipContentProps> & { format: (value: number) => string }) => {\n const tile = active && payload?.length ? asTile(payload[0].payload as TileNode) : undefined;\n if (!tile) return null;\n return (\n <TooltipCard\n title={tile.group}\n rows={[{ name: tile.name, value: format(tile.value), color: tile.color }]}\n />\n );\n};\n\n// A Treemap has no keyboard layer. It shows a tile's tooltip when the pointer\n// enters the tile and hides it when the pointer leaves the chart, so the tile\n// that takes the keyboard focus sends those two events to itself.\nconst pointerOver = (element: Element) =>\n element.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));\nconst pointerOut = (element: Element) =>\n element.dispatchEvent(new MouseEvent('mouseout', { bubbles: true }));\n\nexport const TreemapChart = ({\n series,\n colors,\n formatValue = String,\n showValues = false,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width = '100%',\n}: TreemapChartProps) => {\n const frame = useRef<HTMLDivElement>(null);\n const [roving, setRoving] = useState(0);\n const [ringed, setRinged] = useState<number>();\n const name = ariaLabel ?? `Treemap: ${series.flatMap((s) => s.data.map((d) => d.x)).join(', ')}`;\n // A tile with no area cannot be seen, hovered or focused.\n const drawn = series.map((s) => ({ ...s, data: s.data.filter((d) => d.y > 0) }));\n if (hasNoData(drawn)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n // One color per name, so a name has the same color in every group.\n const colorByName = new Map<string, string>();\n for (const { data } of drawn) {\n for (const { x } of data) {\n if (!colorByName.has(x)) colorByName.set(x, seriesColor(colorByName.size, colors));\n }\n }\n let count = 0;\n const toTile =\n (group?: string) =>\n (datum: TreemapDatum): Tile => ({\n name: datum.x,\n value: datum.y,\n tile: count++,\n color: colorByName.get(datum.x) as string,\n group,\n });\n // Several series are groups, each a block of its own; a single one is just its tiles.\n const grouped = drawn.length > 1;\n const groups = grouped\n ? drawn.map((s, i) => {\n const group = s.name ?? `Series ${i + 1}`;\n return { name: group, children: s.data.map(toTile(group)) };\n })\n : [];\n const data = grouped ? groups : drawn[0].data.map(toTile());\n const firstOfGroup = new Set(grouped ? groups.map((group) => group.children[0].tile) : []);\n // The tab stop stays on a tile that exists when the data shrinks.\n const tabbable = Math.min(roving, count - 1);\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const next = {\n ArrowRight: tabbable + 1,\n ArrowDown: tabbable + 1,\n ArrowLeft: tabbable - 1,\n ArrowUp: tabbable - 1,\n Home: 0,\n End: count - 1,\n }[event.key];\n if (next === undefined) return;\n event.preventDefault();\n const index = Math.min(Math.max(next, 0), count - 1);\n frame.current?.querySelector<SVGGElement>(`[data-tile=\"${index}\"]`)?.focus();\n };\n const onFocusTile = (event: FocusEvent<SVGGElement>, index: number) => {\n setRoving(index);\n // A click focuses a tile too, and the pointer already shows its tooltip: only the keyboard needs this.\n if (event.currentTarget.matches(':focus-visible')) {\n setRinged(index);\n pointerOver(event.currentTarget);\n }\n };\n const onBlurTile = (event: FocusEvent<SVGGElement>) => {\n setRinged(undefined);\n pointerOut(event.currentTarget);\n };\n\n return (\n <div\n ref={frame}\n role=\"group\"\n aria-label={name}\n onKeyDown={onKeyDown}\n style={{ width, height, maxWidth: '100%', color: MUTED }}\n >\n <Treemap\n width=\"100%\"\n height=\"100%\"\n data={data}\n dataKey=\"value\"\n nameKey=\"name\"\n aspectRatio={1.4}\n content={(node) => {\n const tileNode = node as TileNode;\n return (\n <TileView\n node={tileNode}\n titled={firstOfGroup.has(tileNode.tile ?? -1)}\n tabbable={tileNode.tile === tabbable}\n ring={tileNode.tile === ringed}\n showValues={showValues}\n format={formatValue}\n onFocusTile={onFocusTile}\n onBlurTile={onBlurTile}\n />\n );\n }}\n {...ANIMATION}\n >\n <Tooltip content={<TreemapTooltip format={formatValue} />} animationDuration={150} />\n {children}\n </Treemap>\n </div>\n );\n};\n"]}
|