@x-plat/design-system 0.5.32 → 0.5.33
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 +121 -61
- package/dist/components/Chart/index.css +54 -10
- package/dist/components/Chart/index.js +121 -61
- package/dist/components/index.cjs +121 -61
- package/dist/components/index.css +54 -10
- package/dist/components/index.js +121 -61
- package/dist/index.cjs +121 -61
- package/dist/index.css +54 -10
- package/dist/index.js +121 -61
- package/package.json +1 -1
|
@@ -2000,9 +2000,9 @@
|
|
|
2000
2000
|
opacity: 1;
|
|
2001
2001
|
}
|
|
2002
2002
|
.lib-xplat-chart .chart-crosshair {
|
|
2003
|
-
stroke: var(--semantic-border-
|
|
2003
|
+
stroke: var(--semantic-border-strong);
|
|
2004
2004
|
stroke-width: 1;
|
|
2005
|
-
stroke-dasharray: 4
|
|
2005
|
+
stroke-dasharray: 4 3;
|
|
2006
2006
|
pointer-events: none;
|
|
2007
2007
|
}
|
|
2008
2008
|
.lib-xplat-chart .chart-point-active {
|
|
@@ -2018,18 +2018,24 @@
|
|
|
2018
2018
|
overflow: visible;
|
|
2019
2019
|
}
|
|
2020
2020
|
.lib-xplat-chart .chart-tooltip {
|
|
2021
|
-
|
|
2022
|
-
transform: translate(-50%, -100%);
|
|
2023
|
-
padding: var(--spacing-space-2) var(--spacing-space-3);
|
|
2021
|
+
padding: var(--spacing-space-3);
|
|
2024
2022
|
background-color: var(--semantic-surface-neutral-strong);
|
|
2025
2023
|
color: var(--semantic-text-inverse);
|
|
2026
2024
|
font-size: 12px;
|
|
2025
|
+
line-height: 18px;
|
|
2027
2026
|
font-weight: 500;
|
|
2028
2027
|
border-radius: var(--spacing-radius-md);
|
|
2029
|
-
|
|
2028
|
+
max-width: 240px;
|
|
2030
2029
|
pointer-events: none;
|
|
2031
|
-
|
|
2032
|
-
|
|
2030
|
+
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
|
+
animation: chart-tooltip-in 120ms ease-out;
|
|
2035
|
+
}
|
|
2036
|
+
.lib-xplat-chart .chart-tooltip.chart-tooltip-hide {
|
|
2037
|
+
opacity: 0;
|
|
2038
|
+
animation: chart-tooltip-out 80ms ease-in;
|
|
2033
2039
|
}
|
|
2034
2040
|
.lib-xplat-chart .chart-bar-animate {
|
|
2035
2041
|
animation: chart-bar-grow 800ms ease-out both;
|
|
@@ -2041,6 +2047,38 @@
|
|
|
2041
2047
|
.lib-xplat-chart .chart-area[style*=animationDelay] {
|
|
2042
2048
|
animation: chart-fade-in 800ms ease-out both;
|
|
2043
2049
|
}
|
|
2050
|
+
.lib-xplat-chart .chart-legend {
|
|
2051
|
+
display: flex;
|
|
2052
|
+
flex-wrap: wrap;
|
|
2053
|
+
justify-content: center;
|
|
2054
|
+
gap: var(--spacing-space-4);
|
|
2055
|
+
padding: var(--spacing-space-3) 0;
|
|
2056
|
+
}
|
|
2057
|
+
.lib-xplat-chart .chart-legend-item {
|
|
2058
|
+
display: flex;
|
|
2059
|
+
align-items: flex-start;
|
|
2060
|
+
gap: var(--spacing-space-2);
|
|
2061
|
+
}
|
|
2062
|
+
.lib-xplat-chart .chart-legend-dot {
|
|
2063
|
+
flex-shrink: 0;
|
|
2064
|
+
width: 10px;
|
|
2065
|
+
height: 10px;
|
|
2066
|
+
border-radius: 50%;
|
|
2067
|
+
margin-top: 3px;
|
|
2068
|
+
}
|
|
2069
|
+
.lib-xplat-chart .chart-legend-text {
|
|
2070
|
+
display: flex;
|
|
2071
|
+
flex-direction: column;
|
|
2072
|
+
}
|
|
2073
|
+
.lib-xplat-chart .chart-legend-label {
|
|
2074
|
+
font-size: 12px;
|
|
2075
|
+
color: var(--semantic-text-muted);
|
|
2076
|
+
}
|
|
2077
|
+
.lib-xplat-chart .chart-legend-value {
|
|
2078
|
+
font-size: 14px;
|
|
2079
|
+
font-weight: 600;
|
|
2080
|
+
color: var(--semantic-text-strong);
|
|
2081
|
+
}
|
|
2044
2082
|
@keyframes chart-bar-grow {
|
|
2045
2083
|
from {
|
|
2046
2084
|
transform: scaleY(0);
|
|
@@ -2060,11 +2098,17 @@
|
|
|
2060
2098
|
@keyframes chart-tooltip-in {
|
|
2061
2099
|
from {
|
|
2062
2100
|
opacity: 0;
|
|
2063
|
-
transform: translate(-50%, -90%);
|
|
2064
2101
|
}
|
|
2065
2102
|
to {
|
|
2066
2103
|
opacity: 1;
|
|
2067
|
-
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
@keyframes chart-tooltip-out {
|
|
2107
|
+
from {
|
|
2108
|
+
opacity: 1;
|
|
2109
|
+
}
|
|
2110
|
+
to {
|
|
2111
|
+
opacity: 0;
|
|
2068
2112
|
}
|
|
2069
2113
|
}
|
|
2070
2114
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/components/index.js
CHANGED
|
@@ -2261,40 +2261,28 @@ var useChartAnimation = (containerRef, dataKey) => {
|
|
|
2261
2261
|
}, [dataKey]);
|
|
2262
2262
|
return animate || prefersReducedMotion();
|
|
2263
2263
|
};
|
|
2264
|
+
var TOOLTIP_OFFSET = 12;
|
|
2264
2265
|
var useChartTooltip = (enabled) => {
|
|
2265
2266
|
const [tooltip, setTooltip] = React6.useState({
|
|
2266
2267
|
visible: false,
|
|
2267
|
-
|
|
2268
|
-
|
|
2268
|
+
clientX: 0,
|
|
2269
|
+
clientY: 0,
|
|
2269
2270
|
content: ""
|
|
2270
2271
|
});
|
|
2271
2272
|
const containerRef = React6.useRef(null);
|
|
2272
2273
|
const rafRef = React6.useRef(0);
|
|
2273
2274
|
const move = React6.useCallback((e) => {
|
|
2274
2275
|
if (!enabled) return;
|
|
2275
|
-
const
|
|
2276
|
-
const
|
|
2276
|
+
const cx = e.clientX;
|
|
2277
|
+
const cy = e.clientY;
|
|
2277
2278
|
cancelAnimationFrame(rafRef.current);
|
|
2278
2279
|
rafRef.current = requestAnimationFrame(() => {
|
|
2279
|
-
|
|
2280
|
-
if (!rect) return;
|
|
2281
|
-
setTooltip((prev) => ({
|
|
2282
|
-
...prev,
|
|
2283
|
-
x: clientX - rect.left,
|
|
2284
|
-
y: clientY - rect.top - 12
|
|
2285
|
-
}));
|
|
2280
|
+
setTooltip((prev) => ({ ...prev, clientX: cx, clientY: cy }));
|
|
2286
2281
|
});
|
|
2287
2282
|
}, [enabled]);
|
|
2288
2283
|
const show = React6.useCallback((e, content) => {
|
|
2289
2284
|
if (!enabled) return;
|
|
2290
|
-
|
|
2291
|
-
if (!rect) return;
|
|
2292
|
-
setTooltip({
|
|
2293
|
-
visible: true,
|
|
2294
|
-
x: e.clientX - rect.left,
|
|
2295
|
-
y: e.clientY - rect.top - 12,
|
|
2296
|
-
content
|
|
2297
|
-
});
|
|
2285
|
+
setTooltip({ visible: true, clientX: e.clientX, clientY: e.clientY, content });
|
|
2298
2286
|
}, [enabled]);
|
|
2299
2287
|
const hide = React6.useCallback(() => {
|
|
2300
2288
|
cancelAnimationFrame(rafRef.current);
|
|
@@ -2328,14 +2316,14 @@ var AxisLabels = React6.memo(({ labels, count, chartW, height }) => {
|
|
|
2328
2316
|
AxisLabels.displayName = "AxisLabels";
|
|
2329
2317
|
var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
2330
2318
|
const [activeIndex, setActiveIndex] = React6.useState(null);
|
|
2331
|
-
const [mouseX, setMouseX] = React6.useState(null);
|
|
2332
2319
|
const handleMouseMove = React6.useCallback((e) => {
|
|
2333
2320
|
const svg = e.currentTarget;
|
|
2334
2321
|
const rect = svg.getBoundingClientRect();
|
|
2335
2322
|
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
2336
|
-
setMouseX(mx);
|
|
2337
2323
|
if (seriesPoints.length === 0 || seriesPoints[0].length === 0) return;
|
|
2338
2324
|
const points = seriesPoints[0];
|
|
2325
|
+
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2326
|
+
const threshold = step / 2;
|
|
2339
2327
|
let closest = 0;
|
|
2340
2328
|
let minDist = Math.abs(points[0].x - mx);
|
|
2341
2329
|
for (let i = 1; i < points.length; i++) {
|
|
@@ -2345,11 +2333,10 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
2345
2333
|
closest = i;
|
|
2346
2334
|
}
|
|
2347
2335
|
}
|
|
2348
|
-
setActiveIndex(closest);
|
|
2336
|
+
setActiveIndex(minDist <= threshold ? closest : null);
|
|
2349
2337
|
}, [seriesPoints]);
|
|
2350
2338
|
const handleMouseLeave = React6.useCallback(() => {
|
|
2351
2339
|
setActiveIndex(null);
|
|
2352
|
-
setMouseX(null);
|
|
2353
2340
|
}, []);
|
|
2354
2341
|
const tooltipContent = React6.useMemo(() => {
|
|
2355
2342
|
if (activeIndex === null) return "";
|
|
@@ -2358,7 +2345,13 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
2358
2345
|
return p ? `${key}: ${p.v}` : "";
|
|
2359
2346
|
}).filter(Boolean).join(" / ");
|
|
2360
2347
|
}, [activeIndex, entries, seriesPoints]);
|
|
2361
|
-
|
|
2348
|
+
const getTooltipAt = React6.useCallback((idx) => {
|
|
2349
|
+
return entries.map(([key], di) => {
|
|
2350
|
+
const p = seriesPoints[di]?.[idx];
|
|
2351
|
+
return p ? `${key}: ${p.v}` : "";
|
|
2352
|
+
}).filter(Boolean).join(" / ");
|
|
2353
|
+
}, [entries, seriesPoints]);
|
|
2354
|
+
return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
|
|
2362
2355
|
};
|
|
2363
2356
|
var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2364
2357
|
const entries = React6.useMemo(() => Object.entries(data), [data]);
|
|
@@ -2381,7 +2374,7 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2381
2374
|
);
|
|
2382
2375
|
const lineRefs = React6.useRef([]);
|
|
2383
2376
|
const clipRef = React6.useRef(null);
|
|
2384
|
-
const { activeIndex,
|
|
2377
|
+
const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
|
|
2385
2378
|
React6.useEffect(() => {
|
|
2386
2379
|
if (!animate) return;
|
|
2387
2380
|
lineRefs.current.forEach((el) => {
|
|
@@ -2404,8 +2397,7 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2404
2397
|
});
|
|
2405
2398
|
}
|
|
2406
2399
|
}, [animate, seriesPoints, width]);
|
|
2407
|
-
const
|
|
2408
|
-
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x : null;
|
|
2400
|
+
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
|
|
2409
2401
|
const lineClipId = "line-area-clip";
|
|
2410
2402
|
return /* @__PURE__ */ jsxs197(
|
|
2411
2403
|
"svg",
|
|
@@ -2414,7 +2406,26 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2414
2406
|
className: "chart-svg",
|
|
2415
2407
|
onMouseMove: (e) => {
|
|
2416
2408
|
handleMouseMove(e);
|
|
2417
|
-
|
|
2409
|
+
const svg = e.currentTarget;
|
|
2410
|
+
const rect = svg.getBoundingClientRect();
|
|
2411
|
+
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
2412
|
+
const points = seriesPoints[0];
|
|
2413
|
+
if (!points || points.length === 0) return;
|
|
2414
|
+
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2415
|
+
let closest = 0;
|
|
2416
|
+
let minDist = Math.abs(points[0].x - mx);
|
|
2417
|
+
for (let i = 1; i < points.length; i++) {
|
|
2418
|
+
const dist = Math.abs(points[i].x - mx);
|
|
2419
|
+
if (dist < minDist) {
|
|
2420
|
+
minDist = dist;
|
|
2421
|
+
closest = i;
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
if (minDist <= step / 2) {
|
|
2425
|
+
onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
|
|
2426
|
+
} else {
|
|
2427
|
+
onLeave();
|
|
2428
|
+
}
|
|
2418
2429
|
},
|
|
2419
2430
|
onMouseLeave: () => {
|
|
2420
2431
|
handleMouseLeave();
|
|
@@ -2469,21 +2480,16 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2469
2480
|
)
|
|
2470
2481
|
] }, di);
|
|
2471
2482
|
}),
|
|
2472
|
-
|
|
2483
|
+
activeX !== null && /* @__PURE__ */ jsx307(
|
|
2473
2484
|
"line",
|
|
2474
2485
|
{
|
|
2475
|
-
x1:
|
|
2486
|
+
x1: activeX,
|
|
2476
2487
|
y1: PADDING.top,
|
|
2477
|
-
x2:
|
|
2488
|
+
x2: activeX,
|
|
2478
2489
|
y2: PADDING.top + chartH,
|
|
2479
2490
|
className: "chart-crosshair"
|
|
2480
2491
|
}
|
|
2481
2492
|
),
|
|
2482
|
-
activeIndex !== null && activeX !== null && /* @__PURE__ */ jsx307("foreignObject", { x: activeX - 100, y: 0, width: "200", height: PADDING.top, children: /* @__PURE__ */ jsxs197("div", { className: "chart-crosshair-label", children: [
|
|
2483
|
-
labels[activeIndex],
|
|
2484
|
-
" \u2014 ",
|
|
2485
|
-
tooltipContent
|
|
2486
|
-
] }) }),
|
|
2487
2493
|
/* @__PURE__ */ jsx307(
|
|
2488
2494
|
"rect",
|
|
2489
2495
|
{
|
|
@@ -2521,7 +2527,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2521
2527
|
);
|
|
2522
2528
|
const lineRefs = React6.useRef([]);
|
|
2523
2529
|
const curveClipRef = React6.useRef(null);
|
|
2524
|
-
const { activeIndex,
|
|
2530
|
+
const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
|
|
2525
2531
|
React6.useEffect(() => {
|
|
2526
2532
|
if (!animate) return;
|
|
2527
2533
|
lineRefs.current.forEach((el) => {
|
|
@@ -2544,8 +2550,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2544
2550
|
});
|
|
2545
2551
|
}
|
|
2546
2552
|
}, [animate, seriesPoints, width]);
|
|
2547
|
-
const
|
|
2548
|
-
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x : null;
|
|
2553
|
+
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
|
|
2549
2554
|
const curveClipId = "curve-area-clip";
|
|
2550
2555
|
return /* @__PURE__ */ jsxs197(
|
|
2551
2556
|
"svg",
|
|
@@ -2554,7 +2559,26 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2554
2559
|
className: "chart-svg",
|
|
2555
2560
|
onMouseMove: (e) => {
|
|
2556
2561
|
handleMouseMove(e);
|
|
2557
|
-
|
|
2562
|
+
const svg = e.currentTarget;
|
|
2563
|
+
const rect = svg.getBoundingClientRect();
|
|
2564
|
+
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
2565
|
+
const points = seriesPoints[0];
|
|
2566
|
+
if (!points || points.length === 0) return;
|
|
2567
|
+
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2568
|
+
let closest = 0;
|
|
2569
|
+
let minDist = Math.abs(points[0].x - mx);
|
|
2570
|
+
for (let i = 1; i < points.length; i++) {
|
|
2571
|
+
const dist = Math.abs(points[i].x - mx);
|
|
2572
|
+
if (dist < minDist) {
|
|
2573
|
+
minDist = dist;
|
|
2574
|
+
closest = i;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
if (minDist <= step / 2) {
|
|
2578
|
+
onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
|
|
2579
|
+
} else {
|
|
2580
|
+
onLeave();
|
|
2581
|
+
}
|
|
2558
2582
|
},
|
|
2559
2583
|
onMouseLeave: () => {
|
|
2560
2584
|
handleMouseLeave();
|
|
@@ -2609,21 +2633,16 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2609
2633
|
)
|
|
2610
2634
|
] }, di);
|
|
2611
2635
|
}),
|
|
2612
|
-
|
|
2636
|
+
activeX !== null && /* @__PURE__ */ jsx307(
|
|
2613
2637
|
"line",
|
|
2614
2638
|
{
|
|
2615
|
-
x1:
|
|
2639
|
+
x1: activeX,
|
|
2616
2640
|
y1: PADDING.top,
|
|
2617
|
-
x2:
|
|
2641
|
+
x2: activeX,
|
|
2618
2642
|
y2: PADDING.top + chartH,
|
|
2619
2643
|
className: "chart-crosshair"
|
|
2620
2644
|
}
|
|
2621
2645
|
),
|
|
2622
|
-
activeIndex !== null && activeX !== null && /* @__PURE__ */ jsx307("foreignObject", { x: activeX - 100, y: 0, width: "200", height: PADDING.top, children: /* @__PURE__ */ jsxs197("div", { className: "chart-crosshair-label", children: [
|
|
2623
|
-
labels[activeIndex],
|
|
2624
|
-
" \u2014 ",
|
|
2625
|
-
tooltipContent
|
|
2626
|
-
] }) }),
|
|
2627
2646
|
/* @__PURE__ */ jsx307(
|
|
2628
2647
|
"rect",
|
|
2629
2648
|
{
|
|
@@ -2802,30 +2821,70 @@ var PieDonutChart = React6.memo(
|
|
|
2802
2821
|
}
|
|
2803
2822
|
);
|
|
2804
2823
|
PieDonutChart.displayName = "PieDonutChart";
|
|
2805
|
-
var
|
|
2824
|
+
var ChartTooltipPortal = ({ clientX, clientY, visible, children }) => {
|
|
2806
2825
|
const ref = React6.useRef(null);
|
|
2807
|
-
const [
|
|
2808
|
-
React6.
|
|
2826
|
+
const [pos, setPos] = React6.useState({ left: 0, top: 0 });
|
|
2827
|
+
React6.useLayoutEffect(() => {
|
|
2809
2828
|
const el = ref.current;
|
|
2810
2829
|
if (!el) return;
|
|
2811
2830
|
const w = el.offsetWidth;
|
|
2812
|
-
const
|
|
2813
|
-
const
|
|
2814
|
-
let
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2831
|
+
const h = el.offsetHeight;
|
|
2832
|
+
const vw = window.innerWidth;
|
|
2833
|
+
let left = clientX + TOOLTIP_OFFSET;
|
|
2834
|
+
let top = clientY - h - TOOLTIP_OFFSET;
|
|
2835
|
+
if (left + w > vw - 8) left = clientX - w - TOOLTIP_OFFSET;
|
|
2836
|
+
if (top < 8) top = clientY + TOOLTIP_OFFSET;
|
|
2837
|
+
if (left < 8) left = 8;
|
|
2838
|
+
setPos({ left, top });
|
|
2839
|
+
}, [clientX, clientY]);
|
|
2819
2840
|
return /* @__PURE__ */ jsx307(
|
|
2820
2841
|
"div",
|
|
2821
2842
|
{
|
|
2822
2843
|
ref,
|
|
2823
|
-
className: "chart-tooltip"
|
|
2824
|
-
style: { left:
|
|
2844
|
+
className: `chart-tooltip ${visible ? "chart-tooltip-show" : "chart-tooltip-hide"}`,
|
|
2845
|
+
style: { position: "fixed", left: pos.left, top: pos.top, zIndex: 1100 },
|
|
2825
2846
|
children
|
|
2826
2847
|
}
|
|
2827
2848
|
);
|
|
2828
2849
|
};
|
|
2850
|
+
var ChartLegend = ({ data, labels, type }) => {
|
|
2851
|
+
const entries = Object.entries(data);
|
|
2852
|
+
if (type === "pie" || type === "doughnut") {
|
|
2853
|
+
const values = entries.flatMap(([, v]) => v);
|
|
2854
|
+
const total = values.reduce((a, b) => a + b, 0) || 1;
|
|
2855
|
+
const firstKey = entries[0]?.[0] ?? "";
|
|
2856
|
+
const colorOffset = hashString(firstKey);
|
|
2857
|
+
return /* @__PURE__ */ jsx307("div", { className: "chart-legend", children: values.map((v, i) => {
|
|
2858
|
+
const pct = Math.round(v / total * 100);
|
|
2859
|
+
const color = PIE_COLORS[(i + colorOffset) % PIE_COLORS.length];
|
|
2860
|
+
return /* @__PURE__ */ jsxs197("div", { className: "chart-legend-item", children: [
|
|
2861
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
|
|
2862
|
+
/* @__PURE__ */ jsxs197("div", { className: "chart-legend-text", children: [
|
|
2863
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
|
|
2864
|
+
/* @__PURE__ */ jsxs197("span", { className: "chart-legend-value", children: [
|
|
2865
|
+
v.toLocaleString(),
|
|
2866
|
+
"(",
|
|
2867
|
+
pct,
|
|
2868
|
+
"%)"
|
|
2869
|
+
] })
|
|
2870
|
+
] })
|
|
2871
|
+
] }, i);
|
|
2872
|
+
}) });
|
|
2873
|
+
}
|
|
2874
|
+
return /* @__PURE__ */ jsx307("div", { className: "chart-legend", children: entries.map(([key], di) => {
|
|
2875
|
+
const palette = getPalette(LINE_BAR_PALETTES, di, key);
|
|
2876
|
+
const color = palette[2];
|
|
2877
|
+
const values = entries[di][1];
|
|
2878
|
+
const sum = values.reduce((a, b) => a + b, 0);
|
|
2879
|
+
return /* @__PURE__ */ jsxs197("div", { className: "chart-legend-item", children: [
|
|
2880
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
|
|
2881
|
+
/* @__PURE__ */ jsxs197("div", { className: "chart-legend-text", children: [
|
|
2882
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-label", children: key }),
|
|
2883
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-value", children: sum.toLocaleString() })
|
|
2884
|
+
] })
|
|
2885
|
+
] }, di);
|
|
2886
|
+
}) });
|
|
2887
|
+
};
|
|
2829
2888
|
var Chart = React6.memo((props) => {
|
|
2830
2889
|
const { type, data, labels, tooltip: showTooltip = true } = props;
|
|
2831
2890
|
const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
@@ -2841,7 +2900,8 @@ var Chart = React6.memo((props) => {
|
|
|
2841
2900
|
ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2842
2901
|
ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2843
2902
|
ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
|
|
2844
|
-
|
|
2903
|
+
ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
|
|
2904
|
+
tooltip.content && /* @__PURE__ */ jsx307(ChartTooltipPortal, { clientX: tooltip.clientX, clientY: tooltip.clientY, visible: tooltip.visible, children: tooltip.content })
|
|
2845
2905
|
] });
|
|
2846
2906
|
});
|
|
2847
2907
|
Chart.displayName = "Chart";
|