@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,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
// src/core/categoryKeys.ts
|
|
5
|
+
var AS_RECHARTS = {
|
|
6
|
+
ArrowDown: "ArrowLeft",
|
|
7
|
+
ArrowRight: "ArrowLeft",
|
|
8
|
+
ArrowUp: "ArrowRight",
|
|
9
|
+
ArrowLeft: "ArrowRight"
|
|
10
|
+
};
|
|
11
|
+
var remapped = /* @__PURE__ */ new WeakSet();
|
|
12
|
+
var useCategoryKeys = (layout) => useCallback(
|
|
13
|
+
(svg) => {
|
|
14
|
+
if (!svg || layout !== "vertical") return;
|
|
15
|
+
const onKeyDown = (event) => {
|
|
16
|
+
const key = AS_RECHARTS[event.key];
|
|
17
|
+
if (!key || remapped.has(event) || event.ctrlKey || event.metaKey || event.altKey) return;
|
|
18
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") event.preventDefault();
|
|
19
|
+
event.stopPropagation();
|
|
20
|
+
const copy = new KeyboardEvent("keydown", {
|
|
21
|
+
key,
|
|
22
|
+
bubbles: true,
|
|
23
|
+
cancelable: true,
|
|
24
|
+
repeat: event.repeat,
|
|
25
|
+
shiftKey: event.shiftKey
|
|
26
|
+
});
|
|
27
|
+
remapped.add(copy);
|
|
28
|
+
svg.dispatchEvent(copy);
|
|
29
|
+
};
|
|
30
|
+
svg.addEventListener("keydown", onKeyDown, true);
|
|
31
|
+
return () => svg.removeEventListener("keydown", onKeyDown, true);
|
|
32
|
+
},
|
|
33
|
+
[layout]
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export { useCategoryKeys };
|
|
37
|
+
//# sourceMappingURL=chunk-FUZW3H5X.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-FUZW3H5X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/categoryKeys.ts"],"names":[],"mappings":";;;;AAWA,IAAM,WAAA,GAAsC;AAAA,EAC1C,SAAA,EAAW,WAAA;AAAA,EACX,UAAA,EAAY,WAAA;AAAA,EACZ,OAAA,EAAS,YAAA;AAAA,EACT,SAAA,EAAW;AACb,CAAA;AAGA,IAAM,QAAA,uBAAe,OAAA,EAAe;AAc7B,IAAM,eAAA,GAAkB,CAAC,MAAA,KAC9B,WAAA;AAAA,EACE,CAAC,GAAA,KAA8B;AAC7B,IAAA,IAAI,CAAC,GAAA,IAAO,MAAA,KAAW,UAAA,EAAY;AACnC,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAyB;AAC1C,MAAA,MAAM,GAAA,GAAM,WAAA,CAAY,KAAA,CAAM,GAAG,CAAA;AACjC,MAAA,IAAI,CAAC,GAAA,IAAO,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,IAAK,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,MAAA,EAAQ;AACnF,MAAA,IAAI,MAAM,GAAA,KAAQ,SAAA,IAAa,MAAM,GAAA,KAAQ,WAAA,QAAmB,cAAA,EAAe;AAC/E,MAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,MAAA,MAAM,IAAA,GAAO,IAAI,aAAA,CAAc,SAAA,EAAW;AAAA,QACxC,GAAA;AAAA,QACA,OAAA,EAAS,IAAA;AAAA,QACT,UAAA,EAAY,IAAA;AAAA,QACZ,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,UAAU,KAAA,CAAM;AAAA,OACjB,CAAA;AACD,MAAA,QAAA,CAAS,IAAI,IAAI,CAAA;AACjB,MAAA,GAAA,CAAI,cAAc,IAAI,CAAA;AAAA,IACxB,CAAA;AACA,IAAA,GAAA,CAAI,gBAAA,CAAiB,SAAA,EAAW,SAAA,EAAW,IAAI,CAAA;AAC/C,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,SAAA,EAAW,WAAW,IAAI,CAAA;AAAA,EACjE,CAAA;AAAA,EACA,CAAC,MAAM;AACT","file":"chunk-FUZW3H5X.js","sourcesContent":["import { useCallback } from 'react';\n\n// Recharts 3.10.1: `keyboardEventsMiddleware` reads ArrowLeft and ArrowRight\n// only, and treats every chart direction but `left-to-right` as reversed.\n// `selectChartDirection` answers `top-to-bottom` for a vertical layout, so\n// there ArrowRight goes back, ArrowLeft goes forward and ArrowUp and ArrowDown\n// do nothing. Remove this once a Recharts release walks the categories\n// downward on ArrowDown.\n\n// The key to hand Recharts for each key pressed: in a vertical layout its\n// ArrowLeft is the next category and its ArrowRight the previous one.\nconst AS_RECHARTS: Record<string, string> = {\n ArrowDown: 'ArrowLeft',\n ArrowRight: 'ArrowLeft',\n ArrowUp: 'ArrowRight',\n ArrowLeft: 'ArrowRight',\n};\n\n// The events this hook made, which it must let through.\nconst remapped = new WeakSet<Event>();\n\n/**\n * The `ref` of a Recharts chart whose `layout` is `vertical`, the categories on\n * the vertical axis (a horizontal `BarChart`): ArrowDown and ArrowRight move\n * to the next category and ArrowUp and ArrowLeft to the previous one. In a\n * `horizontal` layout the ref does nothing.\n *\n * Recharts reads `event.key` from the keydown that reaches its wrapper, so the\n * arrow key is replaced there by the one Recharts reads the way we want: the\n * original is stopped on the chart and a copy with the other key is dispatched\n * in its place. ArrowUp and ArrowDown walk the chart now, so they no longer\n * scroll the page.\n */\nexport const useCategoryKeys = (layout: 'horizontal' | 'vertical') =>\n useCallback(\n (svg: SVGSVGElement | null) => {\n if (!svg || layout !== 'vertical') return;\n const onKeyDown = (event: KeyboardEvent) => {\n const key = AS_RECHARTS[event.key];\n if (!key || remapped.has(event) || event.ctrlKey || event.metaKey || event.altKey) return;\n if (event.key === 'ArrowUp' || event.key === 'ArrowDown') event.preventDefault();\n event.stopPropagation();\n const copy = new KeyboardEvent('keydown', {\n key,\n bubbles: true,\n cancelable: true,\n repeat: event.repeat,\n shiftKey: event.shiftKey,\n });\n remapped.add(copy);\n svg.dispatchEvent(copy);\n };\n svg.addEventListener('keydown', onKeyDown, true);\n return () => svg.removeEventListener('keydown', onKeyDown, true);\n },\n [layout]\n );\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/core/roundedBar.tsx
|
|
5
|
+
var roundedRect = (x, y, w, h, [tl, tr, br, bl]) => `M${x + tl},${y}H${x + w - tr}a${tr},${tr} 0 0 1 ${tr},${tr}V${y + h - br}a${br},${br} 0 0 1 ${-br},${br}H${x + bl}a${bl},${bl} 0 0 1 ${-bl},${-bl}V${y + tl}a${tl},${tl} 0 0 1 ${tl},${-tl}Z`;
|
|
6
|
+
var roundedBarShape = ({ layout, radius, dataKey, isOuter, fillFor }) => (props) => {
|
|
7
|
+
const { x, y, width, height } = props;
|
|
8
|
+
const row = props.payload ?? {};
|
|
9
|
+
const fill = fillFor?.(Number(row[dataKey]), props.index) ?? props.fill;
|
|
10
|
+
const left = Math.min(x, x + width);
|
|
11
|
+
const top = Math.min(y, y + height);
|
|
12
|
+
const w = Math.abs(width);
|
|
13
|
+
const h = Math.abs(height);
|
|
14
|
+
if (!(w > 0) || !(h > 0)) return null;
|
|
15
|
+
const negative = Number(row[dataKey]) < 0;
|
|
16
|
+
const r = !isOuter || isOuter(row) ? Math.min(radius, w / 2, h / 2) : 0;
|
|
17
|
+
const corners = layout === "horizontal" ? negative ? [0, 0, r, r] : [r, r, 0, 0] : negative ? [r, 0, 0, r] : [0, r, r, 0];
|
|
18
|
+
return /* @__PURE__ */ jsx("path", { d: roundedRect(left, top, w, h, corners), fill });
|
|
19
|
+
};
|
|
20
|
+
var isOuterInStack = (keys, key) => (row) => {
|
|
21
|
+
const value = Number(row[key]);
|
|
22
|
+
return !keys.slice(keys.indexOf(key) + 1).some((other) => Number(row[other]) !== 0 && Number(row[other]) * value > 0);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { isOuterInStack, roundedBarShape };
|
|
26
|
+
//# sourceMappingURL=chunk-GDZLYYL2.js.map
|
|
27
|
+
//# sourceMappingURL=chunk-GDZLYYL2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/roundedBar.tsx"],"names":[],"mappings":"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","file":"chunk-GDZLYYL2.js","sourcesContent":["import type { BarShapeProps } from 'recharts';\n\n/** The side of the plot a bar grows from: `horizontal` is a column chart, `vertical` a chart of horizontal bars (Recharts' own words for `layout`). */\nexport type BarLayout = 'horizontal' | 'vertical';\n\n// A rectangle with its own radius at each corner: top-left, top-right,\n// bottom-right, bottom-left.\nconst roundedRect = (\n x: number,\n y: number,\n w: number,\n h: number,\n [tl, tr, br, bl]: [number, number, number, number]\n) =>\n `M${x + tl},${y}H${x + w - tr}a${tr},${tr} 0 0 1 ${tr},${tr}V${y + h - br}` +\n `a${br},${br} 0 0 1 ${-br},${br}H${x + bl}a${bl},${bl} 0 0 1 ${-bl},${-bl}` +\n `V${y + tl}a${tl},${tl} 0 0 1 ${tl},${-tl}Z`;\n\ntype RoundedBarOptions = {\n layout: BarLayout;\n /** The corner radius of the outer end, in px. */\n radius: number;\n /** The key of the series in the data rows, to read the sign of the value. */\n dataKey: string;\n /**\n * Whether this bar is the outer end of its stack in `row`. A bar outside a\n * stack, or the last of it on its side of the axis, is. Default: always.\n */\n isOuter?: (row: Record<string, unknown>) => boolean;\n /**\n * The fill of a bar from its value and the index of its category, or\n * `undefined` for the series' own color.\n */\n fillFor?: (value: number, index: number) => string | undefined;\n};\n\n/**\n * The `shape` of a `Bar` that rounds the end away from the axis only: the top\n * of a column, the right of a horizontal bar, and the other end when the value\n * is negative. In a stack only the outermost segment on each side is rounded,\n * so the stack reads as one bar. The radius shrinks to fit a short bar. With\n * `fillFor`, a bar can take a color of its own.\n */\nexport const roundedBarShape =\n ({ layout, radius, dataKey, isOuter, fillFor }: RoundedBarOptions) =>\n (props: BarShapeProps) => {\n const { x, y, width, height } = props;\n const row = (props.payload ?? {}) as Record<string, unknown>;\n const fill = fillFor?.(Number(row[dataKey]), props.index) ?? props.fill;\n // The rectangle has a negative size when the value is below zero.\n const left = Math.min(x, x + width);\n const top = Math.min(y, y + height);\n const w = Math.abs(width);\n const h = Math.abs(height);\n if (!(w > 0) || !(h > 0)) return null;\n const negative = Number(row[dataKey]) < 0;\n const r = !isOuter || isOuter(row) ? Math.min(radius, w / 2, h / 2) : 0;\n const corners: [number, number, number, number] =\n layout === 'horizontal'\n ? negative\n ? [0, 0, r, r]\n : [r, r, 0, 0]\n : negative\n ? [r, 0, 0, r]\n : [0, r, r, 0];\n return <path d={roundedRect(left, top, w, h, corners)} fill={fill} />;\n };\n\n/**\n * For a stack, whether the series `key` is the last one drawn on its side of\n * the axis in a row, among the `keys` of the series that are shown.\n */\nexport const isOuterInStack =\n (keys: readonly string[], key: string) => (row: Record<string, unknown>) => {\n const value = Number(row[key]);\n return !keys\n .slice(keys.indexOf(key) + 1)\n .some((other) => Number(row[other]) !== 0 && Number(row[other]) * value > 0);\n };\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/core/roundedBar.tsx
|
|
7
|
+
var roundedRect = (x, y, w, h, [tl, tr, br, bl]) => `M${x + tl},${y}H${x + w - tr}a${tr},${tr} 0 0 1 ${tr},${tr}V${y + h - br}a${br},${br} 0 0 1 ${-br},${br}H${x + bl}a${bl},${bl} 0 0 1 ${-bl},${-bl}V${y + tl}a${tl},${tl} 0 0 1 ${tl},${-tl}Z`;
|
|
8
|
+
var roundedBarShape = ({ layout, radius, dataKey, isOuter, fillFor }) => (props) => {
|
|
9
|
+
const { x, y, width, height } = props;
|
|
10
|
+
const row = props.payload ?? {};
|
|
11
|
+
const fill = fillFor?.(Number(row[dataKey]), props.index) ?? props.fill;
|
|
12
|
+
const left = Math.min(x, x + width);
|
|
13
|
+
const top = Math.min(y, y + height);
|
|
14
|
+
const w = Math.abs(width);
|
|
15
|
+
const h = Math.abs(height);
|
|
16
|
+
if (!(w > 0) || !(h > 0)) return null;
|
|
17
|
+
const negative = Number(row[dataKey]) < 0;
|
|
18
|
+
const r = !isOuter || isOuter(row) ? Math.min(radius, w / 2, h / 2) : 0;
|
|
19
|
+
const corners = layout === "horizontal" ? negative ? [0, 0, r, r] : [r, r, 0, 0] : negative ? [r, 0, 0, r] : [0, r, r, 0];
|
|
20
|
+
return /* @__PURE__ */ jsxRuntime.jsx("path", { d: roundedRect(left, top, w, h, corners), fill });
|
|
21
|
+
};
|
|
22
|
+
var isOuterInStack = (keys, key) => (row) => {
|
|
23
|
+
const value = Number(row[key]);
|
|
24
|
+
return !keys.slice(keys.indexOf(key) + 1).some((other) => Number(row[other]) !== 0 && Number(row[other]) * value > 0);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.isOuterInStack = isOuterInStack;
|
|
28
|
+
exports.roundedBarShape = roundedBarShape;
|
|
29
|
+
//# sourceMappingURL=chunk-GVTMZYOM.cjs.map
|
|
30
|
+
//# sourceMappingURL=chunk-GVTMZYOM.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/roundedBar.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-GVTMZYOM.cjs","sourcesContent":["import type { BarShapeProps } from 'recharts';\n\n/** The side of the plot a bar grows from: `horizontal` is a column chart, `vertical` a chart of horizontal bars (Recharts' own words for `layout`). */\nexport type BarLayout = 'horizontal' | 'vertical';\n\n// A rectangle with its own radius at each corner: top-left, top-right,\n// bottom-right, bottom-left.\nconst roundedRect = (\n x: number,\n y: number,\n w: number,\n h: number,\n [tl, tr, br, bl]: [number, number, number, number]\n) =>\n `M${x + tl},${y}H${x + w - tr}a${tr},${tr} 0 0 1 ${tr},${tr}V${y + h - br}` +\n `a${br},${br} 0 0 1 ${-br},${br}H${x + bl}a${bl},${bl} 0 0 1 ${-bl},${-bl}` +\n `V${y + tl}a${tl},${tl} 0 0 1 ${tl},${-tl}Z`;\n\ntype RoundedBarOptions = {\n layout: BarLayout;\n /** The corner radius of the outer end, in px. */\n radius: number;\n /** The key of the series in the data rows, to read the sign of the value. */\n dataKey: string;\n /**\n * Whether this bar is the outer end of its stack in `row`. A bar outside a\n * stack, or the last of it on its side of the axis, is. Default: always.\n */\n isOuter?: (row: Record<string, unknown>) => boolean;\n /**\n * The fill of a bar from its value and the index of its category, or\n * `undefined` for the series' own color.\n */\n fillFor?: (value: number, index: number) => string | undefined;\n};\n\n/**\n * The `shape` of a `Bar` that rounds the end away from the axis only: the top\n * of a column, the right of a horizontal bar, and the other end when the value\n * is negative. In a stack only the outermost segment on each side is rounded,\n * so the stack reads as one bar. The radius shrinks to fit a short bar. With\n * `fillFor`, a bar can take a color of its own.\n */\nexport const roundedBarShape =\n ({ layout, radius, dataKey, isOuter, fillFor }: RoundedBarOptions) =>\n (props: BarShapeProps) => {\n const { x, y, width, height } = props;\n const row = (props.payload ?? {}) as Record<string, unknown>;\n const fill = fillFor?.(Number(row[dataKey]), props.index) ?? props.fill;\n // The rectangle has a negative size when the value is below zero.\n const left = Math.min(x, x + width);\n const top = Math.min(y, y + height);\n const w = Math.abs(width);\n const h = Math.abs(height);\n if (!(w > 0) || !(h > 0)) return null;\n const negative = Number(row[dataKey]) < 0;\n const r = !isOuter || isOuter(row) ? Math.min(radius, w / 2, h / 2) : 0;\n const corners: [number, number, number, number] =\n layout === 'horizontal'\n ? negative\n ? [0, 0, r, r]\n : [r, r, 0, 0]\n : negative\n ? [r, 0, 0, r]\n : [0, r, r, 0];\n return <path d={roundedRect(left, top, w, h, corners)} fill={fill} />;\n };\n\n/**\n * For a stack, whether the series `key` is the last one drawn on its side of\n * the axis in a row, among the `keys` of the series that are shown.\n */\nexport const isOuterInStack =\n (keys: readonly string[], key: string) => (row: Record<string, unknown>) => {\n const value = Number(row[key]);\n return !keys\n .slice(keys.indexOf(key) + 1)\n .some((other) => Number(row[other]) !== 0 && Number(row[other]) * value > 0);\n };\n"]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
|
|
5
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
var useHiddenSeries = () => {
|
|
10
|
+
const [hidden, setHidden] = react.useState(/* @__PURE__ */ new Set());
|
|
11
|
+
const toggle = react.useCallback((key) => {
|
|
12
|
+
setHidden((current) => {
|
|
13
|
+
const next = new Set(current);
|
|
14
|
+
if (!next.delete(key)) next.add(key);
|
|
15
|
+
return next;
|
|
16
|
+
});
|
|
17
|
+
}, []);
|
|
18
|
+
return { hidden, toggle };
|
|
19
|
+
};
|
|
20
|
+
var ChartLegend = ({ payload, hidden, onToggle, column, detail }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
+
"ul",
|
|
22
|
+
{
|
|
23
|
+
style: {
|
|
24
|
+
display: "flex",
|
|
25
|
+
flexDirection: column ? "column" : "row",
|
|
26
|
+
flexWrap: "wrap",
|
|
27
|
+
gap: column ? "0.375rem" : "0.25rem 1rem",
|
|
28
|
+
margin: 0,
|
|
29
|
+
padding: 0,
|
|
30
|
+
listStyle: "none",
|
|
31
|
+
fontSize: chunkRLHGPHC7_cjs.TEXT_SIZE,
|
|
32
|
+
color: chunkLT3UC65O_cjs.MUTED
|
|
33
|
+
},
|
|
34
|
+
children: payload?.map((entry, index) => {
|
|
35
|
+
const key = String(entry.dataKey);
|
|
36
|
+
const figures = detail?.(index);
|
|
37
|
+
const off = hidden.has(key);
|
|
38
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39
|
+
"button",
|
|
40
|
+
{
|
|
41
|
+
type: "button",
|
|
42
|
+
"aria-pressed": !off,
|
|
43
|
+
onClick: () => onToggle(key),
|
|
44
|
+
className: "focus-visible:focus-indicator",
|
|
45
|
+
style: {
|
|
46
|
+
display: "inline-flex",
|
|
47
|
+
alignItems: "center",
|
|
48
|
+
gap: "0.375rem",
|
|
49
|
+
padding: "0.125rem 0.25rem",
|
|
50
|
+
font: "inherit",
|
|
51
|
+
color: "inherit",
|
|
52
|
+
background: "none",
|
|
53
|
+
border: 0,
|
|
54
|
+
borderRadius: "0.25rem",
|
|
55
|
+
cursor: "pointer",
|
|
56
|
+
textDecoration: off ? "line-through" : void 0,
|
|
57
|
+
// The figures of a column reach its right edge, which aligns them.
|
|
58
|
+
...figures && column ? { display: "flex", width: "100%", gap: "0.75rem" } : {}
|
|
59
|
+
},
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
62
|
+
"span",
|
|
63
|
+
{
|
|
64
|
+
"aria-hidden": true,
|
|
65
|
+
style: {
|
|
66
|
+
width: "0.625rem",
|
|
67
|
+
height: "0.625rem",
|
|
68
|
+
borderRadius: "50%",
|
|
69
|
+
background: entry.color,
|
|
70
|
+
// Text keeps its color: dimming it would fail the contrast check.
|
|
71
|
+
opacity: off ? 0.35 : 1
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
figures ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: column ? { flex: 1, textAlign: "start" } : void 0, children: entry.value }),
|
|
77
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
78
|
+
"span",
|
|
79
|
+
{
|
|
80
|
+
style: {
|
|
81
|
+
color: chunkLT3UC65O_cjs.TEXT,
|
|
82
|
+
fontWeight: 600,
|
|
83
|
+
fontVariantNumeric: "tabular-nums",
|
|
84
|
+
textAlign: "end"
|
|
85
|
+
},
|
|
86
|
+
children: figures.value
|
|
87
|
+
}
|
|
88
|
+
),
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
90
|
+
"span",
|
|
91
|
+
{
|
|
92
|
+
style: {
|
|
93
|
+
minWidth: column ? "3.5ch" : void 0,
|
|
94
|
+
fontVariantNumeric: "tabular-nums",
|
|
95
|
+
textAlign: "end"
|
|
96
|
+
},
|
|
97
|
+
children: figures.share
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
] }) : entry.value
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
) }, key);
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
var GAP = "1rem";
|
|
108
|
+
var legendProps = (position, { hidden, toggle }) => ({
|
|
109
|
+
position,
|
|
110
|
+
itemSorter: null,
|
|
111
|
+
wrapperStyle: {
|
|
112
|
+
top: { width: "100%", paddingBottom: GAP },
|
|
113
|
+
bottom: { width: "100%", paddingTop: GAP },
|
|
114
|
+
left: { paddingRight: GAP },
|
|
115
|
+
right: { paddingLeft: GAP }
|
|
116
|
+
}[position],
|
|
117
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
118
|
+
ChartLegend,
|
|
119
|
+
{
|
|
120
|
+
hidden,
|
|
121
|
+
onToggle: toggle,
|
|
122
|
+
column: position === "left" || position === "right"
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
exports.ChartLegend = ChartLegend;
|
|
128
|
+
exports.legendProps = legendProps;
|
|
129
|
+
exports.useHiddenSeries = useHiddenSeries;
|
|
130
|
+
//# sourceMappingURL=chunk-GZRMVE4X.cjs.map
|
|
131
|
+
//# sourceMappingURL=chunk-GZRMVE4X.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/ChartLegend.tsx"],"names":["useState","useCallback","jsx","TEXT_SIZE","MUTED","jsxs","Fragment","TEXT"],"mappings":"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","file":"chunk-GZRMVE4X.cjs","sourcesContent":["import { useCallback, useState, type ReactNode } from 'react';\nimport type { LegendPayload, LegendProps } from 'recharts';\nimport type { ChartLegendPosition } from '../types';\nimport { MUTED, TEXT } from './colors';\nimport { TEXT_SIZE } from './axes';\n\n/**\n * The series a click on the legend hid, and the toggle. A hidden series is\n * passed to its graphical item as `hide`, so the axes fit what is left.\n */\nexport const useHiddenSeries = () => {\n const [hidden, setHidden] = useState<ReadonlySet<string>>(new Set());\n const toggle = useCallback((key: string) => {\n setHidden((current) => {\n const next = new Set(current);\n if (!next.delete(key)) next.add(key);\n return next;\n });\n }, []);\n return { hidden, toggle };\n};\n\ntype ChartLegendProps = {\n /** Given by Recharts: one entry per series, in the order the series are drawn. */\n payload?: readonly LegendPayload[];\n /** The keys of the hidden series. */\n hidden: ReadonlySet<string>;\n onToggle: (key: string) => void;\n /** Items in a column (`left`, `right`) or a row (`top`, `bottom`). */\n column?: boolean;\n /**\n * A figure written after the name of the entry at `index`: a value and its\n * share. In a column the figures sit at the right edge, aligned on their\n * last digit; in a row they follow the name.\n */\n detail?: (index: number) => { value: string; share: string };\n};\n\n/**\n * The legend of every chart: a round chip and the series name in the muted\n * text color, one button per series. A click (or Enter, Space) hides the series\n * and shows it again; the button says which in `aria-pressed`. Pass it as\n * `<Legend content={…} itemSorter={null} />`: Recharts sorts the items by name\n * unless told not to, and the series keep their order.\n */\nexport const ChartLegend = ({ payload, hidden, onToggle, column, detail }: ChartLegendProps) => (\n <ul\n style={{\n display: 'flex',\n flexDirection: column ? 'column' : 'row',\n flexWrap: 'wrap',\n gap: column ? '0.375rem' : '0.25rem 1rem',\n margin: 0,\n padding: 0,\n listStyle: 'none',\n fontSize: TEXT_SIZE,\n color: MUTED,\n }}\n >\n {payload?.map((entry, index) => {\n const key = String(entry.dataKey);\n const figures = detail?.(index);\n const off = hidden.has(key);\n return (\n <li key={key}>\n <button\n type=\"button\"\n aria-pressed={!off}\n onClick={() => onToggle(key)}\n className=\"focus-visible:focus-indicator\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.375rem',\n padding: '0.125rem 0.25rem',\n font: 'inherit',\n color: 'inherit',\n background: 'none',\n border: 0,\n borderRadius: '0.25rem',\n cursor: 'pointer',\n textDecoration: off ? 'line-through' : undefined,\n // The figures of a column reach its right edge, which aligns them.\n ...(figures && column ? { display: 'flex', width: '100%', gap: '0.75rem' } : {}),\n }}\n >\n <span\n aria-hidden\n style={{\n width: '0.625rem',\n height: '0.625rem',\n borderRadius: '50%',\n background: entry.color,\n // Text keeps its color: dimming it would fail the contrast check.\n opacity: off ? 0.35 : 1,\n }}\n />\n {figures ? (\n <>\n <span style={column ? { flex: 1, textAlign: 'start' } : undefined}>\n {entry.value as ReactNode}\n </span>\n <span\n style={{\n color: TEXT,\n fontWeight: 600,\n fontVariantNumeric: 'tabular-nums',\n textAlign: 'end',\n }}\n >\n {figures.value}\n </span>\n <span\n style={{\n minWidth: column ? '3.5ch' : undefined,\n fontVariantNumeric: 'tabular-nums',\n textAlign: 'end',\n }}\n >\n {figures.share}\n </span>\n </>\n ) : (\n (entry.value as ReactNode)\n )}\n </button>\n </li>\n );\n })}\n </ul>\n);\n\nconst GAP = '1rem';\n\n/**\n * The props of the `<Legend>` of a chart: on `position`, the chips and names\n * of `ChartLegend`, in series order, a `GAP` away from the plot.\n */\nexport const legendProps = (\n position: ChartLegendPosition,\n { hidden, toggle }: ReturnType<typeof useHiddenSeries>\n): LegendProps => ({\n position,\n itemSorter: null,\n wrapperStyle: {\n top: { width: '100%', paddingBottom: GAP },\n bottom: { width: '100%', paddingTop: GAP },\n left: { paddingRight: GAP },\n right: { paddingLeft: GAP },\n }[position],\n content: (\n <ChartLegend\n hidden={hidden}\n onToggle={toggle}\n column={position === 'left' || position === 'right'}\n />\n ),\n});\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { AXIS } from './chunk-RILUG7JB.js';
|
|
3
|
+
|
|
4
|
+
// src/core/categoryAxis.ts
|
|
5
|
+
var MAX_CHARS = 14;
|
|
6
|
+
var trimLabel = (value) => {
|
|
7
|
+
const text = String(value);
|
|
8
|
+
return text.length > MAX_CHARS ? `${text.slice(0, MAX_CHARS - 1)}\u2026` : text;
|
|
9
|
+
};
|
|
10
|
+
var categoryAxis = (categories, title) => {
|
|
11
|
+
const longest = Math.max(0, ...categories.map((c) => String(c).length));
|
|
12
|
+
const tilted = categories.length > 6 && longest > 8;
|
|
13
|
+
const base = title ? 52 : 30;
|
|
14
|
+
return {
|
|
15
|
+
tickFormatter: trimLabel,
|
|
16
|
+
...tilted ? {
|
|
17
|
+
interval: 0,
|
|
18
|
+
angle: -40,
|
|
19
|
+
tick: { ...AXIS.tick, textAnchor: "end" },
|
|
20
|
+
height: base + Math.round(Math.min(longest, MAX_CHARS) * 4.2)
|
|
21
|
+
} : {}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { categoryAxis, trimLabel };
|
|
26
|
+
//# sourceMappingURL=chunk-HMH6DI7U.js.map
|
|
27
|
+
//# sourceMappingURL=chunk-HMH6DI7U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/categoryAxis.ts"],"names":[],"mappings":";;;;AAEA,IAAM,SAAA,GAAY,EAAA;AAGX,IAAM,SAAA,GAAY,CAAC,KAAA,KAA2B;AACnD,EAAA,MAAM,IAAA,GAAO,OAAO,KAAK,CAAA;AACzB,EAAA,OAAO,IAAA,CAAK,MAAA,GAAS,SAAA,GAAY,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,EAAG,SAAA,GAAY,CAAC,CAAC,CAAA,MAAA,CAAA,GAAM,IAAA;AACxE;AAOO,IAAM,YAAA,GAAe,CAAC,UAAA,EAA0C,KAAA,KAAmB;AACxF,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,MAAA,CAAO,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AACtE,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,MAAA,GAAS,CAAA,IAAK,OAAA,GAAU,CAAA;AAClD,EAAA,MAAM,IAAA,GAAO,QAAQ,EAAA,GAAK,EAAA;AAC1B,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,SAAA;AAAA,IACf,GAAI,MAAA,GACA;AAAA,MACE,QAAA,EAAU,CAAA;AAAA,MACV,KAAA,EAAO,GAAA;AAAA,MACP,MAAM,EAAE,GAAG,IAAA,CAAK,IAAA,EAAM,YAAY,KAAA,EAAM;AAAA,MACxC,MAAA,EAAQ,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,GAAA,CAAI,OAAA,EAAS,SAAS,CAAA,GAAI,GAAG;AAAA,QAE9D;AAAC,GACP;AACF","file":"chunk-HMH6DI7U.js","sourcesContent":["import { AXIS } from './axes';\n\nconst MAX_CHARS = 14;\n\n/** A category name cut short with an ellipsis; the tooltip keeps the full name. */\nexport const trimLabel = (value: string | number) => {\n const text = String(value);\n return text.length > MAX_CHARS ? `${text.slice(0, MAX_CHARS - 1)}…` : text;\n};\n\n/**\n * The props of a horizontal category `XAxis` that keeps its labels readable:\n * names that would not fit side by side are tilted and cut short, and every one\n * is kept (Recharts would otherwise skip the ones that overlap).\n */\nexport const categoryAxis = (categories: readonly (string | number)[], title?: string) => {\n const longest = Math.max(0, ...categories.map((c) => String(c).length));\n const tilted = categories.length > 6 && longest > 8;\n const base = title ? 52 : 30;\n return {\n tickFormatter: trimLabel,\n ...(tilted\n ? {\n interval: 0,\n angle: -40,\n tick: { ...AXIS.tick, textAnchor: 'end' },\n height: base + Math.round(Math.min(longest, MAX_CHARS) * 4.2),\n }\n : {}),\n } as const;\n};\n"]}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { textOn } from './chunk-BFEDLXVW.js';
|
|
3
|
+
import { TEXT_SIZE } from './chunk-RILUG7JB.js';
|
|
4
|
+
import { TooltipCard } from './chunk-VIOSQN4Z.js';
|
|
5
|
+
import { MUTED, PANEL, TEXT } from './chunk-UATB2IRY.js';
|
|
6
|
+
import { useRef, useState, useLayoutEffect } from 'react';
|
|
7
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
var GAP = 3;
|
|
10
|
+
var RADIUS = 5;
|
|
11
|
+
var LABEL_GAP = 6;
|
|
12
|
+
var TIP_GAP = 6;
|
|
13
|
+
var key = (row, column) => `${row}:${column}`;
|
|
14
|
+
var useLabelStride = (probe, gap) => {
|
|
15
|
+
const gridRef = useRef(null);
|
|
16
|
+
const probeRef = useRef(null);
|
|
17
|
+
const columnRef = useRef(null);
|
|
18
|
+
const [stride, setStride] = useState(1);
|
|
19
|
+
useLayoutEffect(() => {
|
|
20
|
+
const read = () => {
|
|
21
|
+
const label = probeRef.current?.offsetWidth ?? 0;
|
|
22
|
+
const column = columnRef.current?.offsetWidth ?? 0;
|
|
23
|
+
setStride(column > 0 ? Math.max(1, Math.ceil((label + LABEL_GAP) / (column + gap))) : 1);
|
|
24
|
+
};
|
|
25
|
+
read();
|
|
26
|
+
const observer = new ResizeObserver(read);
|
|
27
|
+
for (const el of [gridRef.current, probeRef.current]) if (el) observer.observe(el);
|
|
28
|
+
return () => observer.disconnect();
|
|
29
|
+
}, [probe, gap]);
|
|
30
|
+
return { gridRef, probeRef, columnRef, stride };
|
|
31
|
+
};
|
|
32
|
+
var HeatGrid = ({
|
|
33
|
+
rows,
|
|
34
|
+
columns,
|
|
35
|
+
cells,
|
|
36
|
+
cellHeight,
|
|
37
|
+
ariaLabel,
|
|
38
|
+
xTitle,
|
|
39
|
+
yTitle,
|
|
40
|
+
gap = GAP,
|
|
41
|
+
cellRadius = RADIUS,
|
|
42
|
+
columnWidth,
|
|
43
|
+
labelsAbove = false,
|
|
44
|
+
thinLabels = true
|
|
45
|
+
}) => {
|
|
46
|
+
const frame = useRef(null);
|
|
47
|
+
const longest = columns.reduce((a, b) => b.length > a.length ? b : a, "");
|
|
48
|
+
const { gridRef, probeRef, columnRef, stride: measured } = useLabelStride(longest, gap);
|
|
49
|
+
const stride = thinLabels ? measured : 1;
|
|
50
|
+
const byPosition = new Map(cells.map((cell) => [key(cell.row, cell.column), cell]));
|
|
51
|
+
const cellsByRow = /* @__PURE__ */ new Map();
|
|
52
|
+
for (const cell of cells) cellsByRow.set(cell.row, [...cellsByRow.get(cell.row) ?? [], cell]);
|
|
53
|
+
const inReadingOrder = [...cells].sort((a, b) => a.row - b.row || a.column - b.column);
|
|
54
|
+
const [roving, setRoving] = useState();
|
|
55
|
+
const first = inReadingOrder[0];
|
|
56
|
+
const tabbable = roving && byPosition.has(roving) ? roving : first && key(first.row, first.column);
|
|
57
|
+
const [hover, setHover] = useState();
|
|
58
|
+
const [focus, setFocus] = useState();
|
|
59
|
+
const tip = hover ?? focus;
|
|
60
|
+
const tipFor = (cell, element) => {
|
|
61
|
+
const host = frame.current.getBoundingClientRect();
|
|
62
|
+
const box = element.getBoundingClientRect();
|
|
63
|
+
const middle = box.left - host.left + box.width / 2;
|
|
64
|
+
const align = middle < host.width / 3 ? "start" : middle > 2 * host.width / 3 ? "end" : "center";
|
|
65
|
+
return {
|
|
66
|
+
cell,
|
|
67
|
+
x: { start: box.left - host.left, center: middle, end: box.right - host.left }[align],
|
|
68
|
+
top: box.top - host.top,
|
|
69
|
+
bottom: box.bottom - host.top,
|
|
70
|
+
align,
|
|
71
|
+
// Not enough room above the cell for the card: it goes under.
|
|
72
|
+
below: box.top - host.top < 90
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
const move = (event) => {
|
|
76
|
+
const origin = event.target.closest("[data-heat-cell]");
|
|
77
|
+
if (!origin) return;
|
|
78
|
+
const row = Number(origin.dataset.row);
|
|
79
|
+
const column = Number(origin.dataset.column);
|
|
80
|
+
const step = (dRow, dColumn) => {
|
|
81
|
+
for (let r = row + dRow, c = column + dColumn; r >= 0 && r < rows.length && c >= 0 && c < columns.length; r += dRow, c += dColumn) {
|
|
82
|
+
if (byPosition.has(key(r, c))) return key(r, c);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const edge = (last) => {
|
|
86
|
+
const pool = event.ctrlKey ? inReadingOrder : inReadingOrder.filter((cell2) => cell2.row === row);
|
|
87
|
+
const cell = last ? pool.at(-1) : pool[0];
|
|
88
|
+
return cell && key(cell.row, cell.column);
|
|
89
|
+
};
|
|
90
|
+
const targets = {
|
|
91
|
+
ArrowRight: () => step(0, 1),
|
|
92
|
+
ArrowLeft: () => step(0, -1),
|
|
93
|
+
ArrowDown: () => step(1, 0),
|
|
94
|
+
ArrowUp: () => step(-1, 0),
|
|
95
|
+
Home: () => edge(false),
|
|
96
|
+
End: () => edge(true)
|
|
97
|
+
};
|
|
98
|
+
const target = targets[event.key];
|
|
99
|
+
if (!target) return;
|
|
100
|
+
event.preventDefault();
|
|
101
|
+
const next = target();
|
|
102
|
+
if (next) gridRef.current?.querySelector(`[data-position="${next}"]`)?.focus();
|
|
103
|
+
};
|
|
104
|
+
const focusIn = (cell, event) => {
|
|
105
|
+
setRoving(key(cell.row, cell.column));
|
|
106
|
+
if (event.currentTarget.matches(":focus-visible")) {
|
|
107
|
+
setFocus(tipFor(cell, event.currentTarget));
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const focusOut = (event) => {
|
|
111
|
+
if (!event.currentTarget.contains(event.relatedTarget)) setFocus(void 0);
|
|
112
|
+
};
|
|
113
|
+
const rowOffset = yTitle ? 2 : 1;
|
|
114
|
+
const top = labelsAbove ? 1 : 0;
|
|
115
|
+
const labelsRow = labelsAbove ? 1 : rows.length + 1;
|
|
116
|
+
const tipStyle = tip && {
|
|
117
|
+
position: "absolute",
|
|
118
|
+
left: tip.x,
|
|
119
|
+
top: tip.below ? tip.bottom + TIP_GAP : tip.top - TIP_GAP,
|
|
120
|
+
transform: `translate(${{ start: "0", center: "-50%", end: "-100%" }[tip.align]}, ${tip.below ? "0" : "-100%"})`,
|
|
121
|
+
zIndex: 10,
|
|
122
|
+
pointerEvents: "none"
|
|
123
|
+
};
|
|
124
|
+
const grid = /* @__PURE__ */ jsxs(
|
|
125
|
+
"div",
|
|
126
|
+
{
|
|
127
|
+
ref: gridRef,
|
|
128
|
+
role: "grid",
|
|
129
|
+
"aria-label": ariaLabel,
|
|
130
|
+
onKeyDown: move,
|
|
131
|
+
onBlur: focusOut,
|
|
132
|
+
style: {
|
|
133
|
+
display: "grid",
|
|
134
|
+
gridTemplateColumns: `${yTitle ? "auto " : ""}${columnWidth ? "auto" : "fit-content(40%)"} repeat(${columns.length}, ${columnWidth ? `${columnWidth}px` : "minmax(0, 1fr)"})`,
|
|
135
|
+
gridTemplateRows: `${labelsAbove ? "auto " : ""}repeat(${rows.length}, ${cellHeight ? `${cellHeight}px` : "minmax(0, 1fr)"})${labelsAbove ? "" : " auto"}${xTitle ? " auto" : ""}`,
|
|
136
|
+
gap,
|
|
137
|
+
width: columnWidth ? "max-content" : "100%",
|
|
138
|
+
height: cellHeight ? void 0 : "100%",
|
|
139
|
+
fontSize: TEXT_SIZE,
|
|
140
|
+
color: MUTED
|
|
141
|
+
},
|
|
142
|
+
children: [
|
|
143
|
+
yTitle && /* @__PURE__ */ jsx(
|
|
144
|
+
"div",
|
|
145
|
+
{
|
|
146
|
+
"aria-hidden": true,
|
|
147
|
+
style: {
|
|
148
|
+
gridRow: `${1 + top} / ${rows.length + 1 + top}`,
|
|
149
|
+
gridColumn: 1,
|
|
150
|
+
writingMode: "vertical-rl",
|
|
151
|
+
transform: "rotate(180deg)",
|
|
152
|
+
textAlign: "center",
|
|
153
|
+
alignSelf: "center"
|
|
154
|
+
},
|
|
155
|
+
children: yTitle
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
rows.map((name, r) => /* @__PURE__ */ jsxs("div", { role: "row", style: { display: "contents" }, children: [
|
|
159
|
+
/* @__PURE__ */ jsx(
|
|
160
|
+
"div",
|
|
161
|
+
{
|
|
162
|
+
"aria-hidden": true,
|
|
163
|
+
"data-heat-row": "",
|
|
164
|
+
style: {
|
|
165
|
+
gridRow: r + 1 + top,
|
|
166
|
+
gridColumn: rowOffset,
|
|
167
|
+
alignSelf: "center",
|
|
168
|
+
paddingRight: "0.5rem",
|
|
169
|
+
// Stays in view when the grid scrolls sideways under it.
|
|
170
|
+
...columnWidth ? { position: "sticky", left: 0, zIndex: 2, background: PANEL } : {},
|
|
171
|
+
whiteSpace: "nowrap",
|
|
172
|
+
overflow: "hidden",
|
|
173
|
+
textOverflow: "ellipsis"
|
|
174
|
+
},
|
|
175
|
+
children: name
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
(cellsByRow.get(r) ?? []).map((cell) => {
|
|
179
|
+
const position = key(cell.row, cell.column);
|
|
180
|
+
const active = tip?.cell === cell;
|
|
181
|
+
return /* @__PURE__ */ jsx(
|
|
182
|
+
"div",
|
|
183
|
+
{
|
|
184
|
+
role: "gridcell",
|
|
185
|
+
"data-heat-cell": "",
|
|
186
|
+
"data-position": position,
|
|
187
|
+
"data-row": cell.row,
|
|
188
|
+
"data-column": cell.column,
|
|
189
|
+
tabIndex: position === tabbable ? 0 : -1,
|
|
190
|
+
"aria-label": `${cell.label ? `${cell.label}, ` : ""}${cell.title}: ${cell.value}`,
|
|
191
|
+
onFocus: (event) => focusIn(cell, event),
|
|
192
|
+
onMouseEnter: (event) => setHover(tipFor(cell, event.currentTarget)),
|
|
193
|
+
onMouseLeave: () => setHover(void 0),
|
|
194
|
+
style: {
|
|
195
|
+
gridRow: r + 1 + top,
|
|
196
|
+
gridColumn: cell.column + rowOffset + 1,
|
|
197
|
+
display: "flex",
|
|
198
|
+
alignItems: "center",
|
|
199
|
+
justifyContent: "center",
|
|
200
|
+
minWidth: 0,
|
|
201
|
+
overflow: "hidden",
|
|
202
|
+
borderRadius: cellRadius,
|
|
203
|
+
background: cell.color,
|
|
204
|
+
color: textOn(cell.color),
|
|
205
|
+
fontSize: "var(--text-2xs, 0.6875rem)",
|
|
206
|
+
fontWeight: 500,
|
|
207
|
+
lineHeight: 1,
|
|
208
|
+
whiteSpace: "nowrap",
|
|
209
|
+
// The same ring for the pointer and the keyboard, in the text color
|
|
210
|
+
// since an accent ring would vanish on the cells that are the accent.
|
|
211
|
+
outline: active ? `2px solid ${TEXT}` : "none",
|
|
212
|
+
zIndex: active ? 1 : void 0
|
|
213
|
+
},
|
|
214
|
+
children: cell.text
|
|
215
|
+
},
|
|
216
|
+
position
|
|
217
|
+
);
|
|
218
|
+
})
|
|
219
|
+
] }, r)),
|
|
220
|
+
columns.map((name, c) => /* @__PURE__ */ jsx(
|
|
221
|
+
"div",
|
|
222
|
+
{
|
|
223
|
+
ref: c === 0 ? columnRef : void 0,
|
|
224
|
+
"aria-hidden": true,
|
|
225
|
+
"data-heat-column": "",
|
|
226
|
+
style: {
|
|
227
|
+
gridRow: labelsRow,
|
|
228
|
+
gridColumn: c + rowOffset + 1,
|
|
229
|
+
display: "flex",
|
|
230
|
+
justifyContent: thinLabels ? "center" : "flex-start",
|
|
231
|
+
whiteSpace: "nowrap",
|
|
232
|
+
minWidth: 0
|
|
233
|
+
},
|
|
234
|
+
children: c % stride === 0 ? name : null
|
|
235
|
+
},
|
|
236
|
+
c
|
|
237
|
+
)),
|
|
238
|
+
xTitle && /* @__PURE__ */ jsx(
|
|
239
|
+
"div",
|
|
240
|
+
{
|
|
241
|
+
"aria-hidden": true,
|
|
242
|
+
style: {
|
|
243
|
+
gridRow: (labelsAbove ? rows.length + 1 : labelsRow) + 1,
|
|
244
|
+
gridColumn: `${rowOffset + 1} / -1`,
|
|
245
|
+
textAlign: "center"
|
|
246
|
+
},
|
|
247
|
+
children: xTitle
|
|
248
|
+
}
|
|
249
|
+
),
|
|
250
|
+
/* @__PURE__ */ jsx(
|
|
251
|
+
"span",
|
|
252
|
+
{
|
|
253
|
+
ref: probeRef,
|
|
254
|
+
"aria-hidden": true,
|
|
255
|
+
style: { position: "absolute", visibility: "hidden", whiteSpace: "nowrap" },
|
|
256
|
+
children: longest
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
return /* @__PURE__ */ jsxs("div", { ref: frame, style: { position: "relative", width: "100%", height: "100%", minWidth: 0 }, children: [
|
|
263
|
+
columnWidth ? (
|
|
264
|
+
// The padding leaves room for the focus outline of the cells at the edges,
|
|
265
|
+
// which the scrolling box would cut.
|
|
266
|
+
/* @__PURE__ */ jsx("div", { "data-heat-scroll": "", style: { overflowX: "auto", padding: 3 }, children: grid })
|
|
267
|
+
) : grid,
|
|
268
|
+
tip && tipStyle && /* @__PURE__ */ jsx("div", { "data-heat-tooltip": "", "aria-hidden": true, style: tipStyle, children: /* @__PURE__ */ jsx(
|
|
269
|
+
TooltipCard,
|
|
270
|
+
{
|
|
271
|
+
title: tip.cell.title,
|
|
272
|
+
rows: [{ name: tip.cell.label, value: tip.cell.value, color: tip.cell.color }]
|
|
273
|
+
}
|
|
274
|
+
) })
|
|
275
|
+
] });
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export { HeatGrid };
|
|
279
|
+
//# sourceMappingURL=chunk-ICL5K2CW.js.map
|
|
280
|
+
//# sourceMappingURL=chunk-ICL5K2CW.js.map
|