@x-plat/design-system 0.5.34 → 0.5.36
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/dist/components/Chart/index.cjs +41 -79
- package/dist/components/Chart/index.css +16 -26
- package/dist/components/Chart/index.js +41 -79
- package/dist/components/index.cjs +41 -79
- package/dist/components/index.css +16 -26
- package/dist/components/index.js +41 -79
- package/dist/index.cjs +41 -79
- package/dist/index.css +16 -26
- package/dist/index.js +41 -79
- package/package.json +1 -1
|
@@ -2357,8 +2357,8 @@ var TOOLTIP_OFFSET = 12;
|
|
|
2357
2357
|
var useChartTooltip = (enabled) => {
|
|
2358
2358
|
const [tooltip, setTooltip] = import_react6.default.useState({
|
|
2359
2359
|
visible: false,
|
|
2360
|
-
|
|
2361
|
-
|
|
2360
|
+
x: 0,
|
|
2361
|
+
y: 0,
|
|
2362
2362
|
content: ""
|
|
2363
2363
|
});
|
|
2364
2364
|
const containerRef = import_react6.default.useRef(null);
|
|
@@ -2369,18 +2369,26 @@ var useChartTooltip = (enabled) => {
|
|
|
2369
2369
|
const cy = e.clientY;
|
|
2370
2370
|
cancelAnimationFrame(rafRef.current);
|
|
2371
2371
|
rafRef.current = requestAnimationFrame(() => {
|
|
2372
|
-
|
|
2372
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2373
|
+
if (!rect) return;
|
|
2374
|
+
setTooltip((prev) => ({ ...prev, x: cx - rect.left, y: cy - rect.top }));
|
|
2373
2375
|
});
|
|
2374
2376
|
}, [enabled]);
|
|
2375
2377
|
const show = import_react6.default.useCallback((e, content) => {
|
|
2376
2378
|
if (!enabled) return;
|
|
2377
|
-
|
|
2379
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2380
|
+
if (!rect) return;
|
|
2381
|
+
setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
|
|
2382
|
+
}, [enabled]);
|
|
2383
|
+
const showAt = import_react6.default.useCallback((x, y, content) => {
|
|
2384
|
+
if (!enabled) return;
|
|
2385
|
+
setTooltip({ visible: true, x, y, content });
|
|
2378
2386
|
}, [enabled]);
|
|
2379
2387
|
const hide = import_react6.default.useCallback(() => {
|
|
2380
2388
|
cancelAnimationFrame(rafRef.current);
|
|
2381
2389
|
setTooltip((prev) => ({ ...prev, visible: false }));
|
|
2382
2390
|
}, []);
|
|
2383
|
-
return { tooltip, show, hide, move, containerRef };
|
|
2391
|
+
return { tooltip, show, showAt, hide, move, containerRef };
|
|
2384
2392
|
};
|
|
2385
2393
|
var GridLines = import_react6.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(import_jsx_runtime307.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
|
|
2386
2394
|
const y = PADDING.top + (1 - ratio) * chartH;
|
|
@@ -2445,7 +2453,7 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
2445
2453
|
}, [entries, seriesPoints]);
|
|
2446
2454
|
return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
|
|
2447
2455
|
};
|
|
2448
|
-
var LineChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2456
|
+
var LineChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
|
|
2449
2457
|
const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
|
|
2450
2458
|
const maxVal = import_react6.default.useMemo(() => {
|
|
2451
2459
|
const allValues = entries.flatMap(([, v]) => v);
|
|
@@ -2485,23 +2493,9 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
2485
2493
|
className: "chart-svg",
|
|
2486
2494
|
onMouseMove: (e) => {
|
|
2487
2495
|
handleMouseMove(e);
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
const points = seriesPoints[0];
|
|
2492
|
-
if (!points || points.length === 0) return;
|
|
2493
|
-
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2494
|
-
let closest = 0;
|
|
2495
|
-
let minDist = Math.abs(points[0].x - mx);
|
|
2496
|
-
for (let i = 1; i < points.length; i++) {
|
|
2497
|
-
const dist = Math.abs(points[i].x - mx);
|
|
2498
|
-
if (dist < minDist) {
|
|
2499
|
-
minDist = dist;
|
|
2500
|
-
closest = i;
|
|
2501
|
-
}
|
|
2502
|
-
}
|
|
2503
|
-
if (minDist <= step / 2) {
|
|
2504
|
-
onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
|
|
2496
|
+
if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
|
|
2497
|
+
const p = seriesPoints[0][activeIndex];
|
|
2498
|
+
onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
|
|
2505
2499
|
} else {
|
|
2506
2500
|
onLeave();
|
|
2507
2501
|
}
|
|
@@ -2569,7 +2563,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
2569
2563
|
);
|
|
2570
2564
|
});
|
|
2571
2565
|
LineChart.displayName = "LineChart";
|
|
2572
|
-
var CurveChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2566
|
+
var CurveChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
|
|
2573
2567
|
const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
|
|
2574
2568
|
const maxVal = import_react6.default.useMemo(() => {
|
|
2575
2569
|
const allValues = entries.flatMap(([, v]) => v);
|
|
@@ -2609,23 +2603,9 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
2609
2603
|
className: "chart-svg",
|
|
2610
2604
|
onMouseMove: (e) => {
|
|
2611
2605
|
handleMouseMove(e);
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
const points = seriesPoints[0];
|
|
2616
|
-
if (!points || points.length === 0) return;
|
|
2617
|
-
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2618
|
-
let closest = 0;
|
|
2619
|
-
let minDist = Math.abs(points[0].x - mx);
|
|
2620
|
-
for (let i = 1; i < points.length; i++) {
|
|
2621
|
-
const dist = Math.abs(points[i].x - mx);
|
|
2622
|
-
if (dist < minDist) {
|
|
2623
|
-
minDist = dist;
|
|
2624
|
-
closest = i;
|
|
2625
|
-
}
|
|
2626
|
-
}
|
|
2627
|
-
if (minDist <= step / 2) {
|
|
2628
|
-
onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
|
|
2606
|
+
if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
|
|
2607
|
+
const p = seriesPoints[0][activeIndex];
|
|
2608
|
+
onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
|
|
2629
2609
|
} else {
|
|
2630
2610
|
onLeave();
|
|
2631
2611
|
}
|
|
@@ -2693,7 +2673,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
2693
2673
|
);
|
|
2694
2674
|
});
|
|
2695
2675
|
CurveChart.displayName = "CurveChart";
|
|
2696
|
-
var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2676
|
+
var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
|
|
2697
2677
|
const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
|
|
2698
2678
|
const maxVal = import_react6.default.useMemo(() => {
|
|
2699
2679
|
const allValues = entries.flatMap(([, v]) => v);
|
|
@@ -2743,8 +2723,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
|
|
|
2743
2723
|
transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
|
|
2744
2724
|
animationDelay: `${delay}ms`
|
|
2745
2725
|
} : void 0,
|
|
2746
|
-
onMouseEnter: (
|
|
2747
|
-
onMouseMove: onMove,
|
|
2726
|
+
onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
|
|
2748
2727
|
onMouseLeave: onLeave
|
|
2749
2728
|
},
|
|
2750
2729
|
`${di}-${i}`
|
|
@@ -2832,30 +2811,14 @@ var PieDonutChart = import_react6.default.memo(
|
|
|
2832
2811
|
{
|
|
2833
2812
|
d: s.d,
|
|
2834
2813
|
fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
|
|
2835
|
-
className: "chart-slice"
|
|
2836
|
-
onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
|
|
2837
|
-
onMouseMove: onMove,
|
|
2838
|
-
onMouseLeave: onLeave
|
|
2814
|
+
className: "chart-slice"
|
|
2839
2815
|
}
|
|
2840
|
-
) }, i)) })
|
|
2841
|
-
sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
|
|
2842
|
-
"text",
|
|
2843
|
-
{
|
|
2844
|
-
x: s.lx,
|
|
2845
|
-
y: s.ly,
|
|
2846
|
-
className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
|
|
2847
|
-
style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
|
|
2848
|
-
textAnchor: "middle",
|
|
2849
|
-
dominantBaseline: "central",
|
|
2850
|
-
children: s.v
|
|
2851
|
-
},
|
|
2852
|
-
`label-${i}`
|
|
2853
|
-
))
|
|
2816
|
+
) }, i)) })
|
|
2854
2817
|
] });
|
|
2855
2818
|
}
|
|
2856
2819
|
);
|
|
2857
2820
|
PieDonutChart.displayName = "PieDonutChart";
|
|
2858
|
-
var
|
|
2821
|
+
var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
|
|
2859
2822
|
const ref = import_react6.default.useRef(null);
|
|
2860
2823
|
const [pos, setPos] = import_react6.default.useState({ left: 0, top: 0 });
|
|
2861
2824
|
import_react6.default.useLayoutEffect(() => {
|
|
@@ -2863,20 +2826,19 @@ var ChartTooltipPortal = ({ clientX, clientY, visible, children }) => {
|
|
|
2863
2826
|
if (!el) return;
|
|
2864
2827
|
const w = el.offsetWidth;
|
|
2865
2828
|
const h = el.offsetHeight;
|
|
2866
|
-
|
|
2867
|
-
let
|
|
2868
|
-
|
|
2869
|
-
if (
|
|
2870
|
-
if (
|
|
2871
|
-
if (left < 8) left = 8;
|
|
2829
|
+
let left = x + TOOLTIP_OFFSET;
|
|
2830
|
+
let top = y - h - TOOLTIP_OFFSET;
|
|
2831
|
+
if (left + w > containerWidth) left = x - w - TOOLTIP_OFFSET;
|
|
2832
|
+
if (top < 0) top = y + TOOLTIP_OFFSET;
|
|
2833
|
+
if (left < 0) left = 0;
|
|
2872
2834
|
setPos({ left, top });
|
|
2873
|
-
}, [
|
|
2835
|
+
}, [x, y, containerWidth, containerHeight]);
|
|
2874
2836
|
return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
|
|
2875
2837
|
"div",
|
|
2876
2838
|
{
|
|
2877
2839
|
ref,
|
|
2878
|
-
className:
|
|
2879
|
-
style: {
|
|
2840
|
+
className: "chart-tooltip chart-tooltip-show",
|
|
2841
|
+
style: { left: pos.left, top: pos.top },
|
|
2880
2842
|
children
|
|
2881
2843
|
}
|
|
2882
2844
|
);
|
|
@@ -2921,7 +2883,7 @@ var ChartLegend = ({ data, labels, type }) => {
|
|
|
2921
2883
|
};
|
|
2922
2884
|
var Chart = import_react6.default.memo((props) => {
|
|
2923
2885
|
const { type, data, labels, tooltip: showTooltip = true } = props;
|
|
2924
|
-
const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
2886
|
+
const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
2925
2887
|
const { width, height } = useChartSize(containerRef);
|
|
2926
2888
|
const stableData = import_react6.default.useMemo(() => data, [JSON.stringify(data)]);
|
|
2927
2889
|
const stableLabels = import_react6.default.useMemo(() => labels, [JSON.stringify(labels)]);
|
|
@@ -2929,13 +2891,13 @@ var Chart = import_react6.default.memo((props) => {
|
|
|
2929
2891
|
const animate = useChartAnimation(containerRef, dataKey);
|
|
2930
2892
|
const ready = width > 0 && height > 0;
|
|
2931
2893
|
return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
|
|
2932
|
-
ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2933
|
-
ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2934
|
-
ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2935
|
-
ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2936
|
-
ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
|
|
2894
|
+
ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2895
|
+
ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2896
|
+
ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2897
|
+
ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2898
|
+
ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2937
2899
|
ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
|
|
2938
|
-
tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
|
|
2900
|
+
tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
|
|
2939
2901
|
] });
|
|
2940
2902
|
});
|
|
2941
2903
|
Chart.displayName = "Chart";
|
|
@@ -1929,11 +1929,14 @@
|
|
|
1929
1929
|
width: 100%;
|
|
1930
1930
|
height: 100%;
|
|
1931
1931
|
position: relative;
|
|
1932
|
+
display: flex;
|
|
1933
|
+
flex-direction: column;
|
|
1932
1934
|
}
|
|
1933
1935
|
.lib-xplat-chart .chart-svg {
|
|
1934
1936
|
display: block;
|
|
1935
1937
|
width: 100%;
|
|
1936
|
-
|
|
1938
|
+
flex: 1;
|
|
1939
|
+
min-height: 0;
|
|
1937
1940
|
will-change: transform;
|
|
1938
1941
|
contain: layout style paint;
|
|
1939
1942
|
}
|
|
@@ -2017,7 +2020,19 @@
|
|
|
2017
2020
|
white-space: nowrap;
|
|
2018
2021
|
overflow: visible;
|
|
2019
2022
|
}
|
|
2023
|
+
.lib-xplat-chart .chart-bar-animate {
|
|
2024
|
+
animation: chart-bar-grow 800ms ease-out both;
|
|
2025
|
+
}
|
|
2026
|
+
.lib-xplat-chart .chart-pie-label-animate {
|
|
2027
|
+
opacity: 0;
|
|
2028
|
+
animation: chart-fade-in 150ms ease-out both;
|
|
2029
|
+
}
|
|
2030
|
+
.lib-xplat-chart .chart-area[style*=animationDelay] {
|
|
2031
|
+
animation: chart-fade-in 800ms ease-out both;
|
|
2032
|
+
}
|
|
2020
2033
|
.lib-xplat-chart .chart-tooltip {
|
|
2034
|
+
position: absolute;
|
|
2035
|
+
z-index: 10;
|
|
2021
2036
|
padding: var(--spacing-space-3);
|
|
2022
2037
|
background-color: var(--semantic-surface-neutral-strong);
|
|
2023
2038
|
color: var(--semantic-text-inverse);
|
|
@@ -2028,25 +2043,8 @@
|
|
|
2028
2043
|
max-width: 240px;
|
|
2029
2044
|
pointer-events: none;
|
|
2030
2045
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
2031
|
-
}
|
|
2032
|
-
.lib-xplat-chart .chart-tooltip.chart-tooltip-show {
|
|
2033
|
-
opacity: 1;
|
|
2034
2046
|
animation: chart-tooltip-in 120ms ease-out;
|
|
2035
2047
|
}
|
|
2036
|
-
.lib-xplat-chart .chart-tooltip.chart-tooltip-hide {
|
|
2037
|
-
opacity: 0;
|
|
2038
|
-
animation: chart-tooltip-out 80ms ease-in;
|
|
2039
|
-
}
|
|
2040
|
-
.lib-xplat-chart .chart-bar-animate {
|
|
2041
|
-
animation: chart-bar-grow 800ms ease-out both;
|
|
2042
|
-
}
|
|
2043
|
-
.lib-xplat-chart .chart-pie-label-animate {
|
|
2044
|
-
opacity: 0;
|
|
2045
|
-
animation: chart-fade-in 150ms ease-out both;
|
|
2046
|
-
}
|
|
2047
|
-
.lib-xplat-chart .chart-area[style*=animationDelay] {
|
|
2048
|
-
animation: chart-fade-in 800ms ease-out both;
|
|
2049
|
-
}
|
|
2050
2048
|
.lib-xplat-chart .chart-legend {
|
|
2051
2049
|
display: flex;
|
|
2052
2050
|
flex-wrap: wrap;
|
|
@@ -2103,14 +2101,6 @@
|
|
|
2103
2101
|
opacity: 1;
|
|
2104
2102
|
}
|
|
2105
2103
|
}
|
|
2106
|
-
@keyframes chart-tooltip-out {
|
|
2107
|
-
from {
|
|
2108
|
-
opacity: 1;
|
|
2109
|
-
}
|
|
2110
|
-
to {
|
|
2111
|
-
opacity: 0;
|
|
2112
|
-
}
|
|
2113
|
-
}
|
|
2114
2104
|
@media (prefers-reduced-motion: reduce) {
|
|
2115
2105
|
.lib-xplat-chart .chart-bar-animate,
|
|
2116
2106
|
.lib-xplat-chart .chart-pie-label-animate,
|
package/dist/components/index.js
CHANGED
|
@@ -2267,8 +2267,8 @@ var TOOLTIP_OFFSET = 12;
|
|
|
2267
2267
|
var useChartTooltip = (enabled) => {
|
|
2268
2268
|
const [tooltip, setTooltip] = React6.useState({
|
|
2269
2269
|
visible: false,
|
|
2270
|
-
|
|
2271
|
-
|
|
2270
|
+
x: 0,
|
|
2271
|
+
y: 0,
|
|
2272
2272
|
content: ""
|
|
2273
2273
|
});
|
|
2274
2274
|
const containerRef = React6.useRef(null);
|
|
@@ -2279,18 +2279,26 @@ var useChartTooltip = (enabled) => {
|
|
|
2279
2279
|
const cy = e.clientY;
|
|
2280
2280
|
cancelAnimationFrame(rafRef.current);
|
|
2281
2281
|
rafRef.current = requestAnimationFrame(() => {
|
|
2282
|
-
|
|
2282
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2283
|
+
if (!rect) return;
|
|
2284
|
+
setTooltip((prev) => ({ ...prev, x: cx - rect.left, y: cy - rect.top }));
|
|
2283
2285
|
});
|
|
2284
2286
|
}, [enabled]);
|
|
2285
2287
|
const show = React6.useCallback((e, content) => {
|
|
2286
2288
|
if (!enabled) return;
|
|
2287
|
-
|
|
2289
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2290
|
+
if (!rect) return;
|
|
2291
|
+
setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
|
|
2292
|
+
}, [enabled]);
|
|
2293
|
+
const showAt = React6.useCallback((x, y, content) => {
|
|
2294
|
+
if (!enabled) return;
|
|
2295
|
+
setTooltip({ visible: true, x, y, content });
|
|
2288
2296
|
}, [enabled]);
|
|
2289
2297
|
const hide = React6.useCallback(() => {
|
|
2290
2298
|
cancelAnimationFrame(rafRef.current);
|
|
2291
2299
|
setTooltip((prev) => ({ ...prev, visible: false }));
|
|
2292
2300
|
}, []);
|
|
2293
|
-
return { tooltip, show, hide, move, containerRef };
|
|
2301
|
+
return { tooltip, show, showAt, hide, move, containerRef };
|
|
2294
2302
|
};
|
|
2295
2303
|
var GridLines = React6.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ jsx307(Fragment2, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
|
|
2296
2304
|
const y = PADDING.top + (1 - ratio) * chartH;
|
|
@@ -2355,7 +2363,7 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
2355
2363
|
}, [entries, seriesPoints]);
|
|
2356
2364
|
return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
|
|
2357
2365
|
};
|
|
2358
|
-
var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2366
|
+
var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
|
|
2359
2367
|
const entries = React6.useMemo(() => Object.entries(data), [data]);
|
|
2360
2368
|
const maxVal = React6.useMemo(() => {
|
|
2361
2369
|
const allValues = entries.flatMap(([, v]) => v);
|
|
@@ -2395,23 +2403,9 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2395
2403
|
className: "chart-svg",
|
|
2396
2404
|
onMouseMove: (e) => {
|
|
2397
2405
|
handleMouseMove(e);
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
const points = seriesPoints[0];
|
|
2402
|
-
if (!points || points.length === 0) return;
|
|
2403
|
-
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2404
|
-
let closest = 0;
|
|
2405
|
-
let minDist = Math.abs(points[0].x - mx);
|
|
2406
|
-
for (let i = 1; i < points.length; i++) {
|
|
2407
|
-
const dist = Math.abs(points[i].x - mx);
|
|
2408
|
-
if (dist < minDist) {
|
|
2409
|
-
minDist = dist;
|
|
2410
|
-
closest = i;
|
|
2411
|
-
}
|
|
2412
|
-
}
|
|
2413
|
-
if (minDist <= step / 2) {
|
|
2414
|
-
onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
|
|
2406
|
+
if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
|
|
2407
|
+
const p = seriesPoints[0][activeIndex];
|
|
2408
|
+
onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
|
|
2415
2409
|
} else {
|
|
2416
2410
|
onLeave();
|
|
2417
2411
|
}
|
|
@@ -2479,7 +2473,7 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2479
2473
|
);
|
|
2480
2474
|
});
|
|
2481
2475
|
LineChart.displayName = "LineChart";
|
|
2482
|
-
var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2476
|
+
var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
|
|
2483
2477
|
const entries = React6.useMemo(() => Object.entries(data), [data]);
|
|
2484
2478
|
const maxVal = React6.useMemo(() => {
|
|
2485
2479
|
const allValues = entries.flatMap(([, v]) => v);
|
|
@@ -2519,23 +2513,9 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2519
2513
|
className: "chart-svg",
|
|
2520
2514
|
onMouseMove: (e) => {
|
|
2521
2515
|
handleMouseMove(e);
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
const points = seriesPoints[0];
|
|
2526
|
-
if (!points || points.length === 0) return;
|
|
2527
|
-
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2528
|
-
let closest = 0;
|
|
2529
|
-
let minDist = Math.abs(points[0].x - mx);
|
|
2530
|
-
for (let i = 1; i < points.length; i++) {
|
|
2531
|
-
const dist = Math.abs(points[i].x - mx);
|
|
2532
|
-
if (dist < minDist) {
|
|
2533
|
-
minDist = dist;
|
|
2534
|
-
closest = i;
|
|
2535
|
-
}
|
|
2536
|
-
}
|
|
2537
|
-
if (minDist <= step / 2) {
|
|
2538
|
-
onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
|
|
2516
|
+
if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
|
|
2517
|
+
const p = seriesPoints[0][activeIndex];
|
|
2518
|
+
onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
|
|
2539
2519
|
} else {
|
|
2540
2520
|
onLeave();
|
|
2541
2521
|
}
|
|
@@ -2603,7 +2583,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2603
2583
|
);
|
|
2604
2584
|
});
|
|
2605
2585
|
CurveChart.displayName = "CurveChart";
|
|
2606
|
-
var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2586
|
+
var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
|
|
2607
2587
|
const entries = React6.useMemo(() => Object.entries(data), [data]);
|
|
2608
2588
|
const maxVal = React6.useMemo(() => {
|
|
2609
2589
|
const allValues = entries.flatMap(([, v]) => v);
|
|
@@ -2653,8 +2633,7 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onM
|
|
|
2653
2633
|
transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
|
|
2654
2634
|
animationDelay: `${delay}ms`
|
|
2655
2635
|
} : void 0,
|
|
2656
|
-
onMouseEnter: (
|
|
2657
|
-
onMouseMove: onMove,
|
|
2636
|
+
onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
|
|
2658
2637
|
onMouseLeave: onLeave
|
|
2659
2638
|
},
|
|
2660
2639
|
`${di}-${i}`
|
|
@@ -2742,30 +2721,14 @@ var PieDonutChart = React6.memo(
|
|
|
2742
2721
|
{
|
|
2743
2722
|
d: s.d,
|
|
2744
2723
|
fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
|
|
2745
|
-
className: "chart-slice"
|
|
2746
|
-
onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
|
|
2747
|
-
onMouseMove: onMove,
|
|
2748
|
-
onMouseLeave: onLeave
|
|
2724
|
+
className: "chart-slice"
|
|
2749
2725
|
}
|
|
2750
|
-
) }, i)) })
|
|
2751
|
-
sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ jsx307(
|
|
2752
|
-
"text",
|
|
2753
|
-
{
|
|
2754
|
-
x: s.lx,
|
|
2755
|
-
y: s.ly,
|
|
2756
|
-
className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
|
|
2757
|
-
style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
|
|
2758
|
-
textAnchor: "middle",
|
|
2759
|
-
dominantBaseline: "central",
|
|
2760
|
-
children: s.v
|
|
2761
|
-
},
|
|
2762
|
-
`label-${i}`
|
|
2763
|
-
))
|
|
2726
|
+
) }, i)) })
|
|
2764
2727
|
] });
|
|
2765
2728
|
}
|
|
2766
2729
|
);
|
|
2767
2730
|
PieDonutChart.displayName = "PieDonutChart";
|
|
2768
|
-
var
|
|
2731
|
+
var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
|
|
2769
2732
|
const ref = React6.useRef(null);
|
|
2770
2733
|
const [pos, setPos] = React6.useState({ left: 0, top: 0 });
|
|
2771
2734
|
React6.useLayoutEffect(() => {
|
|
@@ -2773,20 +2736,19 @@ var ChartTooltipPortal = ({ clientX, clientY, visible, children }) => {
|
|
|
2773
2736
|
if (!el) return;
|
|
2774
2737
|
const w = el.offsetWidth;
|
|
2775
2738
|
const h = el.offsetHeight;
|
|
2776
|
-
|
|
2777
|
-
let
|
|
2778
|
-
|
|
2779
|
-
if (
|
|
2780
|
-
if (
|
|
2781
|
-
if (left < 8) left = 8;
|
|
2739
|
+
let left = x + TOOLTIP_OFFSET;
|
|
2740
|
+
let top = y - h - TOOLTIP_OFFSET;
|
|
2741
|
+
if (left + w > containerWidth) left = x - w - TOOLTIP_OFFSET;
|
|
2742
|
+
if (top < 0) top = y + TOOLTIP_OFFSET;
|
|
2743
|
+
if (left < 0) left = 0;
|
|
2782
2744
|
setPos({ left, top });
|
|
2783
|
-
}, [
|
|
2745
|
+
}, [x, y, containerWidth, containerHeight]);
|
|
2784
2746
|
return /* @__PURE__ */ jsx307(
|
|
2785
2747
|
"div",
|
|
2786
2748
|
{
|
|
2787
2749
|
ref,
|
|
2788
|
-
className:
|
|
2789
|
-
style: {
|
|
2750
|
+
className: "chart-tooltip chart-tooltip-show",
|
|
2751
|
+
style: { left: pos.left, top: pos.top },
|
|
2790
2752
|
children
|
|
2791
2753
|
}
|
|
2792
2754
|
);
|
|
@@ -2831,7 +2793,7 @@ var ChartLegend = ({ data, labels, type }) => {
|
|
|
2831
2793
|
};
|
|
2832
2794
|
var Chart = React6.memo((props) => {
|
|
2833
2795
|
const { type, data, labels, tooltip: showTooltip = true } = props;
|
|
2834
|
-
const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
2796
|
+
const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
2835
2797
|
const { width, height } = useChartSize(containerRef);
|
|
2836
2798
|
const stableData = React6.useMemo(() => data, [JSON.stringify(data)]);
|
|
2837
2799
|
const stableLabels = React6.useMemo(() => labels, [JSON.stringify(labels)]);
|
|
@@ -2839,13 +2801,13 @@ var Chart = React6.memo((props) => {
|
|
|
2839
2801
|
const animate = useChartAnimation(containerRef, dataKey);
|
|
2840
2802
|
const ready = width > 0 && height > 0;
|
|
2841
2803
|
return /* @__PURE__ */ jsxs197("div", { className: "lib-xplat-chart", ref: containerRef, children: [
|
|
2842
|
-
ready && type === "line" && /* @__PURE__ */ jsx307(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2843
|
-
ready && type === "curve" && /* @__PURE__ */ jsx307(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2844
|
-
ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2845
|
-
ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2846
|
-
ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
|
|
2804
|
+
ready && type === "line" && /* @__PURE__ */ jsx307(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2805
|
+
ready && type === "curve" && /* @__PURE__ */ jsx307(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2806
|
+
ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2807
|
+
ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2808
|
+
ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
|
|
2847
2809
|
ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
|
|
2848
|
-
tooltip.content && /* @__PURE__ */ jsx307(
|
|
2810
|
+
tooltip.visible && tooltip.content && /* @__PURE__ */ jsx307(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
|
|
2849
2811
|
] });
|
|
2850
2812
|
});
|
|
2851
2813
|
Chart.displayName = "Chart";
|