@pactor-app/chart 0.0.0-stage → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1410 @@
1
+ // src/index.ts
2
+ import { Registry } from "@pactor-app/core";
3
+
4
+ // src/components/MetricCard/index.tsx
5
+ import { ArrowDownRight, ArrowUpRight } from "lucide-react";
6
+
7
+ // src/lib/utils.ts
8
+ import { clsx } from "clsx";
9
+ import { twMerge } from "tailwind-merge";
10
+ function cn(...inputs) {
11
+ return twMerge(clsx(inputs));
12
+ }
13
+
14
+ // src/components/MetricCard/index.tsx
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ function MetricCard({
17
+ title,
18
+ value,
19
+ prefix,
20
+ suffix,
21
+ trend,
22
+ trendLabel,
23
+ className,
24
+ style
25
+ }) {
26
+ const showTrend = typeof trend === "number" && trend !== 0;
27
+ const rising = (trend ?? 0) > 0;
28
+ return /* @__PURE__ */ jsxs(
29
+ "div",
30
+ {
31
+ "data-slot": "metric-card",
32
+ className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
33
+ style,
34
+ children: [
35
+ title ? /* @__PURE__ */ jsx("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
36
+ /* @__PURE__ */ jsxs(
37
+ "div",
38
+ {
39
+ "data-slot": "metric-card-value",
40
+ className: "mt-1 text-2xl font-semibold tracking-tight tabular-nums",
41
+ children: [
42
+ prefix,
43
+ value,
44
+ suffix
45
+ ]
46
+ }
47
+ ),
48
+ showTrend ? /* @__PURE__ */ jsxs(
49
+ "div",
50
+ {
51
+ "data-slot": "metric-card-trend",
52
+ "data-trend": rising ? "up" : "down",
53
+ className: cn(
54
+ "mt-1 inline-flex items-center gap-0.5 text-sm",
55
+ rising ? "text-success" : "text-destructive"
56
+ ),
57
+ children: [
58
+ rising ? /* @__PURE__ */ jsx(ArrowUpRight, { className: "size-4" }) : /* @__PURE__ */ jsx(ArrowDownRight, { className: "size-4" }),
59
+ Math.abs(trend ?? 0),
60
+ "%",
61
+ trendLabel ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
62
+ ]
63
+ }
64
+ ) : null
65
+ ]
66
+ }
67
+ );
68
+ }
69
+
70
+ // src/components/EChartBase/index.tsx
71
+ import { useEffect, useRef, useState } from "react";
72
+
73
+ // src/components/echarts-modules.ts
74
+ import * as echarts from "echarts/core";
75
+ import {
76
+ BarChart,
77
+ FunnelChart,
78
+ GaugeChart,
79
+ HeatmapChart,
80
+ LineChart,
81
+ MapChart,
82
+ PieChart,
83
+ RadarChart,
84
+ SankeyChart,
85
+ ScatterChart,
86
+ TreeChart
87
+ } from "echarts/charts";
88
+ import {
89
+ DataZoomComponent,
90
+ GeoComponent,
91
+ GridComponent,
92
+ LegendComponent,
93
+ RadarComponent,
94
+ TitleComponent,
95
+ TooltipComponent,
96
+ VisualMapComponent
97
+ } from "echarts/components";
98
+ import { CanvasRenderer } from "echarts/renderers";
99
+ echarts.use([
100
+ LineChart,
101
+ BarChart,
102
+ PieChart,
103
+ ScatterChart,
104
+ RadarChart,
105
+ FunnelChart,
106
+ GaugeChart,
107
+ HeatmapChart,
108
+ TreeChart,
109
+ SankeyChart,
110
+ MapChart,
111
+ GridComponent,
112
+ TooltipComponent,
113
+ LegendComponent,
114
+ TitleComponent,
115
+ VisualMapComponent,
116
+ DataZoomComponent,
117
+ GeoComponent,
118
+ RadarComponent,
119
+ CanvasRenderer
120
+ ]);
121
+
122
+ // src/components/EChartBase/index.tsx
123
+ import { jsx as jsx2 } from "react/jsx-runtime";
124
+ function EChartBase({
125
+ option,
126
+ height = 256,
127
+ onSelect,
128
+ className,
129
+ style,
130
+ slot
131
+ }) {
132
+ const hostRef = useRef(null);
133
+ const chartRef = useRef(null);
134
+ const onSelectRef = useRef(onSelect);
135
+ onSelectRef.current = onSelect;
136
+ const [failed, setFailed] = useState(false);
137
+ useEffect(() => {
138
+ const host = hostRef.current;
139
+ if (!host) return;
140
+ let chart = null;
141
+ try {
142
+ chart = echarts.init(host);
143
+ } catch {
144
+ setFailed(true);
145
+ return;
146
+ }
147
+ chartRef.current = chart;
148
+ chart.on("click", (params) => {
149
+ onSelectRef.current?.({
150
+ name: params.name,
151
+ value: params.value,
152
+ seriesName: params.seriesName,
153
+ dataIndex: params.dataIndex
154
+ });
155
+ });
156
+ const observer2 = new ResizeObserver(() => chart?.resize());
157
+ observer2.observe(host);
158
+ return () => {
159
+ observer2.disconnect();
160
+ chart?.dispose();
161
+ chartRef.current = null;
162
+ };
163
+ }, []);
164
+ useEffect(() => {
165
+ try {
166
+ chartRef.current?.setOption(option, { notMerge: true });
167
+ } catch {
168
+ }
169
+ }, [option]);
170
+ if (failed) {
171
+ return /* @__PURE__ */ jsx2(
172
+ "div",
173
+ {
174
+ "data-slot": "chart-fallback",
175
+ className: cn(
176
+ "flex h-32 w-full items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground",
177
+ className
178
+ ),
179
+ style,
180
+ children: "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u56FE\u8868\u6E32\u67D3"
181
+ }
182
+ );
183
+ }
184
+ return /* @__PURE__ */ jsx2(
185
+ "div",
186
+ {
187
+ ref: hostRef,
188
+ "data-slot": slot,
189
+ className: cn("w-full", className),
190
+ style: { height: typeof height === "number" ? `${height}px` : height, ...style }
191
+ }
192
+ );
193
+ }
194
+
195
+ // src/components/lib/option-builders.ts
196
+ function pickColor(theme, colors, index) {
197
+ if (colors && colors.length > 0) return colors[index % colors.length];
198
+ return theme.palette[index % theme.palette.length];
199
+ }
200
+ function toNumber(value) {
201
+ const n = Number(value);
202
+ return Number.isFinite(n) ? n : 0;
203
+ }
204
+ function axisLabel(theme) {
205
+ return { color: theme.muted };
206
+ }
207
+ function grid() {
208
+ return { left: 8, right: 16, top: 40, bottom: 4, containLabel: true };
209
+ }
210
+ function axisTooltip(theme) {
211
+ return {
212
+ trigger: "axis",
213
+ backgroundColor: theme.card,
214
+ borderColor: theme.border,
215
+ textStyle: { color: theme.foreground }
216
+ };
217
+ }
218
+ function itemTooltip(theme) {
219
+ return {
220
+ trigger: "item",
221
+ backgroundColor: theme.card,
222
+ borderColor: theme.border,
223
+ textStyle: { color: theme.foreground }
224
+ };
225
+ }
226
+ function titleOption(title) {
227
+ return title ? { text: title, left: 8, top: 4 } : void 0;
228
+ }
229
+ function legendOption(theme, show) {
230
+ return show ? { top: 4, textStyle: { color: theme.muted } } : void 0;
231
+ }
232
+ function categorySeries(input, theme, kind, area) {
233
+ const rows = input.data;
234
+ const keys = input.yKeys && input.yKeys.length > 0 ? input.yKeys : ["value"];
235
+ const series = keys.map((key, index) => ({
236
+ type: kind,
237
+ name: key,
238
+ data: rows.map((row) => toNumber(row[key])),
239
+ ...kind === "line" ? { smooth: input.smooth ?? false, symbolSize: 6 } : {},
240
+ ...area ? { areaStyle: { opacity: input.fillOpacity ?? 0.25 } } : {},
241
+ ...input.stacked ? { stack: "total" } : {},
242
+ ...kind === "line" ? { emphasis: { focus: "series" } } : {},
243
+ itemStyle: { color: pickColor(theme, input.colors, index) },
244
+ ...kind === "line" ? { lineStyle: { color: pickColor(theme, input.colors, index) } } : {},
245
+ ...area ? { lineStyle: { color: pickColor(theme, input.colors, index) } } : {}
246
+ }));
247
+ const legend = legendOption(theme, keys.length > 1);
248
+ return {
249
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
250
+ title: titleOption(input.title),
251
+ grid: grid(),
252
+ tooltip: axisTooltip(theme),
253
+ ...legend ? { legend } : {},
254
+ xAxis: { type: "category", data: rows.map((row) => String(input.xKey ? row[input.xKey] : "")), axisLabel: axisLabel(theme), axisLine: { lineStyle: { color: theme.border } } },
255
+ yAxis: { type: "value", axisLabel: axisLabel(theme), splitLine: { lineStyle: { color: theme.border } } },
256
+ series
257
+ };
258
+ }
259
+ function buildLineOption(input, theme) {
260
+ return categorySeries(input, theme, "line", input.showArea ?? false);
261
+ }
262
+ function buildColumnOption(input, theme) {
263
+ return categorySeries(input, theme, "bar", false);
264
+ }
265
+ function buildBarOption(input, theme) {
266
+ const rows = input.data;
267
+ const keys = input.yKeys && input.yKeys.length > 0 ? input.yKeys : ["value"];
268
+ const series = keys.map((key, index) => ({
269
+ type: "bar",
270
+ name: key,
271
+ data: rows.map((row) => toNumber(row[key])),
272
+ ...input.stacked ? { stack: "total" } : {},
273
+ itemStyle: { color: pickColor(theme, input.colors, index) }
274
+ }));
275
+ const legend = legendOption(theme, keys.length > 1);
276
+ return {
277
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
278
+ title: titleOption(input.title),
279
+ grid: grid(),
280
+ tooltip: axisTooltip(theme),
281
+ ...legend ? { legend } : {},
282
+ xAxis: { type: "value", axisLabel: axisLabel(theme), splitLine: { lineStyle: { color: theme.border } } },
283
+ yAxis: { type: "category", data: rows.map((row) => String(input.yKey ? row[input.yKey] : "")), axisLabel: axisLabel(theme), axisLine: { lineStyle: { color: theme.border } } },
284
+ series
285
+ };
286
+ }
287
+ function buildAreaOption(input, theme) {
288
+ const withArea = { ...input, showArea: true };
289
+ return categorySeries(withArea, theme, "line", true);
290
+ }
291
+ function pieOption(input, theme, radius, extra) {
292
+ const nameKey = input.nameKey ?? "name";
293
+ const valueKey = input.valueKey ?? "value";
294
+ return {
295
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
296
+ title: titleOption(input.title),
297
+ tooltip: itemTooltip(theme),
298
+ legend: { bottom: 0, textStyle: { color: theme.muted } },
299
+ series: [
300
+ {
301
+ type: "pie",
302
+ radius,
303
+ center: ["50%", "52%"],
304
+ data: input.data.map((row) => ({ name: String(row[nameKey] ?? ""), value: toNumber(row[valueKey]) })),
305
+ label: { show: input.showLabel ?? false, color: theme.muted },
306
+ emphasis: { scaleSize: 6 }
307
+ }
308
+ ],
309
+ ...extra
310
+ };
311
+ }
312
+ function buildPieOption(input, theme) {
313
+ return pieOption(input, theme, [0, "72%"], {});
314
+ }
315
+ function buildDonutOption(input, theme) {
316
+ const inner = input.innerRadius ?? "48%";
317
+ const outer = input.outerRadius ?? "72%";
318
+ const extra = {};
319
+ if (input.centerValue !== void 0 || input.centerLabel !== void 0) {
320
+ extra.title = {
321
+ text: input.centerValue !== void 0 ? String(input.centerValue) : "",
322
+ subtext: input.centerLabel ?? "",
323
+ left: "center",
324
+ top: "40%",
325
+ textStyle: { color: theme.foreground, fontSize: 22 },
326
+ subtextStyle: { color: theme.muted }
327
+ };
328
+ }
329
+ return pieOption(input, theme, [inner, outer], extra);
330
+ }
331
+ function scatterSeries(input, theme, extra) {
332
+ const xKey = input.xKey ?? "x";
333
+ const yKey = input.yKey ?? "y";
334
+ const groups = /* @__PURE__ */ new Map();
335
+ if (input.seriesKey) {
336
+ for (const row of input.data) {
337
+ const g = String(row[input.seriesKey] ?? "");
338
+ if (!groups.has(g)) groups.set(g, []);
339
+ groups.get(g).push(row);
340
+ }
341
+ } else {
342
+ groups.set("", input.data);
343
+ }
344
+ const names = [...groups.keys()];
345
+ const series = names.map((name, index) => ({
346
+ type: "scatter",
347
+ name: name || void 0,
348
+ data: groups.get(name).map(
349
+ (row) => extra?.datum ? extra.datum(row) : [toNumber(row[xKey]), toNumber(row[yKey])]
350
+ ),
351
+ symbolSize: extra?.symbolSize ?? 10,
352
+ itemStyle: { color: pickColor(theme, input.colors, index) }
353
+ }));
354
+ const legend = legendOption(theme, input.seriesKey !== void 0 && names.length > 1);
355
+ return {
356
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
357
+ title: titleOption(input.title),
358
+ grid: grid(),
359
+ tooltip: axisTooltip(theme),
360
+ ...legend ? { legend } : {},
361
+ xAxis: { type: "value", axisLabel: axisLabel(theme), splitLine: { lineStyle: { color: theme.border } } },
362
+ yAxis: { type: "value", axisLabel: axisLabel(theme), splitLine: { lineStyle: { color: theme.border } } },
363
+ series
364
+ };
365
+ }
366
+ function buildScatterOption(input, theme) {
367
+ return scatterSeries(input, theme);
368
+ }
369
+ function buildBubbleOption(input, theme) {
370
+ const sizeKey = input.sizeKey ?? "size";
371
+ const sizes = input.data.map((row) => toNumber(row[sizeKey]));
372
+ const min = Math.min(...sizes, 0);
373
+ const max = Math.max(...sizes, 1);
374
+ const span = max - min || 1;
375
+ return scatterSeries(input, theme, {
376
+ datum: (row) => [toNumber(row[input.xKey ?? "x"]), toNumber(row[input.yKey ?? "y"]), toNumber(row[sizeKey])],
377
+ symbolSize: (datum) => {
378
+ const [x, y, size] = datum;
379
+ void x;
380
+ void y;
381
+ return 12 + (toNumber(size) - min) / span * 36;
382
+ }
383
+ });
384
+ }
385
+ function buildRadarOption(input, theme) {
386
+ const indicatorKey = input.indicatorKey ?? "indicator";
387
+ const keys = input.yKeys && input.yKeys.length > 0 ? input.yKeys : ["value"];
388
+ return {
389
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
390
+ title: titleOption(input.title),
391
+ tooltip: itemTooltip(theme),
392
+ ...keys.length > 1 ? { legend: legendOption(theme, true) } : {},
393
+ radar: {
394
+ indicator: input.data.map((row) => ({ name: String(row[indicatorKey] ?? ""), max: 100 })),
395
+ axisName: { color: theme.muted },
396
+ splitLine: { lineStyle: { color: theme.border } },
397
+ splitArea: { areaStyle: { color: [] } }
398
+ },
399
+ series: [
400
+ {
401
+ type: "radar",
402
+ data: keys.map((key) => ({
403
+ name: key,
404
+ value: input.data.map((row) => toNumber(row[key]))
405
+ }))
406
+ }
407
+ ]
408
+ };
409
+ }
410
+ function buildFunnelOption(input, theme) {
411
+ const nameKey = input.nameKey ?? "name";
412
+ const valueKey = input.valueKey ?? "value";
413
+ return {
414
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
415
+ title: titleOption(input.title),
416
+ tooltip: itemTooltip(theme),
417
+ series: [
418
+ {
419
+ type: "funnel",
420
+ left: "12%",
421
+ width: "76%",
422
+ sort: input.sort ?? "descending",
423
+ gap: 2,
424
+ label: { show: true, position: "inside", color: theme.card },
425
+ data: input.data.map((row) => ({ name: String(row[nameKey] ?? ""), value: toNumber(row[valueKey]) }))
426
+ }
427
+ ]
428
+ };
429
+ }
430
+ function buildGaugeOption(input, theme) {
431
+ const min = input.min ?? 0;
432
+ const max = input.max ?? 100;
433
+ const span = max - min || 1;
434
+ const defaultThresholds = [{ value: max, color: theme.palette[0] }];
435
+ const stops = (input.thresholds && input.thresholds.length > 0 ? input.thresholds : defaultThresholds).slice().sort((a, b) => a.value - b.value).map((t, index, arr) => {
436
+ const upper = index < arr.length - 1 ? t.value : max;
437
+ return [(upper - min) / span, t.color ?? theme.palette[0]];
438
+ });
439
+ return {
440
+ title: titleOption(input.title),
441
+ series: [
442
+ {
443
+ type: "gauge",
444
+ min,
445
+ max,
446
+ startAngle: 210,
447
+ endAngle: -30,
448
+ progress: { show: true, width: 10 },
449
+ axisLine: { lineStyle: { width: 10, color: stops } },
450
+ axisTick: { show: false },
451
+ splitLine: { show: false },
452
+ axisLabel: { show: false },
453
+ pointer: { show: false },
454
+ anchor: { show: false },
455
+ title: { show: false },
456
+ detail: {
457
+ valueAnimation: true,
458
+ offsetCenter: [0, 0],
459
+ fontSize: 26,
460
+ color: theme.foreground,
461
+ formatter: (value) => `${value}${input.unit ?? ""}`
462
+ },
463
+ data: [{ value: toNumber(input.value) }]
464
+ }
465
+ ]
466
+ };
467
+ }
468
+ function valueRange(values) {
469
+ if (values.length === 0) return { min: 0, max: 1 };
470
+ const min = Math.min(...values);
471
+ const max = Math.max(...values);
472
+ return max === min ? { min, max: min + 1 } : { min, max };
473
+ }
474
+ function buildHeatmapOption(input, theme) {
475
+ const xKey = input.xKey ?? "x";
476
+ const yKey = input.yKey ?? "y";
477
+ const valueKey = input.valueKey ?? "value";
478
+ const xs = [...new Set(input.data.map((row) => String(row[xKey])))];
479
+ const ys = [...new Set(input.data.map((row) => String(row[yKey])))];
480
+ const range = valueRange(input.data.map((row) => toNumber(row[valueKey])));
481
+ return {
482
+ title: titleOption(input.title),
483
+ grid: grid(),
484
+ tooltip: itemTooltip(theme),
485
+ xAxis: { type: "category", data: xs, axisLabel: axisLabel(theme), splitArea: { show: true } },
486
+ yAxis: { type: "category", data: ys, axisLabel: axisLabel(theme), splitArea: { show: true } },
487
+ visualMap: {
488
+ min: range.min,
489
+ max: range.max,
490
+ calculable: true,
491
+ orient: "horizontal",
492
+ left: "center",
493
+ bottom: 0,
494
+ textStyle: { color: theme.muted },
495
+ inRange: { color: [theme.palette[2] ?? theme.palette[0], theme.palette[0]] }
496
+ },
497
+ series: [
498
+ {
499
+ type: "heatmap",
500
+ data: input.data.map((row) => [String(row[xKey]), String(row[yKey]), toNumber(row[valueKey])]),
501
+ label: { show: false }
502
+ }
503
+ ]
504
+ };
505
+ }
506
+ function buildTreeOption(input, theme) {
507
+ const horizontal = input.orient === "horizontal";
508
+ return {
509
+ title: titleOption(input.title),
510
+ tooltip: itemTooltip(theme),
511
+ series: [
512
+ {
513
+ type: "tree",
514
+ data: input.data,
515
+ layout: "orthogonal",
516
+ orient: horizontal ? "LR" : "TB",
517
+ edgeShape: input.edgeShape ?? "curve",
518
+ roam: false,
519
+ expandAndCollapse: true,
520
+ initialTreeDepth: input.initialTreeDepth ?? 2,
521
+ label: {
522
+ show: true,
523
+ position: horizontal ? "right" : "bottom",
524
+ color: theme.foreground,
525
+ fontSize: 12
526
+ },
527
+ itemStyle: { color: theme.palette[0], borderColor: theme.palette[0] },
528
+ lineStyle: { color: theme.border, width: 1.5, curveness: 0.5 },
529
+ leaves: {
530
+ itemStyle: { color: theme.palette[1], borderColor: theme.palette[1] }
531
+ },
532
+ emphasis: { focus: "relative" }
533
+ }
534
+ ]
535
+ };
536
+ }
537
+ function buildSankeyOption(input, theme) {
538
+ return {
539
+ color: theme.palette,
540
+ title: titleOption(input.title),
541
+ tooltip: itemTooltip(theme),
542
+ series: [
543
+ {
544
+ type: "sankey",
545
+ left: 24,
546
+ right: 64,
547
+ top: 40,
548
+ bottom: 24,
549
+ nodeWidth: 16,
550
+ nodeGap: 12,
551
+ draggable: false,
552
+ label: { color: theme.muted },
553
+ lineStyle: { color: "gradient", curveness: 0.5 },
554
+ emphasis: { focus: "adjacency" },
555
+ data: input.nodes,
556
+ links: input.links
557
+ }
558
+ ]
559
+ };
560
+ }
561
+ function buildMapOption(input, theme) {
562
+ const nameKey = input.nameKey ?? "name";
563
+ const valueKey = input.valueKey ?? "value";
564
+ const range = valueRange(input.data.map((row) => toNumber(row[valueKey])));
565
+ return {
566
+ title: titleOption(input.title),
567
+ tooltip: itemTooltip(theme),
568
+ visualMap: {
569
+ min: range.min,
570
+ max: range.max,
571
+ left: 8,
572
+ bottom: 8,
573
+ textStyle: { color: theme.muted },
574
+ inRange: { color: [theme.palette[2] ?? theme.palette[0], theme.palette[0]] }
575
+ },
576
+ series: [
577
+ {
578
+ type: "map",
579
+ map: input.mapName,
580
+ roam: false,
581
+ label: { show: false },
582
+ emphasis: { label: { show: true, color: theme.foreground } },
583
+ itemStyle: { borderColor: theme.card, borderWidth: 1 },
584
+ data: input.data.map((row) => ({ name: String(row[nameKey] ?? ""), value: toNumber(row[valueKey]) }))
585
+ }
586
+ ]
587
+ };
588
+ }
589
+ function buildComposedOption(input, theme) {
590
+ const rows = input.data;
591
+ const hasSecondAxis = input.series.some((s) => s.yAxisIndex === 1);
592
+ const series = input.series.map((s, index) => {
593
+ const color = pickColor(theme, input.colors, index);
594
+ return {
595
+ type: s.type === "area" ? "line" : s.type,
596
+ name: s.name ?? s.dataKey,
597
+ data: rows.map((row) => toNumber(row[s.dataKey])),
598
+ ...s.type === "line" ? { smooth: false, symbolSize: 6 } : {},
599
+ ...s.type === "area" ? { areaStyle: { opacity: 0.25 } } : {},
600
+ yAxisIndex: s.yAxisIndex ?? 0,
601
+ itemStyle: { color },
602
+ ...s.type !== "bar" ? { lineStyle: { color } } : {}
603
+ };
604
+ });
605
+ return {
606
+ color: input.colors && input.colors.length > 0 ? input.colors : theme.palette,
607
+ title: titleOption(input.title),
608
+ grid: grid(),
609
+ tooltip: axisTooltip(theme),
610
+ legend: legendOption(theme, true),
611
+ xAxis: { type: "category", data: rows.map((row) => String(input.xKey ? row[input.xKey] : "")), axisLabel: axisLabel(theme), axisLine: { lineStyle: { color: theme.border } } },
612
+ yAxis: hasSecondAxis ? [
613
+ { type: "value", axisLabel: axisLabel(theme), splitLine: { lineStyle: { color: theme.border } } },
614
+ { type: "value", axisLabel: axisLabel(theme), splitLine: { show: false } }
615
+ ] : { type: "value", axisLabel: axisLabel(theme), splitLine: { lineStyle: { color: theme.border } } },
616
+ series
617
+ };
618
+ }
619
+
620
+ // src/components/lib/use-chart-theme.ts
621
+ import { useSyncExternalStore } from "react";
622
+
623
+ // src/components/lib/color.ts
624
+ var LPAREN = String.fromCharCode(40);
625
+ var RPAREN = String.fromCharCode(41);
626
+ var OKLCH_RE = new RegExp(
627
+ "^oklch" + String.fromCharCode(92) + LPAREN + "\\s*([\\d.]+%?)\\s+([-\\d.eE]+)\\s+([-\\d.eE]+)(?:\\s*\\/\\s*[\\d.]+%?)?\\s*" + String.fromCharCode(92) + RPAREN + "$",
628
+ "i"
629
+ );
630
+ var OKLAB_RE = new RegExp(
631
+ "^oklab" + String.fromCharCode(92) + LPAREN + "\\s*([\\d.]+%?)\\s+([-\\d.eE]+)\\s+([-\\d.eE]+)(?:\\s*\\/\\s*[\\d.]+%?)?\\s*" + String.fromCharCode(92) + RPAREN + "$",
632
+ "i"
633
+ );
634
+ function parseLightness(raw) {
635
+ const value = parseFloat(raw);
636
+ return raw.endsWith("%") ? value / 100 : value;
637
+ }
638
+ function oklabToLinearSrgbColor(L, a, b) {
639
+ const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
640
+ const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
641
+ const s_ = L - 0.0894841775 * a - 1.291485548 * b;
642
+ const l = l_ * l_ * l_;
643
+ const m = m_ * m_ * m_;
644
+ const s = s_ * s_ * s_;
645
+ return [
646
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
647
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
648
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
649
+ ];
650
+ }
651
+ function linearToSrgbChannel(c) {
652
+ const clamped = Math.min(1, Math.max(0, c));
653
+ const encoded = clamped <= 31308e-7 ? 12.92 * clamped : 1.055 * Math.pow(clamped, 1 / 2.4) - 0.055;
654
+ return Math.round(encoded * 255);
655
+ }
656
+ function formatSrgbString(r, g, b) {
657
+ return "rgb" + LPAREN + `${linearToSrgbChannel(r)}, ${linearToSrgbChannel(g)}, ${linearToSrgbChannel(b)}` + RPAREN;
658
+ }
659
+ function normalizeColor(value) {
660
+ const trimmed = value.trim();
661
+ const oklch = OKLCH_RE.exec(trimmed);
662
+ if (oklch) {
663
+ const L = parseLightness(oklch[1]);
664
+ const C = parseFloat(oklch[2]);
665
+ const h = parseFloat(oklch[3]) * Math.PI / 180;
666
+ const [r, g, b] = oklabToLinearSrgbColor(L, C * Math.cos(h), C * Math.sin(h));
667
+ return formatSrgbString(r, g, b);
668
+ }
669
+ const oklab = OKLAB_RE.exec(trimmed);
670
+ if (oklab) {
671
+ const L = parseLightness(oklab[1]);
672
+ const a = parseFloat(oklab[2]);
673
+ const b = parseFloat(oklab[3]);
674
+ const [r, g, bl] = oklabToLinearSrgbColor(L, a, b);
675
+ return formatSrgbString(r, g, bl);
676
+ }
677
+ return trimmed;
678
+ }
679
+
680
+ // src/components/lib/theme.ts
681
+ var FALLBACK_THEME = {
682
+ palette: ["steelblue", "seagreen", "darkorange", "slateblue", "tomato"],
683
+ foreground: "black",
684
+ muted: "gray",
685
+ border: "gainsboro",
686
+ card: "white",
687
+ success: "seagreen",
688
+ warning: "darkorange",
689
+ destructive: "tomato",
690
+ info: "steelblue"
691
+ };
692
+ var cached = null;
693
+ function getChartTheme() {
694
+ if (cached) return cached;
695
+ if (typeof document === "undefined") return FALLBACK_THEME;
696
+ try {
697
+ const style = getComputedStyle(document.documentElement);
698
+ const read = (name) => normalizeColor(style.getPropertyValue(name));
699
+ const readColor = (name, fallback) => read(name) || fallback;
700
+ const palette = [1, 2, 3, 4, 5].map(
701
+ (i, index) => readColor(`--chart-${i}`, FALLBACK_THEME.palette[index])
702
+ );
703
+ cached = {
704
+ palette,
705
+ foreground: readColor("--foreground", FALLBACK_THEME.foreground),
706
+ muted: readColor("--muted-foreground", FALLBACK_THEME.muted),
707
+ border: readColor("--border", FALLBACK_THEME.border),
708
+ card: readColor("--card", FALLBACK_THEME.card),
709
+ success: readColor("--success", FALLBACK_THEME.success),
710
+ warning: readColor("--warning", FALLBACK_THEME.warning),
711
+ destructive: readColor("--destructive", FALLBACK_THEME.destructive),
712
+ info: readColor("--info", FALLBACK_THEME.info)
713
+ };
714
+ return cached;
715
+ } catch {
716
+ return FALLBACK_THEME;
717
+ }
718
+ }
719
+ function resetChartTheme() {
720
+ cached = null;
721
+ }
722
+ var CHART_SKIN_CHANGE_EVENT = "pactor:skin-change";
723
+ var listeners = /* @__PURE__ */ new Set();
724
+ var observer = null;
725
+ var scheduled = false;
726
+ function scheduleNotify() {
727
+ if (scheduled) return;
728
+ scheduled = true;
729
+ const enqueue = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
730
+ enqueue(() => {
731
+ scheduled = false;
732
+ resetChartTheme();
733
+ for (const listener of [...listeners]) {
734
+ listener();
735
+ }
736
+ });
737
+ }
738
+ function handleResourceLoad(event) {
739
+ const target = event.target;
740
+ if (target instanceof HTMLLinkElement || target instanceof HTMLStyleElement) {
741
+ scheduleNotify();
742
+ }
743
+ }
744
+ function subscribeChartTheme(listener) {
745
+ if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
746
+ return () => {
747
+ };
748
+ }
749
+ listeners.add(listener);
750
+ if (!observer) {
751
+ observer = new MutationObserver(scheduleNotify);
752
+ observer.observe(document.documentElement, { attributes: true });
753
+ observer.observe(document.head, {
754
+ attributes: true,
755
+ childList: true,
756
+ characterData: true,
757
+ subtree: true
758
+ });
759
+ document.addEventListener("load", handleResourceLoad, true);
760
+ window.addEventListener(CHART_SKIN_CHANGE_EVENT, scheduleNotify);
761
+ }
762
+ return () => {
763
+ listeners.delete(listener);
764
+ if (listeners.size === 0 && observer) {
765
+ observer.disconnect();
766
+ observer = null;
767
+ document.removeEventListener("load", handleResourceLoad, true);
768
+ window.removeEventListener(CHART_SKIN_CHANGE_EVENT, scheduleNotify);
769
+ }
770
+ };
771
+ }
772
+
773
+ // src/components/lib/use-chart-theme.ts
774
+ function useChartTheme() {
775
+ return useSyncExternalStore(subscribeChartTheme, getChartTheme, getChartTheme);
776
+ }
777
+
778
+ // src/components/LineChart/index.tsx
779
+ import { jsx as jsx3 } from "react/jsx-runtime";
780
+ function LineChart2({
781
+ data = [],
782
+ xKey,
783
+ yKeys,
784
+ smooth = false,
785
+ showArea = false,
786
+ stacked = false,
787
+ colors,
788
+ title,
789
+ height,
790
+ onSelect,
791
+ className,
792
+ style
793
+ }) {
794
+ const option = buildLineOption(
795
+ { data, xKey, yKeys, smooth, showArea, stacked, colors, title },
796
+ useChartTheme()
797
+ );
798
+ return /* @__PURE__ */ jsx3(
799
+ EChartBase,
800
+ {
801
+ slot: "line-chart",
802
+ option,
803
+ height,
804
+ onSelect,
805
+ className,
806
+ style
807
+ }
808
+ );
809
+ }
810
+
811
+ // src/components/ColumnChart/index.tsx
812
+ import { jsx as jsx4 } from "react/jsx-runtime";
813
+ function ColumnChart({
814
+ data = [],
815
+ xKey,
816
+ yKeys,
817
+ stacked = false,
818
+ colors,
819
+ title,
820
+ height,
821
+ onSelect,
822
+ className,
823
+ style
824
+ }) {
825
+ const option = buildColumnOption(
826
+ { data, xKey, yKeys, stacked, colors, title },
827
+ useChartTheme()
828
+ );
829
+ return /* @__PURE__ */ jsx4(
830
+ EChartBase,
831
+ {
832
+ slot: "column-chart",
833
+ option,
834
+ height,
835
+ onSelect,
836
+ className,
837
+ style
838
+ }
839
+ );
840
+ }
841
+
842
+ // src/components/BarChart/index.tsx
843
+ import { jsx as jsx5 } from "react/jsx-runtime";
844
+ function BarChart2({
845
+ data = [],
846
+ yKey,
847
+ xKeys,
848
+ stacked = false,
849
+ colors,
850
+ title,
851
+ height,
852
+ onSelect,
853
+ className,
854
+ style
855
+ }) {
856
+ const option = buildBarOption(
857
+ { data, yKey, yKeys: xKeys, stacked, colors, title },
858
+ useChartTheme()
859
+ );
860
+ return /* @__PURE__ */ jsx5(
861
+ EChartBase,
862
+ {
863
+ slot: "bar-chart",
864
+ option,
865
+ height,
866
+ onSelect,
867
+ className,
868
+ style
869
+ }
870
+ );
871
+ }
872
+
873
+ // src/components/AreaChart/index.tsx
874
+ import { jsx as jsx6 } from "react/jsx-runtime";
875
+ function AreaChart({
876
+ data = [],
877
+ xKey,
878
+ yKeys,
879
+ stacked = false,
880
+ fillOpacity,
881
+ colors,
882
+ title,
883
+ height,
884
+ onSelect,
885
+ className,
886
+ style
887
+ }) {
888
+ const option = buildAreaOption(
889
+ { data, xKey, yKeys, stacked, fillOpacity, colors, title },
890
+ useChartTheme()
891
+ );
892
+ return /* @__PURE__ */ jsx6(
893
+ EChartBase,
894
+ {
895
+ slot: "area-chart",
896
+ option,
897
+ height,
898
+ onSelect,
899
+ className,
900
+ style
901
+ }
902
+ );
903
+ }
904
+
905
+ // src/components/PieChart/index.tsx
906
+ import { jsx as jsx7 } from "react/jsx-runtime";
907
+ function PieChart2({
908
+ data = [],
909
+ nameKey,
910
+ valueKey,
911
+ showLabel,
912
+ colors,
913
+ title,
914
+ height,
915
+ onSelect,
916
+ className,
917
+ style
918
+ }) {
919
+ const option = buildPieOption(
920
+ { data, nameKey, valueKey, showLabel, colors, title },
921
+ useChartTheme()
922
+ );
923
+ return /* @__PURE__ */ jsx7(
924
+ EChartBase,
925
+ {
926
+ slot: "pie-chart",
927
+ option,
928
+ height,
929
+ onSelect,
930
+ className,
931
+ style
932
+ }
933
+ );
934
+ }
935
+
936
+ // src/components/DonutChart/index.tsx
937
+ import { jsx as jsx8 } from "react/jsx-runtime";
938
+ function DonutChart({
939
+ data = [],
940
+ nameKey,
941
+ valueKey,
942
+ innerRadius,
943
+ outerRadius,
944
+ centerLabel,
945
+ centerValue,
946
+ showLabel,
947
+ colors,
948
+ title,
949
+ height,
950
+ onSelect,
951
+ className,
952
+ style
953
+ }) {
954
+ const option = buildDonutOption(
955
+ {
956
+ data,
957
+ nameKey,
958
+ valueKey,
959
+ innerRadius,
960
+ outerRadius,
961
+ centerLabel,
962
+ centerValue,
963
+ showLabel,
964
+ colors,
965
+ title
966
+ },
967
+ useChartTheme()
968
+ );
969
+ return /* @__PURE__ */ jsx8(
970
+ EChartBase,
971
+ {
972
+ slot: "donut-chart",
973
+ option,
974
+ height,
975
+ onSelect,
976
+ className,
977
+ style
978
+ }
979
+ );
980
+ }
981
+
982
+ // src/components/ScatterChart/index.tsx
983
+ import { jsx as jsx9 } from "react/jsx-runtime";
984
+ function ScatterChart2({
985
+ data = [],
986
+ xKey,
987
+ yKey,
988
+ seriesKey,
989
+ colors,
990
+ title,
991
+ height,
992
+ onSelect,
993
+ className,
994
+ style
995
+ }) {
996
+ const option = buildScatterOption(
997
+ { data, xKey, yKey, seriesKey, colors, title },
998
+ useChartTheme()
999
+ );
1000
+ return /* @__PURE__ */ jsx9(
1001
+ EChartBase,
1002
+ {
1003
+ slot: "scatter-chart",
1004
+ option,
1005
+ height,
1006
+ onSelect,
1007
+ className,
1008
+ style
1009
+ }
1010
+ );
1011
+ }
1012
+
1013
+ // src/components/BubbleChart/index.tsx
1014
+ import { jsx as jsx10 } from "react/jsx-runtime";
1015
+ function BubbleChart({
1016
+ data = [],
1017
+ xKey,
1018
+ yKey,
1019
+ sizeKey,
1020
+ seriesKey,
1021
+ colors,
1022
+ title,
1023
+ height,
1024
+ onSelect,
1025
+ className,
1026
+ style
1027
+ }) {
1028
+ const option = buildBubbleOption(
1029
+ { data, xKey, yKey, sizeKey, seriesKey, colors, title },
1030
+ useChartTheme()
1031
+ );
1032
+ return /* @__PURE__ */ jsx10(
1033
+ EChartBase,
1034
+ {
1035
+ slot: "bubble-chart",
1036
+ option,
1037
+ height,
1038
+ onSelect,
1039
+ className,
1040
+ style
1041
+ }
1042
+ );
1043
+ }
1044
+
1045
+ // src/components/RadarChart/index.tsx
1046
+ import { jsx as jsx11 } from "react/jsx-runtime";
1047
+ function RadarChart2({
1048
+ data = [],
1049
+ indicatorKey,
1050
+ yKeys,
1051
+ colors,
1052
+ title,
1053
+ height,
1054
+ onSelect,
1055
+ className,
1056
+ style
1057
+ }) {
1058
+ const option = buildRadarOption(
1059
+ { data, indicatorKey, yKeys, colors, title },
1060
+ useChartTheme()
1061
+ );
1062
+ return /* @__PURE__ */ jsx11(
1063
+ EChartBase,
1064
+ {
1065
+ slot: "radar-chart",
1066
+ option,
1067
+ height,
1068
+ onSelect,
1069
+ className,
1070
+ style
1071
+ }
1072
+ );
1073
+ }
1074
+
1075
+ // src/components/FunnelChart/index.tsx
1076
+ import { jsx as jsx12 } from "react/jsx-runtime";
1077
+ function FunnelChart2({
1078
+ data = [],
1079
+ nameKey,
1080
+ valueKey,
1081
+ sort,
1082
+ colors,
1083
+ title,
1084
+ height,
1085
+ onSelect,
1086
+ className,
1087
+ style
1088
+ }) {
1089
+ const option = buildFunnelOption(
1090
+ { data, nameKey, valueKey, sort, colors, title },
1091
+ useChartTheme()
1092
+ );
1093
+ return /* @__PURE__ */ jsx12(
1094
+ EChartBase,
1095
+ {
1096
+ slot: "funnel-chart",
1097
+ option,
1098
+ height,
1099
+ onSelect,
1100
+ className,
1101
+ style
1102
+ }
1103
+ );
1104
+ }
1105
+
1106
+ // src/components/GaugeChart/index.tsx
1107
+ import { jsx as jsx13 } from "react/jsx-runtime";
1108
+ function GaugeChart2({
1109
+ value = 0,
1110
+ min,
1111
+ max,
1112
+ thresholds,
1113
+ unit,
1114
+ title,
1115
+ height,
1116
+ onSelect,
1117
+ className,
1118
+ style
1119
+ }) {
1120
+ const option = buildGaugeOption(
1121
+ { value, min, max, thresholds, unit, title },
1122
+ useChartTheme()
1123
+ );
1124
+ return /* @__PURE__ */ jsx13(
1125
+ EChartBase,
1126
+ {
1127
+ slot: "gauge-chart",
1128
+ option,
1129
+ height,
1130
+ onSelect,
1131
+ className,
1132
+ style
1133
+ }
1134
+ );
1135
+ }
1136
+
1137
+ // src/components/Heatmap/index.tsx
1138
+ import { jsx as jsx14 } from "react/jsx-runtime";
1139
+ function Heatmap({
1140
+ data = [],
1141
+ xKey,
1142
+ yKey,
1143
+ valueKey,
1144
+ title,
1145
+ height,
1146
+ onSelect,
1147
+ className,
1148
+ style
1149
+ }) {
1150
+ const option = buildHeatmapOption(
1151
+ { data, xKey, yKey, valueKey, title },
1152
+ useChartTheme()
1153
+ );
1154
+ return /* @__PURE__ */ jsx14(
1155
+ EChartBase,
1156
+ {
1157
+ slot: "heatmap",
1158
+ option,
1159
+ height,
1160
+ onSelect,
1161
+ className,
1162
+ style
1163
+ }
1164
+ );
1165
+ }
1166
+
1167
+ // src/components/TreeChart/index.tsx
1168
+ import { jsx as jsx15 } from "react/jsx-runtime";
1169
+ function TreeChart2({
1170
+ data = [],
1171
+ title,
1172
+ orient,
1173
+ edgeShape,
1174
+ initialTreeDepth,
1175
+ height,
1176
+ onSelect,
1177
+ className,
1178
+ style
1179
+ }) {
1180
+ const option = buildTreeOption(
1181
+ { data, title, orient, edgeShape, initialTreeDepth },
1182
+ useChartTheme()
1183
+ );
1184
+ return /* @__PURE__ */ jsx15(
1185
+ EChartBase,
1186
+ {
1187
+ slot: "tree-chart",
1188
+ option,
1189
+ height,
1190
+ onSelect,
1191
+ className,
1192
+ style
1193
+ }
1194
+ );
1195
+ }
1196
+
1197
+ // src/components/SankeyChart/index.tsx
1198
+ import { jsx as jsx16 } from "react/jsx-runtime";
1199
+ function SankeyChart2({
1200
+ nodes = [],
1201
+ links = [],
1202
+ title,
1203
+ height,
1204
+ onSelect,
1205
+ className,
1206
+ style
1207
+ }) {
1208
+ const option = buildSankeyOption({ nodes, links, title }, useChartTheme());
1209
+ return /* @__PURE__ */ jsx16(
1210
+ EChartBase,
1211
+ {
1212
+ slot: "sankey-chart",
1213
+ option,
1214
+ height,
1215
+ onSelect,
1216
+ className,
1217
+ style
1218
+ }
1219
+ );
1220
+ }
1221
+
1222
+ // src/components/MapChart/index.tsx
1223
+ import { useEffect as useEffect2, useState as useState2 } from "react";
1224
+ import { Empty } from "@pactor-app/ui/components";
1225
+ import { jsx as jsx17 } from "react/jsx-runtime";
1226
+ var fetchedMaps = /* @__PURE__ */ new Set();
1227
+ function hasRegisteredMap(mapName) {
1228
+ try {
1229
+ return typeof echarts.getMap === "function" && echarts.getMap(mapName) != null;
1230
+ } catch {
1231
+ return false;
1232
+ }
1233
+ }
1234
+ function MapChart2({
1235
+ mapName = "map",
1236
+ data = [],
1237
+ nameKey,
1238
+ valueKey,
1239
+ geoJson,
1240
+ geoJsonUrl,
1241
+ title,
1242
+ height,
1243
+ onSelect,
1244
+ className,
1245
+ style
1246
+ }) {
1247
+ const theme = useChartTheme();
1248
+ const [loadState, setLoadState] = useState2(
1249
+ () => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
1250
+ );
1251
+ if (geoJson) {
1252
+ try {
1253
+ echarts.registerMap(mapName, geoJson);
1254
+ } catch {
1255
+ }
1256
+ }
1257
+ useEffect2(() => {
1258
+ if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
1259
+ setLoadState("idle");
1260
+ return;
1261
+ }
1262
+ let cancelled = false;
1263
+ setLoadState("loading");
1264
+ fetch(geoJsonUrl).then((res) => {
1265
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
1266
+ return res.json();
1267
+ }).then((json) => {
1268
+ if (cancelled) return;
1269
+ echarts.registerMap(mapName, json);
1270
+ fetchedMaps.add(mapName);
1271
+ setLoadState("ready");
1272
+ }).catch(() => {
1273
+ if (cancelled) return;
1274
+ console.warn(`[MapChart] \u5730\u56FE\u6570\u636E\u52A0\u8F7D\u5931\u8D25\uFF1A${geoJsonUrl}`);
1275
+ setLoadState("error");
1276
+ });
1277
+ return () => {
1278
+ cancelled = true;
1279
+ };
1280
+ }, [geoJson, geoJsonUrl, mapName]);
1281
+ if (geoJsonUrl && !geoJson && loadState === "loading") {
1282
+ return /* @__PURE__ */ jsx17(
1283
+ "div",
1284
+ {
1285
+ "data-slot": "map-chart-loading",
1286
+ className,
1287
+ style: { height: typeof height === "number" ? `${height}px` : height ?? 256, ...style }
1288
+ }
1289
+ );
1290
+ }
1291
+ if (!geoJson && loadState === "error") {
1292
+ return /* @__PURE__ */ jsx17(
1293
+ Empty,
1294
+ {
1295
+ title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
1296
+ description: "\u8BF7\u68C0\u67E5 geoJsonUrl \u7F51\u7EDC\u53EF\u8FBE\u6027\uFF0C\u6216\u6539\u7528 geoJson / \u9884\u6CE8\u518C\u5730\u56FE",
1297
+ className,
1298
+ style
1299
+ }
1300
+ );
1301
+ }
1302
+ if (!geoJson && !hasRegisteredMap(mapName)) {
1303
+ console.warn(`[MapChart] \u5730\u56FE "${mapName}" \u672A\u6CE8\u518C\uFF1A\u8BF7\u4F20\u5165 geoJson / geoJsonUrl\uFF0C\u6216\u5728\u5E94\u7528\u542F\u52A8\u65F6 echarts.registerMap`);
1304
+ return /* @__PURE__ */ jsx17(
1305
+ Empty,
1306
+ {
1307
+ title: "\u5730\u56FE\u672A\u6CE8\u518C",
1308
+ description: "\u8BF7\u4F20\u5165 geoJson / geoJsonUrl\uFF0C\u6216\u5728\u5E94\u7528\u542F\u52A8\u65F6\u6CE8\u518C\u5730\u56FE\u6570\u636E",
1309
+ className,
1310
+ style
1311
+ }
1312
+ );
1313
+ }
1314
+ const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, theme);
1315
+ return /* @__PURE__ */ jsx17(
1316
+ EChartBase,
1317
+ {
1318
+ slot: "map-chart",
1319
+ option,
1320
+ height,
1321
+ onSelect,
1322
+ className,
1323
+ style
1324
+ }
1325
+ );
1326
+ }
1327
+
1328
+ // src/components/ComposedChart/index.tsx
1329
+ import { jsx as jsx18 } from "react/jsx-runtime";
1330
+ function ComposedChart({
1331
+ data = [],
1332
+ xKey,
1333
+ series = [],
1334
+ colors,
1335
+ title,
1336
+ height,
1337
+ onSelect,
1338
+ className,
1339
+ style
1340
+ }) {
1341
+ const option = buildComposedOption(
1342
+ { data, xKey, series, colors, title },
1343
+ useChartTheme()
1344
+ );
1345
+ return /* @__PURE__ */ jsx18(
1346
+ EChartBase,
1347
+ {
1348
+ slot: "composed-chart",
1349
+ option,
1350
+ height,
1351
+ onSelect,
1352
+ className,
1353
+ style
1354
+ }
1355
+ );
1356
+ }
1357
+
1358
+ // src/index.ts
1359
+ var chartComponents = {
1360
+ MetricCard,
1361
+ LineChart: LineChart2,
1362
+ ColumnChart,
1363
+ BarChart: BarChart2,
1364
+ AreaChart,
1365
+ PieChart: PieChart2,
1366
+ DonutChart,
1367
+ ScatterChart: ScatterChart2,
1368
+ BubbleChart,
1369
+ RadarChart: RadarChart2,
1370
+ FunnelChart: FunnelChart2,
1371
+ GaugeChart: GaugeChart2,
1372
+ Heatmap,
1373
+ TreeChart: TreeChart2,
1374
+ SankeyChart: SankeyChart2,
1375
+ MapChart: MapChart2,
1376
+ ComposedChart
1377
+ };
1378
+ function registerChartComponents(registry) {
1379
+ for (const [type, component] of Object.entries(chartComponents)) {
1380
+ registry.register(type, component);
1381
+ }
1382
+ }
1383
+ function createChartComponentRegistry() {
1384
+ const registry = new Registry("ComponentRegistry");
1385
+ registerChartComponents(registry);
1386
+ return registry;
1387
+ }
1388
+ export {
1389
+ AreaChart,
1390
+ BarChart2 as BarChart,
1391
+ BubbleChart,
1392
+ ColumnChart,
1393
+ ComposedChart,
1394
+ DonutChart,
1395
+ EChartBase,
1396
+ FunnelChart2 as FunnelChart,
1397
+ GaugeChart2 as GaugeChart,
1398
+ Heatmap,
1399
+ LineChart2 as LineChart,
1400
+ MapChart2 as MapChart,
1401
+ MetricCard,
1402
+ PieChart2 as PieChart,
1403
+ RadarChart2 as RadarChart,
1404
+ SankeyChart2 as SankeyChart,
1405
+ ScatterChart2 as ScatterChart,
1406
+ TreeChart2 as TreeChart,
1407
+ chartComponents,
1408
+ createChartComponentRegistry,
1409
+ registerChartComponents
1410
+ };