@classic-homes/charts-react 0.1.1

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/index.cjs ADDED
@@ -0,0 +1,2188 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AreaChart: () => AreaChart,
34
+ BarChart: () => BarChart,
35
+ CandlestickChart: () => CandlestickChart,
36
+ ChartContainer: () => ChartContainer,
37
+ ChartEmpty: () => ChartEmpty,
38
+ ChartError: () => ChartError,
39
+ ChartSkeleton: () => ChartSkeleton,
40
+ DonutChart: () => DonutChart,
41
+ FunnelChart: () => FunnelChart,
42
+ GaugeChart: () => GaugeChart,
43
+ HeatmapChart: () => HeatmapChart,
44
+ LineChart: () => LineChart,
45
+ PieChart: () => PieChart,
46
+ RadarChart: () => RadarChart,
47
+ SankeyChart: () => SankeyChart,
48
+ ScatterChart: () => ScatterChart,
49
+ TreemapChart: () => TreemapChart,
50
+ cn: () => cn,
51
+ registerClassicThemes: () => registerClassicThemes,
52
+ useChart: () => useChart,
53
+ useChartResize: () => useChartResize,
54
+ useChartTheme: () => useChartTheme,
55
+ useReducedMotion: () => useReducedMotion
56
+ });
57
+ module.exports = __toCommonJS(index_exports);
58
+
59
+ // src/components/base/ChartContainer.tsx
60
+ var React4 = __toESM(require("react"), 1);
61
+
62
+ // src/lib/utils.ts
63
+ var import_clsx = require("clsx");
64
+ var import_tailwind_merge = require("tailwind-merge");
65
+ function cn(...inputs) {
66
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
67
+ }
68
+
69
+ // src/components/base/ChartSkeleton.tsx
70
+ var React = __toESM(require("react"), 1);
71
+ var import_jsx_runtime = require("react/jsx-runtime");
72
+ var ChartSkeleton = React.forwardRef(
73
+ ({ height = 400, className }, ref) => {
74
+ const heightStyle = typeof height === "number" ? `${height}px` : height;
75
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
76
+ "div",
77
+ {
78
+ ref,
79
+ "data-testid": "chart-skeleton",
80
+ className: cn("animate-pulse rounded-lg border border-border bg-muted", className),
81
+ style: { height: heightStyle },
82
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex h-full flex-col p-4", children: [
83
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-4 h-5 w-1/3 rounded bg-muted-foreground/20" }),
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-1 items-end gap-2 px-4 pb-8", children: [40, 65, 45, 80, 55, 70, 50].map((height2, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
85
+ "div",
86
+ {
87
+ className: "flex-1 rounded-t bg-muted-foreground/20",
88
+ style: { height: `${height2}%` }
89
+ },
90
+ i
91
+ )) }),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex justify-between px-4", children: [1, 2, 3, 4, 5, 6, 7].map((i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-8 rounded bg-muted-foreground/20" }, i)) })
93
+ ] })
94
+ }
95
+ );
96
+ }
97
+ );
98
+ ChartSkeleton.displayName = "ChartSkeleton";
99
+
100
+ // src/components/base/ChartError.tsx
101
+ var React2 = __toESM(require("react"), 1);
102
+ var import_jsx_runtime2 = require("react/jsx-runtime");
103
+ var ChartError = React2.forwardRef(
104
+ ({ message, height = 400, onRetry, className }, ref) => {
105
+ const heightStyle = typeof height === "number" ? `${height}px` : height;
106
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
107
+ "div",
108
+ {
109
+ ref,
110
+ "data-testid": "chart-error",
111
+ role: "alert",
112
+ className: cn(
113
+ "flex flex-col items-center justify-center rounded-lg border border-destructive/50 bg-destructive/10",
114
+ className
115
+ ),
116
+ style: { height: heightStyle },
117
+ children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
119
+ "svg",
120
+ {
121
+ className: "mb-3 h-10 w-10 text-destructive",
122
+ xmlns: "http://www.w3.org/2000/svg",
123
+ fill: "none",
124
+ viewBox: "0 0 24 24",
125
+ stroke: "currentColor",
126
+ "aria-hidden": "true",
127
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
128
+ "path",
129
+ {
130
+ strokeLinecap: "round",
131
+ strokeLinejoin: "round",
132
+ strokeWidth: 2,
133
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
134
+ }
135
+ )
136
+ }
137
+ ),
138
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-2 text-sm font-medium text-destructive", children: message }),
139
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
140
+ "button",
141
+ {
142
+ onClick: onRetry,
143
+ className: "rounded-md bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground transition-colors hover:bg-destructive/90",
144
+ children: "Retry"
145
+ }
146
+ )
147
+ ]
148
+ }
149
+ );
150
+ }
151
+ );
152
+ ChartError.displayName = "ChartError";
153
+
154
+ // src/components/base/ChartEmpty.tsx
155
+ var React3 = __toESM(require("react"), 1);
156
+ var import_jsx_runtime3 = require("react/jsx-runtime");
157
+ var ChartEmpty = React3.forwardRef(
158
+ ({ message = "No data available", height = 400, className }, ref) => {
159
+ const heightStyle = typeof height === "number" ? `${height}px` : height;
160
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
161
+ "div",
162
+ {
163
+ ref,
164
+ "data-testid": "chart-empty",
165
+ className: cn(
166
+ "flex flex-col items-center justify-center rounded-lg border border-border bg-muted/50",
167
+ className
168
+ ),
169
+ style: { height: heightStyle },
170
+ children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
172
+ "svg",
173
+ {
174
+ className: "mb-3 h-10 w-10 text-muted-foreground",
175
+ xmlns: "http://www.w3.org/2000/svg",
176
+ fill: "none",
177
+ viewBox: "0 0 24 24",
178
+ stroke: "currentColor",
179
+ "aria-hidden": "true",
180
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
181
+ "path",
182
+ {
183
+ strokeLinecap: "round",
184
+ strokeLinejoin: "round",
185
+ strokeWidth: 1.5,
186
+ d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
187
+ }
188
+ )
189
+ }
190
+ ),
191
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-muted-foreground", children: message })
192
+ ]
193
+ }
194
+ );
195
+ }
196
+ );
197
+ ChartEmpty.displayName = "ChartEmpty";
198
+
199
+ // src/components/base/ChartContainer.tsx
200
+ var import_jsx_runtime4 = require("react/jsx-runtime");
201
+ var ChartContainer = React4.forwardRef(
202
+ ({
203
+ title,
204
+ description,
205
+ height = 400,
206
+ loading,
207
+ error,
208
+ empty,
209
+ emptyMessage,
210
+ onRetry,
211
+ className,
212
+ wrapperClassName,
213
+ children,
214
+ ...props
215
+ }, ref) => {
216
+ const heightStyle = typeof height === "number" ? `${height}px` : height;
217
+ if (loading) {
218
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChartSkeleton, { height, className: wrapperClassName });
219
+ }
220
+ if (error) {
221
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
222
+ ChartError,
223
+ {
224
+ message: error,
225
+ height,
226
+ onRetry,
227
+ className: wrapperClassName
228
+ }
229
+ );
230
+ }
231
+ if (empty) {
232
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChartEmpty, { message: emptyMessage, height, className: wrapperClassName });
233
+ }
234
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
235
+ "div",
236
+ {
237
+ ref,
238
+ role: "img",
239
+ "aria-label": title,
240
+ "aria-describedby": description ? `${title}-desc` : void 0,
241
+ "data-testid": "chart-container",
242
+ className: cn("rounded-lg border border-border bg-card", wrapperClassName),
243
+ ...props,
244
+ children: [
245
+ description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { id: `${title}-desc`, className: "sr-only", children: description }),
246
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("h-full w-full", className), style: { height: heightStyle }, children })
247
+ ]
248
+ }
249
+ );
250
+ }
251
+ );
252
+ ChartContainer.displayName = "ChartContainer";
253
+
254
+ // src/components/core/LineChart.tsx
255
+ var React5 = __toESM(require("react"), 1);
256
+ var echarts3 = __toESM(require("echarts/core"), 1);
257
+ var import_charts = require("echarts/charts");
258
+ var import_components = require("echarts/components");
259
+ var import_renderers = require("echarts/renderers");
260
+ var import_charts_core2 = require("@classic-homes/charts-core");
261
+
262
+ // src/hooks/useChart.ts
263
+ var import_react4 = require("react");
264
+ var echarts2 = __toESM(require("echarts/core"), 1);
265
+
266
+ // src/hooks/useChartTheme.ts
267
+ var import_react = require("react");
268
+ var echarts = __toESM(require("echarts/core"), 1);
269
+ var import_charts_core = require("@classic-homes/charts-core");
270
+ var themesRegistered = false;
271
+ function registerClassicThemes() {
272
+ if (themesRegistered) return;
273
+ echarts.registerTheme(import_charts_core.THEME_LIGHT, import_charts_core.lightTheme);
274
+ echarts.registerTheme(import_charts_core.THEME_DARK, import_charts_core.darkTheme);
275
+ themesRegistered = true;
276
+ }
277
+ function useChartTheme(preference = "auto") {
278
+ const [currentTheme, setCurrentTheme] = (0, import_react.useState)(import_charts_core.THEME_LIGHT);
279
+ const updateTheme = (0, import_react.useCallback)(() => {
280
+ if (preference !== "auto") {
281
+ setCurrentTheme(preference === "dark" ? import_charts_core.THEME_DARK : import_charts_core.THEME_LIGHT);
282
+ return;
283
+ }
284
+ const isDark = document.documentElement.classList.contains("dark");
285
+ setCurrentTheme(isDark ? import_charts_core.THEME_DARK : import_charts_core.THEME_LIGHT);
286
+ }, [preference]);
287
+ (0, import_react.useEffect)(() => {
288
+ registerClassicThemes();
289
+ updateTheme();
290
+ if (preference !== "auto") return;
291
+ const observer = new MutationObserver((mutations) => {
292
+ mutations.forEach((mutation) => {
293
+ if (mutation.type === "attributes" && mutation.attributeName === "class") {
294
+ updateTheme();
295
+ }
296
+ });
297
+ });
298
+ observer.observe(document.documentElement, {
299
+ attributes: true,
300
+ attributeFilter: ["class"]
301
+ });
302
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
303
+ const handleMediaChange = () => updateTheme();
304
+ mediaQuery.addEventListener("change", handleMediaChange);
305
+ return () => {
306
+ observer.disconnect();
307
+ mediaQuery.removeEventListener("change", handleMediaChange);
308
+ };
309
+ }, [preference, updateTheme]);
310
+ return currentTheme;
311
+ }
312
+
313
+ // src/hooks/useChartResize.ts
314
+ var import_react2 = require("react");
315
+ function useChartResize(chartRef, containerRef) {
316
+ const resizeObserverRef = (0, import_react2.useRef)(null);
317
+ (0, import_react2.useEffect)(() => {
318
+ const container = containerRef.current;
319
+ const chart = chartRef.current;
320
+ if (!container || !chart) return;
321
+ let resizeTimeout;
322
+ resizeObserverRef.current = new ResizeObserver(() => {
323
+ clearTimeout(resizeTimeout);
324
+ resizeTimeout = setTimeout(() => {
325
+ chart.resize();
326
+ }, 100);
327
+ });
328
+ resizeObserverRef.current.observe(container);
329
+ return () => {
330
+ clearTimeout(resizeTimeout);
331
+ resizeObserverRef.current?.disconnect();
332
+ };
333
+ }, [chartRef, containerRef]);
334
+ }
335
+
336
+ // src/hooks/useReducedMotion.ts
337
+ var import_react3 = require("react");
338
+ function useReducedMotion() {
339
+ const [reducedMotion, setReducedMotion] = (0, import_react3.useState)(false);
340
+ (0, import_react3.useEffect)(() => {
341
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
342
+ setReducedMotion(mediaQuery.matches);
343
+ const handleChange = (event) => {
344
+ setReducedMotion(event.matches);
345
+ };
346
+ mediaQuery.addEventListener("change", handleChange);
347
+ return () => {
348
+ mediaQuery.removeEventListener("change", handleChange);
349
+ };
350
+ }, []);
351
+ return reducedMotion;
352
+ }
353
+
354
+ // src/hooks/useChart.ts
355
+ function useChart({
356
+ option,
357
+ theme = "auto",
358
+ animation,
359
+ onReady
360
+ }) {
361
+ const containerRef = (0, import_react4.useRef)(null);
362
+ const chartRef = (0, import_react4.useRef)(null);
363
+ const currentTheme = useChartTheme(theme);
364
+ const reducedMotion = useReducedMotion();
365
+ (0, import_react4.useEffect)(() => {
366
+ if (!containerRef.current) return;
367
+ if (chartRef.current) {
368
+ chartRef.current.dispose();
369
+ }
370
+ chartRef.current = echarts2.init(containerRef.current, currentTheme);
371
+ if (onReady && chartRef.current) {
372
+ onReady(chartRef.current);
373
+ }
374
+ return () => {
375
+ chartRef.current?.dispose();
376
+ chartRef.current = null;
377
+ };
378
+ }, [currentTheme, onReady]);
379
+ (0, import_react4.useEffect)(() => {
380
+ if (!chartRef.current) return;
381
+ const shouldAnimate = animation ?? !reducedMotion;
382
+ const optionWithAnimation = {
383
+ ...option,
384
+ animation: shouldAnimate
385
+ };
386
+ chartRef.current.setOption(optionWithAnimation, {
387
+ notMerge: false,
388
+ lazyUpdate: true
389
+ });
390
+ }, [option, animation, reducedMotion]);
391
+ (0, import_react4.useEffect)(() => {
392
+ if (!chartRef.current || !containerRef.current) return;
393
+ const currentOption = chartRef.current.getOption();
394
+ chartRef.current.dispose();
395
+ chartRef.current = echarts2.init(containerRef.current, currentTheme);
396
+ chartRef.current.setOption(currentOption);
397
+ }, [currentTheme]);
398
+ useChartResize(chartRef, containerRef);
399
+ return {
400
+ chartRef,
401
+ containerRef,
402
+ currentTheme
403
+ };
404
+ }
405
+
406
+ // src/components/core/LineChart.tsx
407
+ var import_jsx_runtime5 = require("react/jsx-runtime");
408
+ echarts3.use([
409
+ import_charts.LineChart,
410
+ import_components.GridComponent,
411
+ import_components.TooltipComponent,
412
+ import_components.LegendComponent,
413
+ import_components.TitleComponent,
414
+ import_renderers.CanvasRenderer
415
+ ]);
416
+ var LineChart = React5.forwardRef(
417
+ ({
418
+ title,
419
+ description,
420
+ data,
421
+ height = 400,
422
+ loading,
423
+ error,
424
+ emptyMessage,
425
+ theme = "auto",
426
+ animation = true,
427
+ showLegend = true,
428
+ showTooltip = true,
429
+ showGrid = true,
430
+ smooth = false,
431
+ areaFilled = false,
432
+ showDataPoints = false,
433
+ stacked = false,
434
+ onClick,
435
+ onHover,
436
+ class: className,
437
+ ...props
438
+ }, ref) => {
439
+ const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
440
+ const option = React5.useMemo(() => {
441
+ if (isEmpty) return {};
442
+ return {
443
+ grid: {
444
+ left: "3%",
445
+ right: "4%",
446
+ bottom: "3%",
447
+ containLabel: true
448
+ },
449
+ tooltip: showTooltip ? {
450
+ trigger: "axis",
451
+ axisPointer: {
452
+ type: "cross",
453
+ label: {
454
+ backgroundColor: "#6a7985"
455
+ }
456
+ }
457
+ } : void 0,
458
+ legend: showLegend ? {
459
+ data: data.series.map((s) => s.name),
460
+ bottom: 0
461
+ } : void 0,
462
+ xAxis: {
463
+ type: "category",
464
+ boundaryGap: false,
465
+ data: data.categories,
466
+ splitLine: {
467
+ show: showGrid
468
+ }
469
+ },
470
+ yAxis: {
471
+ type: "value",
472
+ splitLine: {
473
+ show: showGrid
474
+ }
475
+ },
476
+ series: data.series.map((series) => ({
477
+ name: series.name,
478
+ type: "line",
479
+ data: series.data,
480
+ smooth,
481
+ showSymbol: showDataPoints,
482
+ symbolSize: showDataPoints ? 6 : 0,
483
+ stack: stacked ? "Total" : void 0,
484
+ areaStyle: areaFilled ? { opacity: 0.3 } : void 0,
485
+ itemStyle: series.color ? { color: series.color } : void 0,
486
+ emphasis: {
487
+ focus: "series"
488
+ }
489
+ }))
490
+ };
491
+ }, [
492
+ data,
493
+ isEmpty,
494
+ showTooltip,
495
+ showLegend,
496
+ showGrid,
497
+ smooth,
498
+ areaFilled,
499
+ showDataPoints,
500
+ stacked
501
+ ]);
502
+ const { containerRef } = useChart({
503
+ option,
504
+ theme,
505
+ animation,
506
+ onReady: (chart) => {
507
+ if (onClick) {
508
+ chart.on("click", (params) => {
509
+ onClick({
510
+ type: params.type || "click",
511
+ componentType: params.componentType || "series",
512
+ seriesIndex: params.seriesIndex,
513
+ seriesName: params.seriesName || "",
514
+ dataIndex: params.dataIndex || 0,
515
+ name: params.name || "",
516
+ value: params.value,
517
+ color: params.color
518
+ });
519
+ });
520
+ }
521
+ if (onHover) {
522
+ chart.on("mouseover", (params) => {
523
+ onHover({
524
+ type: params.type || "mouseover",
525
+ componentType: params.componentType || "series",
526
+ seriesIndex: params.seriesIndex,
527
+ seriesName: params.seriesName || "",
528
+ dataIndex: params.dataIndex || 0,
529
+ name: params.name || "",
530
+ value: params.value,
531
+ color: params.color
532
+ });
533
+ });
534
+ }
535
+ }
536
+ });
537
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core2.generateLineChartDescription)(title, data) : void 0);
538
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
539
+ ChartContainer,
540
+ {
541
+ ref,
542
+ title,
543
+ description: accessibilityDescription,
544
+ height,
545
+ loading,
546
+ error,
547
+ empty: isEmpty,
548
+ emptyMessage,
549
+ className: cn(className),
550
+ ...props,
551
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: containerRef, className: "h-full w-full" })
552
+ }
553
+ );
554
+ }
555
+ );
556
+ LineChart.displayName = "LineChart";
557
+
558
+ // src/components/core/BarChart.tsx
559
+ var React6 = __toESM(require("react"), 1);
560
+ var echarts4 = __toESM(require("echarts/core"), 1);
561
+ var import_charts2 = require("echarts/charts");
562
+ var import_components2 = require("echarts/components");
563
+ var import_renderers2 = require("echarts/renderers");
564
+ var import_charts_core3 = require("@classic-homes/charts-core");
565
+ var import_jsx_runtime6 = require("react/jsx-runtime");
566
+ echarts4.use([
567
+ import_charts2.BarChart,
568
+ import_components2.GridComponent,
569
+ import_components2.TooltipComponent,
570
+ import_components2.LegendComponent,
571
+ import_components2.TitleComponent,
572
+ import_renderers2.CanvasRenderer
573
+ ]);
574
+ var BarChart = React6.forwardRef(
575
+ ({
576
+ title,
577
+ description,
578
+ data,
579
+ height = 400,
580
+ loading,
581
+ error,
582
+ emptyMessage,
583
+ theme = "auto",
584
+ animation = true,
585
+ showLegend = true,
586
+ showTooltip = true,
587
+ showGrid = true,
588
+ orientation = "vertical",
589
+ stacked = false,
590
+ showValues = false,
591
+ onClick,
592
+ class: className,
593
+ ...props
594
+ }, ref) => {
595
+ const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
596
+ const isHorizontal = orientation === "horizontal";
597
+ const option = React6.useMemo(() => {
598
+ if (isEmpty) return {};
599
+ const categoryAxis = {
600
+ type: "category",
601
+ data: data.categories,
602
+ axisTick: {
603
+ alignWithLabel: true
604
+ }
605
+ };
606
+ const valueAxis = {
607
+ type: "value",
608
+ splitLine: {
609
+ show: showGrid
610
+ }
611
+ };
612
+ return {
613
+ grid: {
614
+ left: "3%",
615
+ right: "4%",
616
+ bottom: "3%",
617
+ containLabel: true
618
+ },
619
+ tooltip: showTooltip ? {
620
+ trigger: "axis",
621
+ axisPointer: {
622
+ type: "shadow"
623
+ }
624
+ } : void 0,
625
+ legend: showLegend ? {
626
+ data: data.series.map((s) => s.name),
627
+ bottom: 0
628
+ } : void 0,
629
+ xAxis: isHorizontal ? valueAxis : categoryAxis,
630
+ yAxis: isHorizontal ? categoryAxis : valueAxis,
631
+ series: data.series.map((series) => ({
632
+ name: series.name,
633
+ type: "bar",
634
+ data: series.data,
635
+ stack: stacked ? "Total" : void 0,
636
+ itemStyle: series.color ? { color: series.color } : void 0,
637
+ label: showValues ? {
638
+ show: true,
639
+ position: isHorizontal ? "right" : "top"
640
+ } : void 0,
641
+ emphasis: {
642
+ focus: "series"
643
+ }
644
+ }))
645
+ };
646
+ }, [data, isEmpty, showTooltip, showLegend, showGrid, isHorizontal, stacked, showValues]);
647
+ const { containerRef } = useChart({
648
+ option,
649
+ theme,
650
+ animation,
651
+ onReady: (chart) => {
652
+ if (onClick) {
653
+ chart.on("click", (params) => {
654
+ onClick({
655
+ type: params.type || "click",
656
+ componentType: params.componentType || "series",
657
+ seriesIndex: params.seriesIndex,
658
+ seriesName: params.seriesName || "",
659
+ dataIndex: params.dataIndex || 0,
660
+ name: params.name || "",
661
+ value: params.value,
662
+ color: params.color
663
+ });
664
+ });
665
+ }
666
+ }
667
+ });
668
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core3.generateBarChartDescription)(title, data) : void 0);
669
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
670
+ ChartContainer,
671
+ {
672
+ ref,
673
+ title,
674
+ description: accessibilityDescription,
675
+ height,
676
+ loading,
677
+ error,
678
+ empty: isEmpty,
679
+ emptyMessage,
680
+ className: cn(className),
681
+ ...props,
682
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: containerRef, className: "h-full w-full" })
683
+ }
684
+ );
685
+ }
686
+ );
687
+ BarChart.displayName = "BarChart";
688
+
689
+ // src/components/core/PieChart.tsx
690
+ var React7 = __toESM(require("react"), 1);
691
+ var echarts5 = __toESM(require("echarts/core"), 1);
692
+ var import_charts3 = require("echarts/charts");
693
+ var import_components3 = require("echarts/components");
694
+ var import_renderers3 = require("echarts/renderers");
695
+ var import_charts_core4 = require("@classic-homes/charts-core");
696
+ var import_jsx_runtime7 = require("react/jsx-runtime");
697
+ echarts5.use([import_charts3.PieChart, import_components3.TooltipComponent, import_components3.LegendComponent, import_components3.TitleComponent, import_renderers3.CanvasRenderer]);
698
+ var PieChart = React7.forwardRef(
699
+ ({
700
+ title,
701
+ description,
702
+ data,
703
+ height = 400,
704
+ loading,
705
+ error,
706
+ emptyMessage,
707
+ theme = "auto",
708
+ animation = true,
709
+ showLegend = true,
710
+ showTooltip = true,
711
+ showLabels = true,
712
+ labelPosition = "outside",
713
+ innerRadius = 0,
714
+ onClick,
715
+ class: className,
716
+ ...props
717
+ }, ref) => {
718
+ const isEmpty = !data?.length;
719
+ const option = React7.useMemo(() => {
720
+ if (isEmpty) return {};
721
+ return {
722
+ tooltip: showTooltip ? {
723
+ trigger: "item",
724
+ formatter: "{a} <br/>{b}: {c} ({d}%)"
725
+ } : void 0,
726
+ legend: showLegend ? {
727
+ orient: "horizontal",
728
+ bottom: 0,
729
+ data: data.map((d) => d.name)
730
+ } : void 0,
731
+ series: [
732
+ {
733
+ name: title,
734
+ type: "pie",
735
+ radius: innerRadius === 0 ? "70%" : ["50%", "70%"],
736
+ center: ["50%", "45%"],
737
+ data: data.map((item) => ({
738
+ name: item.name,
739
+ value: item.value,
740
+ itemStyle: item.color ? { color: item.color } : void 0
741
+ })),
742
+ label: showLabels ? {
743
+ show: true,
744
+ position: labelPosition,
745
+ formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
746
+ } : {
747
+ show: false
748
+ },
749
+ emphasis: {
750
+ itemStyle: {
751
+ shadowBlur: 10,
752
+ shadowOffsetX: 0,
753
+ shadowColor: "rgba(0, 0, 0, 0.5)"
754
+ }
755
+ }
756
+ }
757
+ ]
758
+ };
759
+ }, [data, isEmpty, showTooltip, showLegend, showLabels, labelPosition, innerRadius, title]);
760
+ const { containerRef } = useChart({
761
+ option,
762
+ theme,
763
+ animation,
764
+ onReady: (chart) => {
765
+ if (onClick) {
766
+ chart.on("click", (params) => {
767
+ onClick({
768
+ type: params.type || "click",
769
+ componentType: params.componentType || "series",
770
+ name: params.name || "",
771
+ value: params.value,
772
+ percent: params.percent,
773
+ color: params.color
774
+ });
775
+ });
776
+ }
777
+ }
778
+ });
779
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core4.generatePieChartDescription)(title, data, false) : void 0);
780
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
781
+ ChartContainer,
782
+ {
783
+ ref,
784
+ title,
785
+ description: accessibilityDescription,
786
+ height,
787
+ loading,
788
+ error,
789
+ empty: isEmpty,
790
+ emptyMessage,
791
+ className: cn(className),
792
+ ...props,
793
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: containerRef, className: "h-full w-full" })
794
+ }
795
+ );
796
+ }
797
+ );
798
+ PieChart.displayName = "PieChart";
799
+
800
+ // src/components/core/AreaChart.tsx
801
+ var React8 = __toESM(require("react"), 1);
802
+ var echarts6 = __toESM(require("echarts/core"), 1);
803
+ var import_charts4 = require("echarts/charts");
804
+ var import_components4 = require("echarts/components");
805
+ var import_renderers4 = require("echarts/renderers");
806
+ var import_jsx_runtime8 = require("react/jsx-runtime");
807
+ echarts6.use([
808
+ import_charts4.LineChart,
809
+ import_components4.GridComponent,
810
+ import_components4.TooltipComponent,
811
+ import_components4.LegendComponent,
812
+ import_components4.TitleComponent,
813
+ import_renderers4.CanvasRenderer
814
+ ]);
815
+ var AreaChart = React8.forwardRef(
816
+ ({
817
+ title,
818
+ description,
819
+ data,
820
+ height = 400,
821
+ loading,
822
+ error,
823
+ emptyMessage,
824
+ theme = "auto",
825
+ animation = true,
826
+ showLegend = true,
827
+ showTooltip = true,
828
+ showGrid = true,
829
+ smooth = false,
830
+ stacked = false,
831
+ gradient = true,
832
+ onClick,
833
+ class: className,
834
+ ...props
835
+ }, ref) => {
836
+ const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
837
+ const option = React8.useMemo(() => {
838
+ if (isEmpty) return {};
839
+ return {
840
+ grid: {
841
+ left: "3%",
842
+ right: "4%",
843
+ bottom: "3%",
844
+ containLabel: true
845
+ },
846
+ tooltip: showTooltip ? {
847
+ trigger: "axis",
848
+ axisPointer: {
849
+ type: "cross",
850
+ label: {
851
+ backgroundColor: "#6a7985"
852
+ }
853
+ }
854
+ } : void 0,
855
+ legend: showLegend ? {
856
+ data: data.series.map((s) => s.name),
857
+ bottom: 0
858
+ } : void 0,
859
+ xAxis: {
860
+ type: "category",
861
+ boundaryGap: false,
862
+ data: data.categories
863
+ },
864
+ yAxis: {
865
+ type: "value",
866
+ splitLine: {
867
+ show: showGrid
868
+ }
869
+ },
870
+ series: data.series.map((series, index) => ({
871
+ name: series.name,
872
+ type: "line",
873
+ data: series.data,
874
+ smooth,
875
+ stack: stacked ? "Total" : void 0,
876
+ areaStyle: gradient ? {
877
+ opacity: 0.8,
878
+ color: new echarts6.graphic.LinearGradient(0, 0, 0, 1, [
879
+ {
880
+ offset: 0,
881
+ color: series.color || `rgba(${60 + index * 40}, ${160 - index * 20}, ${180 - index * 30}, 0.8)`
882
+ },
883
+ {
884
+ offset: 1,
885
+ color: series.color || `rgba(${60 + index * 40}, ${160 - index * 20}, ${180 - index * 30}, 0.1)`
886
+ }
887
+ ])
888
+ } : { opacity: 0.5 },
889
+ itemStyle: series.color ? { color: series.color } : void 0,
890
+ emphasis: {
891
+ focus: "series"
892
+ },
893
+ showSymbol: false
894
+ }))
895
+ };
896
+ }, [data, isEmpty, showTooltip, showLegend, showGrid, smooth, stacked, gradient]);
897
+ const { containerRef } = useChart({
898
+ option,
899
+ theme,
900
+ animation,
901
+ onReady: (chart) => {
902
+ if (onClick) {
903
+ chart.on("click", (params) => {
904
+ onClick({
905
+ type: params.type || "click",
906
+ componentType: params.componentType || "series",
907
+ seriesIndex: params.seriesIndex,
908
+ seriesName: params.seriesName || "",
909
+ dataIndex: params.dataIndex || 0,
910
+ name: params.name || "",
911
+ value: params.value,
912
+ color: params.color
913
+ });
914
+ });
915
+ }
916
+ }
917
+ });
918
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Area chart with ${data.categories.length} data points across ${data.series.length} series.` : void 0);
919
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
920
+ ChartContainer,
921
+ {
922
+ ref,
923
+ title,
924
+ description: accessibilityDescription,
925
+ height,
926
+ loading,
927
+ error,
928
+ empty: isEmpty,
929
+ emptyMessage,
930
+ className: cn(className),
931
+ ...props,
932
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, className: "h-full w-full" })
933
+ }
934
+ );
935
+ }
936
+ );
937
+ AreaChart.displayName = "AreaChart";
938
+
939
+ // src/components/core/ScatterChart.tsx
940
+ var React9 = __toESM(require("react"), 1);
941
+ var echarts7 = __toESM(require("echarts/core"), 1);
942
+ var import_charts5 = require("echarts/charts");
943
+ var import_components5 = require("echarts/components");
944
+ var import_renderers5 = require("echarts/renderers");
945
+ var import_charts_core5 = require("@classic-homes/charts-core");
946
+ var import_jsx_runtime9 = require("react/jsx-runtime");
947
+ echarts7.use([
948
+ import_charts5.ScatterChart,
949
+ import_components5.GridComponent,
950
+ import_components5.TooltipComponent,
951
+ import_components5.LegendComponent,
952
+ import_components5.TitleComponent,
953
+ import_renderers5.CanvasRenderer
954
+ ]);
955
+ var ScatterChart = React9.forwardRef(
956
+ ({
957
+ title,
958
+ description,
959
+ data,
960
+ height = 400,
961
+ loading,
962
+ error,
963
+ emptyMessage,
964
+ theme = "auto",
965
+ animation = true,
966
+ showLegend = true,
967
+ showTooltip = true,
968
+ showGrid = true,
969
+ showTrendLine = false,
970
+ symbolSize = 10,
971
+ onClick,
972
+ class: className,
973
+ ...props
974
+ }, ref) => {
975
+ const isEmpty = !data?.series?.length || data.series.every((s) => !s.data?.length);
976
+ const option = React9.useMemo(() => {
977
+ if (isEmpty) return {};
978
+ const series = data.series.map((s) => ({
979
+ name: s.name,
980
+ type: "scatter",
981
+ data: s.data,
982
+ symbolSize: typeof symbolSize === "function" ? symbolSize : symbolSize,
983
+ itemStyle: s.color ? { color: s.color } : void 0,
984
+ emphasis: {
985
+ focus: "series",
986
+ itemStyle: {
987
+ shadowBlur: 10,
988
+ shadowColor: "rgba(0, 0, 0, 0.5)"
989
+ }
990
+ }
991
+ }));
992
+ if (showTrendLine) {
993
+ data.series.forEach((s, index) => {
994
+ if (s.data.length < 2) return;
995
+ const n = s.data.length;
996
+ let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
997
+ s.data.forEach(([x, y]) => {
998
+ sumX += x;
999
+ sumY += y;
1000
+ sumXY += x * y;
1001
+ sumX2 += x * x;
1002
+ });
1003
+ const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
1004
+ const intercept = (sumY - slope * sumX) / n;
1005
+ const xValues = s.data.map(([x]) => x);
1006
+ const minX = Math.min(...xValues);
1007
+ const maxX = Math.max(...xValues);
1008
+ series.push({
1009
+ name: `${s.name} Trend`,
1010
+ type: "line",
1011
+ data: [
1012
+ [minX, slope * minX + intercept],
1013
+ [maxX, slope * maxX + intercept]
1014
+ ],
1015
+ smooth: false,
1016
+ showSymbol: false,
1017
+ lineStyle: {
1018
+ type: "dashed",
1019
+ opacity: 0.7
1020
+ },
1021
+ emphasis: {
1022
+ disabled: true
1023
+ },
1024
+ z: index
1025
+ });
1026
+ });
1027
+ }
1028
+ return {
1029
+ grid: {
1030
+ left: "3%",
1031
+ right: "4%",
1032
+ bottom: "3%",
1033
+ containLabel: true
1034
+ },
1035
+ tooltip: showTooltip ? {
1036
+ trigger: "item",
1037
+ formatter: (params) => {
1038
+ const p = params;
1039
+ if (!p.value) return "";
1040
+ return `${p.seriesName}<br/>X: ${p.value[0]}<br/>Y: ${p.value[1]}`;
1041
+ }
1042
+ } : void 0,
1043
+ legend: showLegend ? {
1044
+ data: data.series.map((s) => s.name),
1045
+ bottom: 0
1046
+ } : void 0,
1047
+ xAxis: {
1048
+ type: "value",
1049
+ splitLine: {
1050
+ show: showGrid
1051
+ }
1052
+ },
1053
+ yAxis: {
1054
+ type: "value",
1055
+ splitLine: {
1056
+ show: showGrid
1057
+ }
1058
+ },
1059
+ series
1060
+ };
1061
+ }, [data, isEmpty, showTooltip, showLegend, showGrid, showTrendLine, symbolSize]);
1062
+ const { containerRef } = useChart({
1063
+ option,
1064
+ theme,
1065
+ animation,
1066
+ onReady: (chart) => {
1067
+ if (onClick) {
1068
+ chart.on("click", (params) => {
1069
+ onClick({
1070
+ type: params.type || "click",
1071
+ componentType: params.componentType || "series",
1072
+ seriesIndex: params.seriesIndex,
1073
+ seriesName: params.seriesName || "",
1074
+ dataIndex: params.dataIndex || 0,
1075
+ name: params.name || "",
1076
+ value: params.value,
1077
+ color: params.color
1078
+ });
1079
+ });
1080
+ }
1081
+ }
1082
+ });
1083
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core5.generateScatterChartDescription)(title, data) : void 0);
1084
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1085
+ ChartContainer,
1086
+ {
1087
+ ref,
1088
+ title,
1089
+ description: accessibilityDescription,
1090
+ height,
1091
+ loading,
1092
+ error,
1093
+ empty: isEmpty,
1094
+ emptyMessage,
1095
+ className: cn(className),
1096
+ ...props,
1097
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1098
+ }
1099
+ );
1100
+ }
1101
+ );
1102
+ ScatterChart.displayName = "ScatterChart";
1103
+
1104
+ // src/components/core/DonutChart.tsx
1105
+ var React10 = __toESM(require("react"), 1);
1106
+ var echarts8 = __toESM(require("echarts/core"), 1);
1107
+ var import_charts6 = require("echarts/charts");
1108
+ var import_components6 = require("echarts/components");
1109
+ var import_renderers6 = require("echarts/renderers");
1110
+ var import_charts_core6 = require("@classic-homes/charts-core");
1111
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1112
+ echarts8.use([import_charts6.PieChart, import_components6.TooltipComponent, import_components6.LegendComponent, import_components6.TitleComponent, import_renderers6.CanvasRenderer]);
1113
+ var DonutChart = React10.forwardRef(
1114
+ ({
1115
+ title,
1116
+ description,
1117
+ data,
1118
+ height = 400,
1119
+ loading,
1120
+ error,
1121
+ emptyMessage,
1122
+ theme = "auto",
1123
+ animation = true,
1124
+ showLegend = true,
1125
+ showTooltip = true,
1126
+ showLabels = true,
1127
+ labelPosition = "outside",
1128
+ innerRadius = "50%",
1129
+ centerLabel,
1130
+ centerValue,
1131
+ onClick,
1132
+ class: className,
1133
+ ...props
1134
+ }, ref) => {
1135
+ const isEmpty = !data?.length;
1136
+ const option = React10.useMemo(() => {
1137
+ if (isEmpty) return {};
1138
+ const graphicElements = [];
1139
+ if (centerLabel || centerValue) {
1140
+ graphicElements.push({
1141
+ type: "group",
1142
+ left: "center",
1143
+ top: "40%",
1144
+ children: [
1145
+ ...centerValue !== void 0 ? [
1146
+ {
1147
+ type: "text",
1148
+ style: {
1149
+ text: String(centerValue),
1150
+ fontSize: 28,
1151
+ fontWeight: "bold",
1152
+ fill: "currentColor",
1153
+ textAlign: "center"
1154
+ },
1155
+ top: 0,
1156
+ left: "center"
1157
+ }
1158
+ ] : [],
1159
+ ...centerLabel ? [
1160
+ {
1161
+ type: "text",
1162
+ style: {
1163
+ text: centerLabel,
1164
+ fontSize: 14,
1165
+ fill: "#888",
1166
+ textAlign: "center"
1167
+ },
1168
+ top: centerValue !== void 0 ? 35 : 0,
1169
+ left: "center"
1170
+ }
1171
+ ] : []
1172
+ ]
1173
+ });
1174
+ }
1175
+ return {
1176
+ tooltip: showTooltip ? {
1177
+ trigger: "item",
1178
+ formatter: "{a} <br/>{b}: {c} ({d}%)"
1179
+ } : void 0,
1180
+ legend: showLegend ? {
1181
+ orient: "horizontal",
1182
+ bottom: 0,
1183
+ data: data.map((d) => d.name)
1184
+ } : void 0,
1185
+ graphic: graphicElements.length > 0 ? graphicElements : void 0,
1186
+ series: [
1187
+ {
1188
+ name: title,
1189
+ type: "pie",
1190
+ radius: [innerRadius, "70%"],
1191
+ center: ["50%", "45%"],
1192
+ avoidLabelOverlap: true,
1193
+ data: data.map((item) => ({
1194
+ name: item.name,
1195
+ value: item.value,
1196
+ itemStyle: item.color ? { color: item.color } : void 0
1197
+ })),
1198
+ label: showLabels ? {
1199
+ show: true,
1200
+ position: labelPosition,
1201
+ formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
1202
+ } : {
1203
+ show: false
1204
+ },
1205
+ labelLine: {
1206
+ show: showLabels && labelPosition === "outside"
1207
+ },
1208
+ emphasis: {
1209
+ itemStyle: {
1210
+ shadowBlur: 10,
1211
+ shadowOffsetX: 0,
1212
+ shadowColor: "rgba(0, 0, 0, 0.5)"
1213
+ }
1214
+ }
1215
+ }
1216
+ ]
1217
+ };
1218
+ }, [
1219
+ data,
1220
+ isEmpty,
1221
+ showTooltip,
1222
+ showLegend,
1223
+ showLabels,
1224
+ labelPosition,
1225
+ innerRadius,
1226
+ centerLabel,
1227
+ centerValue,
1228
+ title
1229
+ ]);
1230
+ const { containerRef } = useChart({
1231
+ option,
1232
+ theme,
1233
+ animation,
1234
+ onReady: (chart) => {
1235
+ if (onClick) {
1236
+ chart.on("click", (params) => {
1237
+ onClick({
1238
+ type: params.type || "click",
1239
+ componentType: params.componentType || "series",
1240
+ name: params.name || "",
1241
+ value: params.value,
1242
+ percent: params.percent,
1243
+ color: params.color
1244
+ });
1245
+ });
1246
+ }
1247
+ }
1248
+ });
1249
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core6.generatePieChartDescription)(title, data, true) : void 0);
1250
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1251
+ ChartContainer,
1252
+ {
1253
+ ref,
1254
+ title,
1255
+ description: accessibilityDescription,
1256
+ height,
1257
+ loading,
1258
+ error,
1259
+ empty: isEmpty,
1260
+ emptyMessage,
1261
+ className: cn(className),
1262
+ ...props,
1263
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1264
+ }
1265
+ );
1266
+ }
1267
+ );
1268
+ DonutChart.displayName = "DonutChart";
1269
+
1270
+ // src/components/extended/RadarChart.tsx
1271
+ var React11 = __toESM(require("react"), 1);
1272
+ var echarts9 = __toESM(require("echarts/core"), 1);
1273
+ var import_charts7 = require("echarts/charts");
1274
+ var import_components7 = require("echarts/components");
1275
+ var import_renderers7 = require("echarts/renderers");
1276
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1277
+ echarts9.use([
1278
+ import_charts7.RadarChart,
1279
+ import_components7.TooltipComponent,
1280
+ import_components7.LegendComponent,
1281
+ import_components7.TitleComponent,
1282
+ import_components7.RadarComponent,
1283
+ import_renderers7.CanvasRenderer
1284
+ ]);
1285
+ var RadarChart = React11.forwardRef(
1286
+ ({
1287
+ title,
1288
+ description,
1289
+ data,
1290
+ indicators,
1291
+ height = 400,
1292
+ loading,
1293
+ error,
1294
+ emptyMessage,
1295
+ theme = "auto",
1296
+ animation = true,
1297
+ showLegend = true,
1298
+ showTooltip = true,
1299
+ shape = "polygon",
1300
+ class: className,
1301
+ ...props
1302
+ }, ref) => {
1303
+ const isEmpty = !data?.series?.length || !indicators?.length || data.series.every((s) => !s.data?.length);
1304
+ const option = React11.useMemo(() => {
1305
+ if (isEmpty) return {};
1306
+ return {
1307
+ tooltip: showTooltip ? {
1308
+ trigger: "item"
1309
+ } : void 0,
1310
+ legend: showLegend ? {
1311
+ data: data.series.map((s) => s.name),
1312
+ bottom: 0
1313
+ } : void 0,
1314
+ radar: {
1315
+ indicator: indicators.map((ind) => ({
1316
+ name: ind.name,
1317
+ max: ind.max,
1318
+ min: ind.min
1319
+ })),
1320
+ shape
1321
+ },
1322
+ series: [
1323
+ {
1324
+ type: "radar",
1325
+ data: data.series.map((series) => ({
1326
+ name: series.name,
1327
+ value: series.data,
1328
+ itemStyle: series.color ? { color: series.color } : void 0,
1329
+ areaStyle: {
1330
+ opacity: 0.2
1331
+ }
1332
+ }))
1333
+ }
1334
+ ]
1335
+ };
1336
+ }, [data, indicators, isEmpty, showTooltip, showLegend, shape]);
1337
+ const { containerRef } = useChart({
1338
+ option,
1339
+ theme,
1340
+ animation
1341
+ });
1342
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Radar chart with ${indicators.length} dimensions comparing ${data.series.length} series.` : void 0);
1343
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1344
+ ChartContainer,
1345
+ {
1346
+ ref,
1347
+ title,
1348
+ description: accessibilityDescription,
1349
+ height,
1350
+ loading,
1351
+ error,
1352
+ empty: isEmpty,
1353
+ emptyMessage,
1354
+ className: cn(className),
1355
+ ...props,
1356
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1357
+ }
1358
+ );
1359
+ }
1360
+ );
1361
+ RadarChart.displayName = "RadarChart";
1362
+
1363
+ // src/components/extended/FunnelChart.tsx
1364
+ var React12 = __toESM(require("react"), 1);
1365
+ var echarts10 = __toESM(require("echarts/core"), 1);
1366
+ var import_charts8 = require("echarts/charts");
1367
+ var import_components8 = require("echarts/components");
1368
+ var import_renderers8 = require("echarts/renderers");
1369
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1370
+ echarts10.use([
1371
+ import_charts8.FunnelChart,
1372
+ import_components8.TooltipComponent,
1373
+ import_components8.LegendComponent,
1374
+ import_components8.TitleComponent,
1375
+ import_renderers8.CanvasRenderer
1376
+ ]);
1377
+ var FunnelChart = React12.forwardRef(
1378
+ ({
1379
+ title,
1380
+ description,
1381
+ data,
1382
+ height = 400,
1383
+ loading,
1384
+ error,
1385
+ emptyMessage,
1386
+ theme = "auto",
1387
+ animation = true,
1388
+ showLegend = true,
1389
+ showTooltip = true,
1390
+ sort = "descending",
1391
+ orientation = "vertical",
1392
+ showLabels = true,
1393
+ onClick,
1394
+ class: className,
1395
+ ...props
1396
+ }, ref) => {
1397
+ const isEmpty = !data?.length;
1398
+ const option = React12.useMemo(() => {
1399
+ if (isEmpty) return {};
1400
+ return {
1401
+ tooltip: showTooltip ? {
1402
+ trigger: "item",
1403
+ formatter: "{a} <br/>{b}: {c}"
1404
+ } : void 0,
1405
+ legend: showLegend ? {
1406
+ data: data.map((d) => d.name),
1407
+ bottom: 0
1408
+ } : void 0,
1409
+ series: [
1410
+ {
1411
+ name: title,
1412
+ type: "funnel",
1413
+ left: "10%",
1414
+ top: 60,
1415
+ bottom: 60,
1416
+ width: "80%",
1417
+ min: 0,
1418
+ max: Math.max(...data.map((d) => d.value)),
1419
+ minSize: "0%",
1420
+ maxSize: "100%",
1421
+ sort,
1422
+ orient: orientation,
1423
+ gap: 2,
1424
+ label: showLabels ? {
1425
+ show: true,
1426
+ position: "inside",
1427
+ formatter: "{b}: {c}"
1428
+ } : {
1429
+ show: false
1430
+ },
1431
+ labelLine: {
1432
+ show: false
1433
+ },
1434
+ emphasis: {
1435
+ label: {
1436
+ fontSize: 16
1437
+ }
1438
+ },
1439
+ data: data.map((item) => ({
1440
+ name: item.name,
1441
+ value: item.value,
1442
+ itemStyle: item.color ? { color: item.color } : void 0
1443
+ }))
1444
+ }
1445
+ ]
1446
+ };
1447
+ }, [data, isEmpty, showTooltip, showLegend, sort, orientation, showLabels, title]);
1448
+ const { containerRef } = useChart({
1449
+ option,
1450
+ theme,
1451
+ animation,
1452
+ onReady: (chart) => {
1453
+ if (onClick) {
1454
+ chart.on("click", (params) => {
1455
+ onClick({
1456
+ type: params.type || "click",
1457
+ componentType: params.componentType || "series",
1458
+ name: params.name || "",
1459
+ value: params.value,
1460
+ color: params.color
1461
+ });
1462
+ });
1463
+ }
1464
+ }
1465
+ });
1466
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Funnel chart with ${data.length} stages.` : void 0);
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1468
+ ChartContainer,
1469
+ {
1470
+ ref,
1471
+ title,
1472
+ description: accessibilityDescription,
1473
+ height,
1474
+ loading,
1475
+ error,
1476
+ empty: isEmpty,
1477
+ emptyMessage,
1478
+ className: cn(className),
1479
+ ...props,
1480
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1481
+ }
1482
+ );
1483
+ }
1484
+ );
1485
+ FunnelChart.displayName = "FunnelChart";
1486
+
1487
+ // src/components/extended/GaugeChart.tsx
1488
+ var React13 = __toESM(require("react"), 1);
1489
+ var echarts11 = __toESM(require("echarts/core"), 1);
1490
+ var import_charts9 = require("echarts/charts");
1491
+ var import_components9 = require("echarts/components");
1492
+ var import_renderers9 = require("echarts/renderers");
1493
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1494
+ echarts11.use([import_charts9.GaugeChart, import_components9.TitleComponent, import_renderers9.CanvasRenderer]);
1495
+ var GaugeChart = React13.forwardRef(
1496
+ ({
1497
+ title,
1498
+ description,
1499
+ value,
1500
+ min = 0,
1501
+ max = 100,
1502
+ height = 400,
1503
+ loading,
1504
+ error,
1505
+ emptyMessage,
1506
+ theme = "auto",
1507
+ animation = true,
1508
+ splitNumber = 10,
1509
+ showProgress = true,
1510
+ formatValue,
1511
+ class: className,
1512
+ ...props
1513
+ }, ref) => {
1514
+ const option = React13.useMemo(() => {
1515
+ return {
1516
+ series: [
1517
+ {
1518
+ type: "gauge",
1519
+ center: ["50%", "60%"],
1520
+ radius: "80%",
1521
+ min,
1522
+ max,
1523
+ splitNumber,
1524
+ progress: showProgress ? {
1525
+ show: true,
1526
+ width: 18
1527
+ } : void 0,
1528
+ axisLine: {
1529
+ lineStyle: {
1530
+ width: 18
1531
+ }
1532
+ },
1533
+ axisTick: {
1534
+ distance: -30,
1535
+ splitNumber: 5,
1536
+ lineStyle: {
1537
+ width: 2,
1538
+ color: "#999"
1539
+ }
1540
+ },
1541
+ splitLine: {
1542
+ distance: -32,
1543
+ length: 10,
1544
+ lineStyle: {
1545
+ width: 3,
1546
+ color: "#999"
1547
+ }
1548
+ },
1549
+ axisLabel: {
1550
+ distance: -20,
1551
+ color: "#999",
1552
+ fontSize: 12
1553
+ },
1554
+ anchor: {
1555
+ show: true,
1556
+ size: 20,
1557
+ itemStyle: {
1558
+ borderWidth: 2
1559
+ }
1560
+ },
1561
+ pointer: {
1562
+ width: 6,
1563
+ length: "60%"
1564
+ },
1565
+ title: {
1566
+ show: true,
1567
+ offsetCenter: [0, "70%"],
1568
+ fontSize: 14
1569
+ },
1570
+ detail: {
1571
+ valueAnimation: animation,
1572
+ fontSize: 28,
1573
+ fontWeight: "bold",
1574
+ offsetCenter: [0, "40%"],
1575
+ formatter: formatValue || "{value}"
1576
+ },
1577
+ data: [
1578
+ {
1579
+ value,
1580
+ name: title
1581
+ }
1582
+ ]
1583
+ }
1584
+ ]
1585
+ };
1586
+ }, [value, min, max, splitNumber, showProgress, formatValue, title, animation]);
1587
+ const { containerRef } = useChart({
1588
+ option,
1589
+ theme,
1590
+ animation
1591
+ });
1592
+ const accessibilityDescription = description || `${title}. Gauge showing value ${value} on scale from ${min} to ${max}.`;
1593
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1594
+ ChartContainer,
1595
+ {
1596
+ ref,
1597
+ title,
1598
+ description: accessibilityDescription,
1599
+ height,
1600
+ loading,
1601
+ error,
1602
+ emptyMessage,
1603
+ className: cn(className),
1604
+ ...props,
1605
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1606
+ }
1607
+ );
1608
+ }
1609
+ );
1610
+ GaugeChart.displayName = "GaugeChart";
1611
+
1612
+ // src/components/extended/HeatmapChart.tsx
1613
+ var React14 = __toESM(require("react"), 1);
1614
+ var echarts12 = __toESM(require("echarts/core"), 1);
1615
+ var import_charts10 = require("echarts/charts");
1616
+ var import_components10 = require("echarts/components");
1617
+ var import_renderers10 = require("echarts/renderers");
1618
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1619
+ echarts12.use([
1620
+ import_charts10.HeatmapChart,
1621
+ import_components10.GridComponent,
1622
+ import_components10.TooltipComponent,
1623
+ import_components10.TitleComponent,
1624
+ import_components10.VisualMapComponent,
1625
+ import_renderers10.CanvasRenderer
1626
+ ]);
1627
+ var HeatmapChart = React14.forwardRef(
1628
+ ({
1629
+ title,
1630
+ description,
1631
+ data,
1632
+ xAxis,
1633
+ yAxis,
1634
+ height = 400,
1635
+ loading,
1636
+ error,
1637
+ emptyMessage,
1638
+ theme = "auto",
1639
+ animation = true,
1640
+ showTooltip = true,
1641
+ showValues = false,
1642
+ onClick,
1643
+ class: className,
1644
+ ...props
1645
+ }, ref) => {
1646
+ const isEmpty = !data?.data?.length || !xAxis?.length || !yAxis?.length;
1647
+ const values = data?.data?.map(([, , value]) => value) || [];
1648
+ const minValue = data?.min ?? Math.min(...values);
1649
+ const maxValue = data?.max ?? Math.max(...values);
1650
+ const option = React14.useMemo(() => {
1651
+ if (isEmpty) return {};
1652
+ return {
1653
+ tooltip: showTooltip ? {
1654
+ position: "top",
1655
+ formatter: (params) => {
1656
+ const p = params;
1657
+ if (!p.value) return "";
1658
+ const [xIdx, yIdx, value] = p.value;
1659
+ return `${xAxis[xIdx]} / ${yAxis[yIdx]}: ${value}`;
1660
+ }
1661
+ } : void 0,
1662
+ grid: {
1663
+ left: "3%",
1664
+ right: "10%",
1665
+ bottom: "3%",
1666
+ containLabel: true
1667
+ },
1668
+ xAxis: {
1669
+ type: "category",
1670
+ data: xAxis,
1671
+ splitArea: {
1672
+ show: true
1673
+ }
1674
+ },
1675
+ yAxis: {
1676
+ type: "category",
1677
+ data: yAxis,
1678
+ splitArea: {
1679
+ show: true
1680
+ }
1681
+ },
1682
+ visualMap: {
1683
+ min: minValue,
1684
+ max: maxValue,
1685
+ calculable: true,
1686
+ orient: "vertical",
1687
+ right: "0%",
1688
+ top: "center"
1689
+ },
1690
+ series: [
1691
+ {
1692
+ name: title,
1693
+ type: "heatmap",
1694
+ data: data.data,
1695
+ label: showValues ? {
1696
+ show: true
1697
+ } : void 0,
1698
+ emphasis: {
1699
+ itemStyle: {
1700
+ shadowBlur: 10,
1701
+ shadowColor: "rgba(0, 0, 0, 0.5)"
1702
+ }
1703
+ }
1704
+ }
1705
+ ]
1706
+ };
1707
+ }, [data, xAxis, yAxis, isEmpty, showTooltip, showValues, minValue, maxValue, title]);
1708
+ const { containerRef } = useChart({
1709
+ option,
1710
+ theme,
1711
+ animation,
1712
+ onReady: (chart) => {
1713
+ if (onClick) {
1714
+ chart.on("click", (params) => {
1715
+ const [xIdx, yIdx, value] = params.value || [0, 0, 0];
1716
+ onClick({
1717
+ type: params.type || "click",
1718
+ componentType: params.componentType || "series",
1719
+ xIndex: xIdx,
1720
+ yIndex: yIdx,
1721
+ xLabel: xAxis[xIdx],
1722
+ yLabel: yAxis[yIdx],
1723
+ value
1724
+ });
1725
+ });
1726
+ }
1727
+ }
1728
+ });
1729
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Heatmap with ${xAxis.length} columns and ${yAxis.length} rows.` : void 0);
1730
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1731
+ ChartContainer,
1732
+ {
1733
+ ref,
1734
+ title,
1735
+ description: accessibilityDescription,
1736
+ height,
1737
+ loading,
1738
+ error,
1739
+ empty: isEmpty,
1740
+ emptyMessage,
1741
+ className: cn(className),
1742
+ ...props,
1743
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1744
+ }
1745
+ );
1746
+ }
1747
+ );
1748
+ HeatmapChart.displayName = "HeatmapChart";
1749
+
1750
+ // src/components/extended/TreemapChart.tsx
1751
+ var React15 = __toESM(require("react"), 1);
1752
+ var echarts13 = __toESM(require("echarts/core"), 1);
1753
+ var import_charts11 = require("echarts/charts");
1754
+ var import_components11 = require("echarts/components");
1755
+ var import_renderers11 = require("echarts/renderers");
1756
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1757
+ echarts13.use([import_charts11.TreemapChart, import_components11.TooltipComponent, import_components11.TitleComponent, import_renderers11.CanvasRenderer]);
1758
+ var TreemapChart = React15.forwardRef(
1759
+ ({
1760
+ title,
1761
+ description,
1762
+ data,
1763
+ levels,
1764
+ height = 400,
1765
+ loading,
1766
+ error,
1767
+ emptyMessage,
1768
+ theme = "auto",
1769
+ animation = true,
1770
+ showTooltip = true,
1771
+ onClick,
1772
+ class: className,
1773
+ ...props
1774
+ }, ref) => {
1775
+ const isEmpty = !data?.length;
1776
+ const option = React15.useMemo(() => {
1777
+ if (isEmpty) return {};
1778
+ return {
1779
+ tooltip: showTooltip ? {
1780
+ formatter: (params) => {
1781
+ const p = params;
1782
+ return `${p.name}: ${p.value}`;
1783
+ }
1784
+ } : void 0,
1785
+ series: [
1786
+ {
1787
+ type: "treemap",
1788
+ data,
1789
+ roam: false,
1790
+ levels: levels || [
1791
+ {
1792
+ itemStyle: {
1793
+ borderColor: "#555",
1794
+ borderWidth: 4,
1795
+ gapWidth: 4
1796
+ }
1797
+ },
1798
+ {
1799
+ colorSaturation: [0.3, 0.6],
1800
+ itemStyle: {
1801
+ borderColorSaturation: 0.7,
1802
+ gapWidth: 2,
1803
+ borderWidth: 2
1804
+ }
1805
+ },
1806
+ {
1807
+ colorSaturation: [0.3, 0.5],
1808
+ itemStyle: {
1809
+ borderColorSaturation: 0.6,
1810
+ gapWidth: 1
1811
+ }
1812
+ },
1813
+ {
1814
+ colorSaturation: [0.3, 0.5]
1815
+ }
1816
+ ],
1817
+ label: {
1818
+ show: true,
1819
+ formatter: "{b}"
1820
+ },
1821
+ upperLabel: {
1822
+ show: true,
1823
+ height: 30
1824
+ },
1825
+ breadcrumb: {
1826
+ show: true
1827
+ }
1828
+ }
1829
+ ]
1830
+ };
1831
+ }, [data, levels, isEmpty, showTooltip]);
1832
+ const { containerRef } = useChart({
1833
+ option,
1834
+ theme,
1835
+ animation,
1836
+ onReady: (chart) => {
1837
+ if (onClick) {
1838
+ chart.on("click", (params) => {
1839
+ const treePathInfo = params.treePathInfo || [];
1840
+ onClick({
1841
+ type: params.type || "click",
1842
+ componentType: params.componentType || "series",
1843
+ name: params.name || "",
1844
+ value: params.value,
1845
+ path: treePathInfo.map((item) => item.name || ""),
1846
+ depth: treePathInfo.length - 1
1847
+ });
1848
+ });
1849
+ }
1850
+ }
1851
+ });
1852
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Treemap chart showing hierarchical data.` : void 0);
1853
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1854
+ ChartContainer,
1855
+ {
1856
+ ref,
1857
+ title,
1858
+ description: accessibilityDescription,
1859
+ height,
1860
+ loading,
1861
+ error,
1862
+ empty: isEmpty,
1863
+ emptyMessage,
1864
+ className: cn(className),
1865
+ ...props,
1866
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1867
+ }
1868
+ );
1869
+ }
1870
+ );
1871
+ TreemapChart.displayName = "TreemapChart";
1872
+
1873
+ // src/components/extended/CandlestickChart.tsx
1874
+ var React16 = __toESM(require("react"), 1);
1875
+ var echarts14 = __toESM(require("echarts/core"), 1);
1876
+ var import_charts12 = require("echarts/charts");
1877
+ var import_components12 = require("echarts/components");
1878
+ var import_renderers12 = require("echarts/renderers");
1879
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1880
+ echarts14.use([
1881
+ import_charts12.CandlestickChart,
1882
+ import_charts12.BarChart,
1883
+ import_components12.GridComponent,
1884
+ import_components12.TooltipComponent,
1885
+ import_components12.TitleComponent,
1886
+ import_components12.DataZoomComponent,
1887
+ import_renderers12.CanvasRenderer
1888
+ ]);
1889
+ var CandlestickChart = React16.forwardRef(
1890
+ ({
1891
+ title,
1892
+ description,
1893
+ data,
1894
+ height = 400,
1895
+ loading,
1896
+ error,
1897
+ emptyMessage,
1898
+ theme = "auto",
1899
+ animation = true,
1900
+ showTooltip = true,
1901
+ showVolume = false,
1902
+ onClick,
1903
+ class: className,
1904
+ ...props
1905
+ }, ref) => {
1906
+ const isEmpty = !data?.dates?.length || !data?.data?.length;
1907
+ const option = React16.useMemo(() => {
1908
+ if (isEmpty) return {};
1909
+ const candlestickData = data.data.map((item) => [item.open, item.close, item.low, item.high]);
1910
+ const seriesArr = [
1911
+ {
1912
+ name: title,
1913
+ type: "candlestick",
1914
+ data: candlestickData,
1915
+ itemStyle: {
1916
+ color: "#ef4444",
1917
+ // Up color (red for bearish in some markets)
1918
+ color0: "#22c55e",
1919
+ // Down color (green for bullish)
1920
+ borderColor: "#ef4444",
1921
+ borderColor0: "#22c55e"
1922
+ }
1923
+ }
1924
+ ];
1925
+ const gridArr = [
1926
+ {
1927
+ left: "10%",
1928
+ right: "10%",
1929
+ top: 60,
1930
+ height: showVolume ? "50%" : "70%"
1931
+ }
1932
+ ];
1933
+ const xAxisArr = [
1934
+ {
1935
+ type: "category",
1936
+ data: data.dates,
1937
+ boundaryGap: false,
1938
+ axisLine: { onZero: false },
1939
+ splitLine: { show: false },
1940
+ min: "dataMin",
1941
+ max: "dataMax"
1942
+ }
1943
+ ];
1944
+ const yAxisArr = [
1945
+ {
1946
+ scale: true,
1947
+ splitArea: {
1948
+ show: true
1949
+ }
1950
+ }
1951
+ ];
1952
+ if (showVolume && data.volume) {
1953
+ gridArr.push({
1954
+ left: "10%",
1955
+ right: "10%",
1956
+ top: "73%",
1957
+ height: "12%"
1958
+ });
1959
+ xAxisArr.push({
1960
+ type: "category",
1961
+ gridIndex: 1,
1962
+ data: data.dates,
1963
+ boundaryGap: false,
1964
+ axisLine: { onZero: false },
1965
+ axisTick: { show: false },
1966
+ splitLine: { show: false },
1967
+ axisLabel: { show: false },
1968
+ min: "dataMin",
1969
+ max: "dataMax"
1970
+ });
1971
+ yAxisArr.push({
1972
+ scale: true,
1973
+ gridIndex: 1,
1974
+ splitNumber: 2,
1975
+ axisLabel: { show: false },
1976
+ axisLine: { show: false },
1977
+ axisTick: { show: false },
1978
+ splitLine: { show: false }
1979
+ });
1980
+ seriesArr.push({
1981
+ name: "Volume",
1982
+ type: "bar",
1983
+ xAxisIndex: 1,
1984
+ yAxisIndex: 1,
1985
+ data: data.volume,
1986
+ itemStyle: {
1987
+ color: "#6b7280"
1988
+ }
1989
+ });
1990
+ }
1991
+ return {
1992
+ tooltip: showTooltip ? {
1993
+ trigger: "axis",
1994
+ axisPointer: {
1995
+ type: "cross"
1996
+ }
1997
+ } : void 0,
1998
+ grid: gridArr,
1999
+ xAxis: xAxisArr,
2000
+ yAxis: yAxisArr,
2001
+ dataZoom: [
2002
+ {
2003
+ type: "inside",
2004
+ start: 80,
2005
+ end: 100
2006
+ },
2007
+ {
2008
+ show: true,
2009
+ type: "slider",
2010
+ top: "90%",
2011
+ start: 80,
2012
+ end: 100
2013
+ }
2014
+ ],
2015
+ series: seriesArr
2016
+ };
2017
+ }, [data, isEmpty, showTooltip, showVolume, title]);
2018
+ const { containerRef } = useChart({
2019
+ option,
2020
+ theme,
2021
+ animation,
2022
+ onReady: (chart) => {
2023
+ if (onClick) {
2024
+ chart.on("click", (params) => {
2025
+ const dataIndex = params.dataIndex || 0;
2026
+ const item = data.data[dataIndex];
2027
+ onClick({
2028
+ type: params.type || "click",
2029
+ componentType: params.componentType || "series",
2030
+ date: data.dates[dataIndex],
2031
+ open: item.open,
2032
+ close: item.close,
2033
+ high: item.high,
2034
+ low: item.low,
2035
+ volume: data.volume?.[dataIndex]
2036
+ });
2037
+ });
2038
+ }
2039
+ }
2040
+ });
2041
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Candlestick chart with ${data.dates.length} data points.` : void 0);
2042
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2043
+ ChartContainer,
2044
+ {
2045
+ ref,
2046
+ title,
2047
+ description: accessibilityDescription,
2048
+ height,
2049
+ loading,
2050
+ error,
2051
+ empty: isEmpty,
2052
+ emptyMessage,
2053
+ className: cn(className),
2054
+ ...props,
2055
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2056
+ }
2057
+ );
2058
+ }
2059
+ );
2060
+ CandlestickChart.displayName = "CandlestickChart";
2061
+
2062
+ // src/components/extended/SankeyChart.tsx
2063
+ var React17 = __toESM(require("react"), 1);
2064
+ var echarts15 = __toESM(require("echarts/core"), 1);
2065
+ var import_charts13 = require("echarts/charts");
2066
+ var import_components13 = require("echarts/components");
2067
+ var import_renderers13 = require("echarts/renderers");
2068
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2069
+ echarts15.use([import_charts13.SankeyChart, import_components13.TooltipComponent, import_components13.TitleComponent, import_renderers13.CanvasRenderer]);
2070
+ var SankeyChart = React17.forwardRef(
2071
+ ({
2072
+ title,
2073
+ description,
2074
+ data,
2075
+ height = 400,
2076
+ loading,
2077
+ error,
2078
+ emptyMessage,
2079
+ theme = "auto",
2080
+ animation = true,
2081
+ showTooltip = true,
2082
+ orient = "horizontal",
2083
+ onClick,
2084
+ class: className,
2085
+ ...props
2086
+ }, ref) => {
2087
+ const isEmpty = !data?.nodes?.length || !data?.links?.length;
2088
+ const option = React17.useMemo(() => {
2089
+ if (isEmpty) return {};
2090
+ return {
2091
+ tooltip: showTooltip ? {
2092
+ trigger: "item",
2093
+ triggerOn: "mousemove"
2094
+ } : void 0,
2095
+ series: [
2096
+ {
2097
+ type: "sankey",
2098
+ orient,
2099
+ emphasis: {
2100
+ focus: "adjacency"
2101
+ },
2102
+ data: data.nodes.map((node) => ({
2103
+ name: node.name,
2104
+ itemStyle: node.color ? { color: node.color } : void 0
2105
+ })),
2106
+ links: data.links.map((link) => ({
2107
+ source: link.source,
2108
+ target: link.target,
2109
+ value: link.value
2110
+ })),
2111
+ lineStyle: {
2112
+ color: "gradient",
2113
+ curveness: 0.5
2114
+ },
2115
+ label: {
2116
+ position: orient === "horizontal" ? "right" : "bottom"
2117
+ }
2118
+ }
2119
+ ]
2120
+ };
2121
+ }, [data, isEmpty, showTooltip, orient]);
2122
+ const { containerRef } = useChart({
2123
+ option,
2124
+ theme,
2125
+ animation,
2126
+ onReady: (chart) => {
2127
+ if (onClick) {
2128
+ chart.on("click", (params) => {
2129
+ const isEdge = params.dataType === "edge";
2130
+ onClick({
2131
+ type: params.type || "click",
2132
+ componentType: params.componentType || "series",
2133
+ dataType: isEdge ? "edge" : "node",
2134
+ name: params.name || "",
2135
+ value: isEdge ? params.value : void 0,
2136
+ source: isEdge ? params.data?.source : void 0,
2137
+ target: isEdge ? params.data?.target : void 0
2138
+ });
2139
+ });
2140
+ }
2141
+ }
2142
+ });
2143
+ const accessibilityDescription = description || (!isEmpty ? `${title}. Sankey diagram with ${data.nodes.length} nodes and ${data.links.length} links.` : void 0);
2144
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2145
+ ChartContainer,
2146
+ {
2147
+ ref,
2148
+ title,
2149
+ description: accessibilityDescription,
2150
+ height,
2151
+ loading,
2152
+ error,
2153
+ empty: isEmpty,
2154
+ emptyMessage,
2155
+ className: cn(className),
2156
+ ...props,
2157
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2158
+ }
2159
+ );
2160
+ }
2161
+ );
2162
+ SankeyChart.displayName = "SankeyChart";
2163
+ // Annotate the CommonJS export names for ESM import in node:
2164
+ 0 && (module.exports = {
2165
+ AreaChart,
2166
+ BarChart,
2167
+ CandlestickChart,
2168
+ ChartContainer,
2169
+ ChartEmpty,
2170
+ ChartError,
2171
+ ChartSkeleton,
2172
+ DonutChart,
2173
+ FunnelChart,
2174
+ GaugeChart,
2175
+ HeatmapChart,
2176
+ LineChart,
2177
+ PieChart,
2178
+ RadarChart,
2179
+ SankeyChart,
2180
+ ScatterChart,
2181
+ TreemapChart,
2182
+ cn,
2183
+ registerClassicThemes,
2184
+ useChart,
2185
+ useChartResize,
2186
+ useChartTheme,
2187
+ useReducedMotion
2188
+ });