@x-plat/design-system 0.5.32 → 0.5.34
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 +148 -144
- package/dist/components/Chart/index.css +54 -10
- package/dist/components/Chart/index.js +148 -144
- package/dist/components/index.cjs +148 -144
- package/dist/components/index.css +54 -10
- package/dist/components/index.js +148 -144
- package/dist/index.cjs +148 -144
- package/dist/index.css +54 -10
- package/dist/index.js +148 -144
- package/package.json +1 -1
package/dist/components/index.js
CHANGED
|
@@ -2256,45 +2256,35 @@ var useChartAnimation = (containerRef, dataKey) => {
|
|
|
2256
2256
|
prevDataKey.current = dataKey;
|
|
2257
2257
|
if (prefersReducedMotion()) return;
|
|
2258
2258
|
setAnimate(false);
|
|
2259
|
-
requestAnimationFrame(() =>
|
|
2259
|
+
requestAnimationFrame(() => {
|
|
2260
|
+
requestAnimationFrame(() => setAnimate(true));
|
|
2261
|
+
});
|
|
2260
2262
|
}
|
|
2261
2263
|
}, [dataKey]);
|
|
2262
2264
|
return animate || prefersReducedMotion();
|
|
2263
2265
|
};
|
|
2266
|
+
var TOOLTIP_OFFSET = 12;
|
|
2264
2267
|
var useChartTooltip = (enabled) => {
|
|
2265
2268
|
const [tooltip, setTooltip] = React6.useState({
|
|
2266
2269
|
visible: false,
|
|
2267
|
-
|
|
2268
|
-
|
|
2270
|
+
clientX: 0,
|
|
2271
|
+
clientY: 0,
|
|
2269
2272
|
content: ""
|
|
2270
2273
|
});
|
|
2271
2274
|
const containerRef = React6.useRef(null);
|
|
2272
2275
|
const rafRef = React6.useRef(0);
|
|
2273
2276
|
const move = React6.useCallback((e) => {
|
|
2274
2277
|
if (!enabled) return;
|
|
2275
|
-
const
|
|
2276
|
-
const
|
|
2278
|
+
const cx = e.clientX;
|
|
2279
|
+
const cy = e.clientY;
|
|
2277
2280
|
cancelAnimationFrame(rafRef.current);
|
|
2278
2281
|
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
|
-
}));
|
|
2282
|
+
setTooltip((prev) => ({ ...prev, clientX: cx, clientY: cy }));
|
|
2286
2283
|
});
|
|
2287
2284
|
}, [enabled]);
|
|
2288
2285
|
const show = React6.useCallback((e, content) => {
|
|
2289
2286
|
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
|
-
});
|
|
2287
|
+
setTooltip({ visible: true, clientX: e.clientX, clientY: e.clientY, content });
|
|
2298
2288
|
}, [enabled]);
|
|
2299
2289
|
const hide = React6.useCallback(() => {
|
|
2300
2290
|
cancelAnimationFrame(rafRef.current);
|
|
@@ -2328,14 +2318,14 @@ var AxisLabels = React6.memo(({ labels, count, chartW, height }) => {
|
|
|
2328
2318
|
AxisLabels.displayName = "AxisLabels";
|
|
2329
2319
|
var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
2330
2320
|
const [activeIndex, setActiveIndex] = React6.useState(null);
|
|
2331
|
-
const [mouseX, setMouseX] = React6.useState(null);
|
|
2332
2321
|
const handleMouseMove = React6.useCallback((e) => {
|
|
2333
2322
|
const svg = e.currentTarget;
|
|
2334
2323
|
const rect = svg.getBoundingClientRect();
|
|
2335
2324
|
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
2336
|
-
setMouseX(mx);
|
|
2337
2325
|
if (seriesPoints.length === 0 || seriesPoints[0].length === 0) return;
|
|
2338
2326
|
const points = seriesPoints[0];
|
|
2327
|
+
const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
|
|
2328
|
+
const threshold = step / 2;
|
|
2339
2329
|
let closest = 0;
|
|
2340
2330
|
let minDist = Math.abs(points[0].x - mx);
|
|
2341
2331
|
for (let i = 1; i < points.length; i++) {
|
|
@@ -2345,11 +2335,10 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
2345
2335
|
closest = i;
|
|
2346
2336
|
}
|
|
2347
2337
|
}
|
|
2348
|
-
setActiveIndex(closest);
|
|
2338
|
+
setActiveIndex(minDist <= threshold ? closest : null);
|
|
2349
2339
|
}, [seriesPoints]);
|
|
2350
2340
|
const handleMouseLeave = React6.useCallback(() => {
|
|
2351
2341
|
setActiveIndex(null);
|
|
2352
|
-
setMouseX(null);
|
|
2353
2342
|
}, []);
|
|
2354
2343
|
const tooltipContent = React6.useMemo(() => {
|
|
2355
2344
|
if (activeIndex === null) return "";
|
|
@@ -2358,7 +2347,13 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
2358
2347
|
return p ? `${key}: ${p.v}` : "";
|
|
2359
2348
|
}).filter(Boolean).join(" / ");
|
|
2360
2349
|
}, [activeIndex, entries, seriesPoints]);
|
|
2361
|
-
|
|
2350
|
+
const getTooltipAt = React6.useCallback((idx) => {
|
|
2351
|
+
return entries.map(([key], di) => {
|
|
2352
|
+
const p = seriesPoints[di]?.[idx];
|
|
2353
|
+
return p ? `${key}: ${p.v}` : "";
|
|
2354
|
+
}).filter(Boolean).join(" / ");
|
|
2355
|
+
}, [entries, seriesPoints]);
|
|
2356
|
+
return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
|
|
2362
2357
|
};
|
|
2363
2358
|
var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
2364
2359
|
const entries = React6.useMemo(() => Object.entries(data), [data]);
|
|
@@ -2379,33 +2374,19 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2379
2374
|
),
|
|
2380
2375
|
[entries, count, chartW, chartH, maxVal]
|
|
2381
2376
|
);
|
|
2382
|
-
const lineRefs = React6.useRef([]);
|
|
2383
2377
|
const clipRef = React6.useRef(null);
|
|
2384
|
-
const { activeIndex,
|
|
2378
|
+
const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
|
|
2385
2379
|
React6.useEffect(() => {
|
|
2386
|
-
if (!animate) return;
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
el.style.transition = "stroke-dashoffset 1200ms ease-out 200ms";
|
|
2394
|
-
el.style.strokeDashoffset = "0";
|
|
2395
|
-
});
|
|
2380
|
+
if (!animate || !clipRef.current) return;
|
|
2381
|
+
clipRef.current.setAttribute("width", "0");
|
|
2382
|
+
requestAnimationFrame(() => {
|
|
2383
|
+
if (clipRef.current) {
|
|
2384
|
+
clipRef.current.style.transition = "width 1200ms ease-out 200ms";
|
|
2385
|
+
clipRef.current.setAttribute("width", `${width}`);
|
|
2386
|
+
}
|
|
2396
2387
|
});
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
requestAnimationFrame(() => {
|
|
2400
|
-
if (clipRef.current) {
|
|
2401
|
-
clipRef.current.style.transition = "width 1200ms ease-out 200ms";
|
|
2402
|
-
clipRef.current.setAttribute("width", `${width}`);
|
|
2403
|
-
}
|
|
2404
|
-
});
|
|
2405
|
-
}
|
|
2406
|
-
}, [animate, seriesPoints, width]);
|
|
2407
|
-
const guideX = mouseX != null && mouseX >= PADDING.left && mouseX <= width - PADDING.right ? mouseX : null;
|
|
2408
|
-
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x : null;
|
|
2388
|
+
}, [animate, width]);
|
|
2389
|
+
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
|
|
2409
2390
|
const lineClipId = "line-area-clip";
|
|
2410
2391
|
return /* @__PURE__ */ jsxs197(
|
|
2411
2392
|
"svg",
|
|
@@ -2414,7 +2395,26 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2414
2395
|
className: "chart-svg",
|
|
2415
2396
|
onMouseMove: (e) => {
|
|
2416
2397
|
handleMouseMove(e);
|
|
2417
|
-
|
|
2398
|
+
const svg = e.currentTarget;
|
|
2399
|
+
const rect = svg.getBoundingClientRect();
|
|
2400
|
+
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
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)}`);
|
|
2415
|
+
} else {
|
|
2416
|
+
onLeave();
|
|
2417
|
+
}
|
|
2418
2418
|
},
|
|
2419
2419
|
onMouseLeave: () => {
|
|
2420
2420
|
handleMouseLeave();
|
|
@@ -2437,26 +2437,10 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2437
2437
|
/* @__PURE__ */ jsx307("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
|
|
2438
2438
|
/* @__PURE__ */ jsx307("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
|
|
2439
2439
|
] }) }),
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
"path",
|
|
2442
|
-
{
|
|
2443
|
-
|
|
2444
|
-
fill: `url(#${gradientId})`,
|
|
2445
|
-
clipPath: animate ? `url(#${lineClipId})` : void 0
|
|
2446
|
-
}
|
|
2447
|
-
),
|
|
2448
|
-
/* @__PURE__ */ jsx307(
|
|
2449
|
-
"polyline",
|
|
2450
|
-
{
|
|
2451
|
-
ref: (el) => {
|
|
2452
|
-
lineRefs.current[di] = el;
|
|
2453
|
-
},
|
|
2454
|
-
points: polyPoints,
|
|
2455
|
-
fill: "none",
|
|
2456
|
-
stroke: color,
|
|
2457
|
-
strokeWidth: "2"
|
|
2458
|
-
}
|
|
2459
|
-
),
|
|
2440
|
+
/* @__PURE__ */ jsxs197("g", { clipPath: animate ? `url(#${lineClipId})` : void 0, children: [
|
|
2441
|
+
/* @__PURE__ */ jsx307("path", { d: areaD, fill: `url(#${gradientId})` }),
|
|
2442
|
+
/* @__PURE__ */ jsx307("polyline", { points: polyPoints, fill: "none", stroke: color, strokeWidth: "2" })
|
|
2443
|
+
] }),
|
|
2460
2444
|
activeIndex !== null && points[activeIndex] && /* @__PURE__ */ jsx307(
|
|
2461
2445
|
"circle",
|
|
2462
2446
|
{
|
|
@@ -2469,21 +2453,16 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
|
|
|
2469
2453
|
)
|
|
2470
2454
|
] }, di);
|
|
2471
2455
|
}),
|
|
2472
|
-
|
|
2456
|
+
activeX !== null && /* @__PURE__ */ jsx307(
|
|
2473
2457
|
"line",
|
|
2474
2458
|
{
|
|
2475
|
-
x1:
|
|
2459
|
+
x1: activeX,
|
|
2476
2460
|
y1: PADDING.top,
|
|
2477
|
-
x2:
|
|
2461
|
+
x2: activeX,
|
|
2478
2462
|
y2: PADDING.top + chartH,
|
|
2479
2463
|
className: "chart-crosshair"
|
|
2480
2464
|
}
|
|
2481
2465
|
),
|
|
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
2466
|
/* @__PURE__ */ jsx307(
|
|
2488
2467
|
"rect",
|
|
2489
2468
|
{
|
|
@@ -2519,33 +2498,19 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2519
2498
|
),
|
|
2520
2499
|
[entries, count, chartW, chartH, maxVal]
|
|
2521
2500
|
);
|
|
2522
|
-
const lineRefs = React6.useRef([]);
|
|
2523
2501
|
const curveClipRef = React6.useRef(null);
|
|
2524
|
-
const { activeIndex,
|
|
2502
|
+
const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
|
|
2525
2503
|
React6.useEffect(() => {
|
|
2526
|
-
if (!animate) return;
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
el.style.transition = "stroke-dashoffset 1200ms ease-out 200ms";
|
|
2534
|
-
el.style.strokeDashoffset = "0";
|
|
2535
|
-
});
|
|
2504
|
+
if (!animate || !curveClipRef.current) return;
|
|
2505
|
+
curveClipRef.current.setAttribute("width", "0");
|
|
2506
|
+
requestAnimationFrame(() => {
|
|
2507
|
+
if (curveClipRef.current) {
|
|
2508
|
+
curveClipRef.current.style.transition = "width 1200ms ease-out 200ms";
|
|
2509
|
+
curveClipRef.current.setAttribute("width", `${width}`);
|
|
2510
|
+
}
|
|
2536
2511
|
});
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
requestAnimationFrame(() => {
|
|
2540
|
-
if (curveClipRef.current) {
|
|
2541
|
-
curveClipRef.current.style.transition = "width 1200ms ease-out 200ms";
|
|
2542
|
-
curveClipRef.current.setAttribute("width", `${width}`);
|
|
2543
|
-
}
|
|
2544
|
-
});
|
|
2545
|
-
}
|
|
2546
|
-
}, [animate, seriesPoints, width]);
|
|
2547
|
-
const guideX = mouseX != null && mouseX >= PADDING.left && mouseX <= width - PADDING.right ? mouseX : null;
|
|
2548
|
-
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x : null;
|
|
2512
|
+
}, [animate, width]);
|
|
2513
|
+
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
|
|
2549
2514
|
const curveClipId = "curve-area-clip";
|
|
2550
2515
|
return /* @__PURE__ */ jsxs197(
|
|
2551
2516
|
"svg",
|
|
@@ -2554,7 +2519,26 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2554
2519
|
className: "chart-svg",
|
|
2555
2520
|
onMouseMove: (e) => {
|
|
2556
2521
|
handleMouseMove(e);
|
|
2557
|
-
|
|
2522
|
+
const svg = e.currentTarget;
|
|
2523
|
+
const rect = svg.getBoundingClientRect();
|
|
2524
|
+
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
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)}`);
|
|
2539
|
+
} else {
|
|
2540
|
+
onLeave();
|
|
2541
|
+
}
|
|
2558
2542
|
},
|
|
2559
2543
|
onMouseLeave: () => {
|
|
2560
2544
|
handleMouseLeave();
|
|
@@ -2577,26 +2561,10 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2577
2561
|
/* @__PURE__ */ jsx307("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
|
|
2578
2562
|
/* @__PURE__ */ jsx307("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
|
|
2579
2563
|
] }) }),
|
|
2580
|
-
/* @__PURE__ */
|
|
2581
|
-
"path",
|
|
2582
|
-
{
|
|
2583
|
-
|
|
2584
|
-
fill: `url(#${gradientId})`,
|
|
2585
|
-
clipPath: animate ? `url(#${curveClipId})` : void 0
|
|
2586
|
-
}
|
|
2587
|
-
),
|
|
2588
|
-
/* @__PURE__ */ jsx307(
|
|
2589
|
-
"path",
|
|
2590
|
-
{
|
|
2591
|
-
ref: (el) => {
|
|
2592
|
-
lineRefs.current[di] = el;
|
|
2593
|
-
},
|
|
2594
|
-
d: linePath,
|
|
2595
|
-
fill: "none",
|
|
2596
|
-
stroke: color,
|
|
2597
|
-
strokeWidth: "2"
|
|
2598
|
-
}
|
|
2599
|
-
),
|
|
2564
|
+
/* @__PURE__ */ jsxs197("g", { clipPath: animate ? `url(#${curveClipId})` : void 0, children: [
|
|
2565
|
+
/* @__PURE__ */ jsx307("path", { d: areaPath, fill: `url(#${gradientId})` }),
|
|
2566
|
+
/* @__PURE__ */ jsx307("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" })
|
|
2567
|
+
] }),
|
|
2600
2568
|
activeIndex !== null && points[activeIndex] && /* @__PURE__ */ jsx307(
|
|
2601
2569
|
"circle",
|
|
2602
2570
|
{
|
|
@@ -2609,21 +2577,16 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
|
|
|
2609
2577
|
)
|
|
2610
2578
|
] }, di);
|
|
2611
2579
|
}),
|
|
2612
|
-
|
|
2580
|
+
activeX !== null && /* @__PURE__ */ jsx307(
|
|
2613
2581
|
"line",
|
|
2614
2582
|
{
|
|
2615
|
-
x1:
|
|
2583
|
+
x1: activeX,
|
|
2616
2584
|
y1: PADDING.top,
|
|
2617
|
-
x2:
|
|
2585
|
+
x2: activeX,
|
|
2618
2586
|
y2: PADDING.top + chartH,
|
|
2619
2587
|
className: "chart-crosshair"
|
|
2620
2588
|
}
|
|
2621
2589
|
),
|
|
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
2590
|
/* @__PURE__ */ jsx307(
|
|
2628
2591
|
"rect",
|
|
2629
2592
|
{
|
|
@@ -2802,30 +2765,70 @@ var PieDonutChart = React6.memo(
|
|
|
2802
2765
|
}
|
|
2803
2766
|
);
|
|
2804
2767
|
PieDonutChart.displayName = "PieDonutChart";
|
|
2805
|
-
var
|
|
2768
|
+
var ChartTooltipPortal = ({ clientX, clientY, visible, children }) => {
|
|
2806
2769
|
const ref = React6.useRef(null);
|
|
2807
|
-
const [
|
|
2808
|
-
React6.
|
|
2770
|
+
const [pos, setPos] = React6.useState({ left: 0, top: 0 });
|
|
2771
|
+
React6.useLayoutEffect(() => {
|
|
2809
2772
|
const el = ref.current;
|
|
2810
2773
|
if (!el) return;
|
|
2811
2774
|
const w = el.offsetWidth;
|
|
2812
|
-
const
|
|
2813
|
-
const
|
|
2814
|
-
let
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2775
|
+
const h = el.offsetHeight;
|
|
2776
|
+
const vw = window.innerWidth;
|
|
2777
|
+
let left = clientX + TOOLTIP_OFFSET;
|
|
2778
|
+
let top = clientY - h - TOOLTIP_OFFSET;
|
|
2779
|
+
if (left + w > vw - 8) left = clientX - w - TOOLTIP_OFFSET;
|
|
2780
|
+
if (top < 8) top = clientY + TOOLTIP_OFFSET;
|
|
2781
|
+
if (left < 8) left = 8;
|
|
2782
|
+
setPos({ left, top });
|
|
2783
|
+
}, [clientX, clientY]);
|
|
2819
2784
|
return /* @__PURE__ */ jsx307(
|
|
2820
2785
|
"div",
|
|
2821
2786
|
{
|
|
2822
2787
|
ref,
|
|
2823
|
-
className: "chart-tooltip"
|
|
2824
|
-
style: { left:
|
|
2788
|
+
className: `chart-tooltip ${visible ? "chart-tooltip-show" : "chart-tooltip-hide"}`,
|
|
2789
|
+
style: { position: "fixed", left: pos.left, top: pos.top, zIndex: 1100 },
|
|
2825
2790
|
children
|
|
2826
2791
|
}
|
|
2827
2792
|
);
|
|
2828
2793
|
};
|
|
2794
|
+
var ChartLegend = ({ data, labels, type }) => {
|
|
2795
|
+
const entries = Object.entries(data);
|
|
2796
|
+
if (type === "pie" || type === "doughnut") {
|
|
2797
|
+
const values = entries.flatMap(([, v]) => v);
|
|
2798
|
+
const total = values.reduce((a, b) => a + b, 0) || 1;
|
|
2799
|
+
const firstKey = entries[0]?.[0] ?? "";
|
|
2800
|
+
const colorOffset = hashString(firstKey);
|
|
2801
|
+
return /* @__PURE__ */ jsx307("div", { className: "chart-legend", children: values.map((v, i) => {
|
|
2802
|
+
const pct = Math.round(v / total * 100);
|
|
2803
|
+
const color = PIE_COLORS[(i + colorOffset) % PIE_COLORS.length];
|
|
2804
|
+
return /* @__PURE__ */ jsxs197("div", { className: "chart-legend-item", children: [
|
|
2805
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
|
|
2806
|
+
/* @__PURE__ */ jsxs197("div", { className: "chart-legend-text", children: [
|
|
2807
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
|
|
2808
|
+
/* @__PURE__ */ jsxs197("span", { className: "chart-legend-value", children: [
|
|
2809
|
+
v.toLocaleString(),
|
|
2810
|
+
"(",
|
|
2811
|
+
pct,
|
|
2812
|
+
"%)"
|
|
2813
|
+
] })
|
|
2814
|
+
] })
|
|
2815
|
+
] }, i);
|
|
2816
|
+
}) });
|
|
2817
|
+
}
|
|
2818
|
+
return /* @__PURE__ */ jsx307("div", { className: "chart-legend", children: entries.map(([key], di) => {
|
|
2819
|
+
const palette = getPalette(LINE_BAR_PALETTES, di, key);
|
|
2820
|
+
const color = palette[2];
|
|
2821
|
+
const values = entries[di][1];
|
|
2822
|
+
const sum = values.reduce((a, b) => a + b, 0);
|
|
2823
|
+
return /* @__PURE__ */ jsxs197("div", { className: "chart-legend-item", children: [
|
|
2824
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
|
|
2825
|
+
/* @__PURE__ */ jsxs197("div", { className: "chart-legend-text", children: [
|
|
2826
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-label", children: key }),
|
|
2827
|
+
/* @__PURE__ */ jsx307("span", { className: "chart-legend-value", children: sum.toLocaleString() })
|
|
2828
|
+
] })
|
|
2829
|
+
] }, di);
|
|
2830
|
+
}) });
|
|
2831
|
+
};
|
|
2829
2832
|
var Chart = React6.memo((props) => {
|
|
2830
2833
|
const { type, data, labels, tooltip: showTooltip = true } = props;
|
|
2831
2834
|
const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
@@ -2841,7 +2844,8 @@ var Chart = React6.memo((props) => {
|
|
|
2841
2844
|
ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2842
2845
|
ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
2843
2846
|
ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
|
|
2844
|
-
|
|
2847
|
+
ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
|
|
2848
|
+
tooltip.content && /* @__PURE__ */ jsx307(ChartTooltipPortal, { clientX: tooltip.clientX, clientY: tooltip.clientY, visible: tooltip.visible, children: tooltip.content })
|
|
2845
2849
|
] });
|
|
2846
2850
|
});
|
|
2847
2851
|
Chart.displayName = "Chart";
|