@particle-academy/fancy-echarts 1.2.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,606 @@
1
+ import { forwardRef, useMemo, useRef, useState, useEffect, useSyncExternalStore } from 'react';
2
+ import { getInstanceByDom, init, use, registerTheme as registerTheme$1 } from 'echarts/core';
3
+ import { jsx, Fragment } from 'react/jsx-runtime';
4
+ import { LineChart, BarChart, PieChart, ScatterChart, RadarChart, HeatmapChart, GaugeChart, FunnelChart, TreemapChart, SunburstChart, SankeyChart, GraphChart, CandlestickChart, BoxplotChart, ParallelChart, ThemeRiverChart, MapChart, CustomChart, EffectScatterChart, PictorialBarChart } from 'echarts/charts';
5
+ export { BarChart, BoxplotChart, CandlestickChart, CustomChart, EffectScatterChart, FunnelChart, GaugeChart, GraphChart, HeatmapChart, LineChart, MapChart, ParallelChart, PictorialBarChart, PieChart, RadarChart, SankeyChart, ScatterChart, SunburstChart, ThemeRiverChart, TreemapChart } from 'echarts/charts';
6
+ import { GridComponent, TooltipComponent, TitleComponent, LegendComponent, DataZoomComponent, ToolboxComponent, VisualMapComponent, GeoComponent, ParallelComponent, CalendarComponent, GraphicComponent, PolarComponent, RadarComponent, DatasetComponent, MarkLineComponent, MarkPointComponent, MarkAreaComponent, TimelineComponent, BrushComponent, SingleAxisComponent } from 'echarts/components';
7
+ export { CalendarComponent, DataZoomComponent, DatasetComponent, GeoComponent, GraphicComponent, GridComponent, LegendComponent, PolarComponent, TitleComponent, ToolboxComponent, TooltipComponent, VisualMapComponent } from 'echarts/components';
8
+ import { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
9
+ export { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
10
+
11
+ // src/components/EChart.tsx
12
+ function useResizeObserver(ref, callback) {
13
+ const callbackRef = useRef(callback);
14
+ callbackRef.current = callback;
15
+ useEffect(() => {
16
+ const element = ref.current;
17
+ if (!element) return;
18
+ const observer = new ResizeObserver(() => {
19
+ callbackRef.current();
20
+ });
21
+ observer.observe(element);
22
+ return () => {
23
+ observer.disconnect();
24
+ };
25
+ }, [ref]);
26
+ }
27
+
28
+ // src/hooks/use-echarts.ts
29
+ function useDarkMode() {
30
+ return useSyncExternalStore(
31
+ (callback) => {
32
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
33
+ mq.addEventListener("change", callback);
34
+ return () => mq.removeEventListener("change", callback);
35
+ },
36
+ () => window.matchMedia("(prefers-color-scheme: dark)").matches,
37
+ () => false
38
+ );
39
+ }
40
+ function useECharts(options) {
41
+ const {
42
+ option,
43
+ theme,
44
+ renderer = "canvas",
45
+ notMerge = false,
46
+ lazyUpdate = false,
47
+ showLoading = false,
48
+ loadingOption,
49
+ onEvents,
50
+ autoResize = true
51
+ } = options;
52
+ const isDark = useDarkMode();
53
+ const autoDark = theme === void 0 && isDark;
54
+ const resolvedTheme = theme !== void 0 ? theme : isDark ? "dark" : void 0;
55
+ const chartRef = useRef(null);
56
+ const instanceRef = useRef(null);
57
+ const [instance, setInstance] = useState(null);
58
+ useEffect(() => {
59
+ if (!chartRef.current) return;
60
+ const existing = getInstanceByDom(chartRef.current);
61
+ if (existing) {
62
+ existing.dispose();
63
+ }
64
+ const chart = init(chartRef.current, resolvedTheme, { renderer });
65
+ instanceRef.current = chart;
66
+ setInstance(chart);
67
+ return () => {
68
+ chart.dispose();
69
+ instanceRef.current = null;
70
+ setInstance(null);
71
+ };
72
+ }, [resolvedTheme, renderer]);
73
+ useEffect(() => {
74
+ const chart = instanceRef.current;
75
+ if (!chart || !option) return;
76
+ const finalOption = autoDark ? { backgroundColor: "transparent", ...option } : option;
77
+ chart.setOption(finalOption, { notMerge, lazyUpdate });
78
+ }, [option, notMerge, lazyUpdate, autoDark]);
79
+ useEffect(() => {
80
+ const chart = instanceRef.current;
81
+ if (!chart) return;
82
+ if (showLoading) {
83
+ chart.showLoading("default", loadingOption);
84
+ } else {
85
+ chart.hideLoading();
86
+ }
87
+ }, [showLoading, loadingOption]);
88
+ useEffect(() => {
89
+ const chart = instanceRef.current;
90
+ if (!chart || !onEvents) return;
91
+ const entries = Object.entries(onEvents);
92
+ for (const [event, handler] of entries) {
93
+ chart.on(event, handler);
94
+ }
95
+ return () => {
96
+ for (const [event, handler] of entries) {
97
+ chart.off(event, handler);
98
+ }
99
+ };
100
+ }, [onEvents]);
101
+ useResizeObserver(chartRef, () => {
102
+ if (autoResize && instanceRef.current) {
103
+ instanceRef.current.resize();
104
+ }
105
+ });
106
+ return { chartRef, instance };
107
+ }
108
+ var DEFAULT_STYLE = { width: "100%", height: 400 };
109
+ var EChartBase = forwardRef(
110
+ ({
111
+ option,
112
+ theme,
113
+ renderer,
114
+ notMerge,
115
+ lazyUpdate,
116
+ showLoading,
117
+ loadingOption,
118
+ onEvents,
119
+ autoResize = true,
120
+ style,
121
+ className,
122
+ ...rest
123
+ }, _ref) => {
124
+ const { chartRef } = useECharts({
125
+ option,
126
+ theme,
127
+ renderer,
128
+ notMerge,
129
+ lazyUpdate,
130
+ showLoading,
131
+ loadingOption,
132
+ onEvents,
133
+ autoResize
134
+ });
135
+ return /* @__PURE__ */ jsx(
136
+ "div",
137
+ {
138
+ ref: chartRef,
139
+ style: { ...DEFAULT_STYLE, ...style },
140
+ className,
141
+ ...rest
142
+ }
143
+ );
144
+ }
145
+ );
146
+ EChartBase.displayName = "EChart";
147
+ function createSeriesComponent(seriesType, displayName) {
148
+ const Component = ({
149
+ data,
150
+ title,
151
+ xAxis,
152
+ yAxis,
153
+ tooltip = true,
154
+ legend = false,
155
+ grid,
156
+ seriesOptions = {},
157
+ option: extraOption = {},
158
+ style,
159
+ className,
160
+ ...rest
161
+ }) => {
162
+ const option = useMemo(() => {
163
+ const base = {};
164
+ if (title) {
165
+ base.title = { text: title };
166
+ }
167
+ if (tooltip === true) {
168
+ base.tooltip = { trigger: "axis" };
169
+ } else if (tooltip && typeof tooltip === "object") {
170
+ base.tooltip = tooltip;
171
+ }
172
+ if (legend === true) {
173
+ base.legend = {};
174
+ } else if (legend && typeof legend === "object") {
175
+ base.legend = legend;
176
+ }
177
+ if (grid) {
178
+ base.grid = grid;
179
+ }
180
+ const axisCharts = [
181
+ "line",
182
+ "bar",
183
+ "scatter",
184
+ "candlestick",
185
+ "boxplot",
186
+ "heatmap",
187
+ "effectScatter",
188
+ "pictorialBar"
189
+ ];
190
+ if (axisCharts.includes(seriesType)) {
191
+ base.xAxis = xAxis ?? { type: "category" };
192
+ base.yAxis = yAxis ?? { type: "value" };
193
+ }
194
+ if (Array.isArray(data)) {
195
+ base.series = [{ type: seriesType, data, ...seriesOptions }];
196
+ } else if (data && typeof data === "object" && "series" in data) {
197
+ const multiData = data;
198
+ if (multiData.categories && axisCharts.includes(seriesType)) {
199
+ base.xAxis = xAxis ?? {
200
+ type: "category",
201
+ data: multiData.categories
202
+ };
203
+ }
204
+ base.series = multiData.series.map((s) => ({
205
+ type: seriesType,
206
+ ...seriesOptions,
207
+ ...s
208
+ }));
209
+ } else {
210
+ base.series = [{ type: seriesType, data, ...seriesOptions }];
211
+ }
212
+ return { ...base, ...extraOption };
213
+ }, [
214
+ data,
215
+ title,
216
+ xAxis,
217
+ yAxis,
218
+ tooltip,
219
+ legend,
220
+ grid,
221
+ seriesOptions,
222
+ extraOption
223
+ ]);
224
+ return /* @__PURE__ */ jsx(
225
+ EChartBase,
226
+ {
227
+ option,
228
+ style,
229
+ className,
230
+ ...rest
231
+ }
232
+ );
233
+ };
234
+ Component.displayName = displayName;
235
+ return Component;
236
+ }
237
+ var EChart = Object.assign(EChartBase, {
238
+ Line: createSeriesComponent("line", "EChart.Line"),
239
+ Bar: createSeriesComponent("bar", "EChart.Bar"),
240
+ Pie: createSeriesComponent("pie", "EChart.Pie"),
241
+ Scatter: createSeriesComponent("scatter", "EChart.Scatter"),
242
+ Radar: createSeriesComponent("radar", "EChart.Radar"),
243
+ Heatmap: createSeriesComponent("heatmap", "EChart.Heatmap"),
244
+ Gauge: createSeriesComponent("gauge", "EChart.Gauge"),
245
+ Funnel: createSeriesComponent("funnel", "EChart.Funnel"),
246
+ Treemap: createSeriesComponent("treemap", "EChart.Treemap"),
247
+ Sunburst: createSeriesComponent("sunburst", "EChart.Sunburst"),
248
+ Sankey: createSeriesComponent("sankey", "EChart.Sankey"),
249
+ Graph: createSeriesComponent("graph", "EChart.Graph"),
250
+ Candlestick: createSeriesComponent("candlestick", "EChart.Candlestick"),
251
+ Boxplot: createSeriesComponent("boxplot", "EChart.Boxplot"),
252
+ Parallel: createSeriesComponent("parallel", "EChart.Parallel"),
253
+ ThemeRiver: createSeriesComponent("themeRiver", "EChart.ThemeRiver"),
254
+ Map: createSeriesComponent("map", "EChart.Map"),
255
+ Custom: createSeriesComponent("custom", "EChart.Custom"),
256
+ EffectScatter: createSeriesComponent(
257
+ "effectScatter",
258
+ "EChart.EffectScatter"
259
+ ),
260
+ PictorialBar: createSeriesComponent("pictorialBar", "EChart.PictorialBar")
261
+ });
262
+ var DEFAULT_STYLE2 = { width: "100%", height: 500 };
263
+ var glLoaded = false;
264
+ var glPromise = null;
265
+ function loadEChartsGL() {
266
+ if (glLoaded) return Promise.resolve();
267
+ if (!glPromise) {
268
+ glPromise = import('echarts-gl').then(() => {
269
+ glLoaded = true;
270
+ }).catch((err) => {
271
+ console.warn("Failed to load echarts-gl for 3D charts:", err);
272
+ });
273
+ }
274
+ return glPromise;
275
+ }
276
+ function WithGL({ children, style, className }) {
277
+ const [ready, setReady] = useState(glLoaded);
278
+ useEffect(() => {
279
+ if (glLoaded) {
280
+ setReady(true);
281
+ return;
282
+ }
283
+ loadEChartsGL().then(() => setReady(true));
284
+ }, []);
285
+ if (!ready) {
286
+ return /* @__PURE__ */ jsx("div", { style: { ...DEFAULT_STYLE2, ...style, display: "flex", alignItems: "center", justifyContent: "center" }, className, children: /* @__PURE__ */ jsx("span", { style: { color: "#9ca3af", fontSize: 14 }, children: "Loading 3D engine..." }) });
287
+ }
288
+ return /* @__PURE__ */ jsx(Fragment, { children });
289
+ }
290
+ var EChart3DInner = forwardRef(
291
+ ({
292
+ option,
293
+ theme,
294
+ renderer,
295
+ notMerge,
296
+ lazyUpdate,
297
+ showLoading,
298
+ loadingOption,
299
+ onEvents,
300
+ autoResize = true,
301
+ style,
302
+ className,
303
+ ...rest
304
+ }, _ref) => {
305
+ const { chartRef } = useECharts({
306
+ option,
307
+ theme,
308
+ renderer,
309
+ notMerge,
310
+ lazyUpdate,
311
+ showLoading,
312
+ loadingOption,
313
+ onEvents,
314
+ autoResize
315
+ });
316
+ return /* @__PURE__ */ jsx(
317
+ "div",
318
+ {
319
+ ref: chartRef,
320
+ style: { ...DEFAULT_STYLE2, ...style },
321
+ className,
322
+ ...rest
323
+ }
324
+ );
325
+ }
326
+ );
327
+ EChart3DInner.displayName = "EChart3DInner";
328
+ var EChart3DBase = forwardRef(
329
+ (props, ref) => {
330
+ const { style, className, ...rest } = props;
331
+ return /* @__PURE__ */ jsx(WithGL, { style, className, children: /* @__PURE__ */ jsx(EChart3DInner, { ref, style, className, ...rest }) });
332
+ }
333
+ );
334
+ EChart3DBase.displayName = "EChart3D";
335
+ function create3DSeriesComponent(seriesType, displayName) {
336
+ const Component = ({
337
+ data,
338
+ title,
339
+ tooltip = true,
340
+ seriesOptions = {},
341
+ option: extraOption = {},
342
+ style,
343
+ className,
344
+ ...rest
345
+ }) => {
346
+ const option = useMemo(() => {
347
+ const base = {};
348
+ if (title) {
349
+ base.title = { text: title };
350
+ }
351
+ if (tooltip === true) {
352
+ base.tooltip = {};
353
+ } else if (tooltip && typeof tooltip === "object") {
354
+ base.tooltip = tooltip;
355
+ }
356
+ if (["bar3D", "scatter3D", "line3D", "surface"].includes(seriesType)) {
357
+ base.xAxis3D = { type: "value" };
358
+ base.yAxis3D = { type: "value" };
359
+ base.zAxis3D = { type: "value" };
360
+ base.grid3D = {};
361
+ }
362
+ base.series = [{ type: seriesType, data, ...seriesOptions }];
363
+ return { ...base, ...extraOption };
364
+ }, [data, title, tooltip, seriesOptions, extraOption]);
365
+ return /* @__PURE__ */ jsx(
366
+ EChart3DBase,
367
+ {
368
+ option,
369
+ style,
370
+ className,
371
+ ...rest
372
+ }
373
+ );
374
+ };
375
+ Component.displayName = displayName;
376
+ return Component;
377
+ }
378
+ function createGlobeComponent() {
379
+ const Component = ({
380
+ title,
381
+ globe,
382
+ series = [],
383
+ option: extraOption = {},
384
+ style,
385
+ className,
386
+ ...rest
387
+ }) => {
388
+ const option = useMemo(() => {
389
+ const base = {};
390
+ if (title) {
391
+ base.title = { text: title };
392
+ }
393
+ base.globe = globe ?? {
394
+ baseTexture: "",
395
+ shading: "lambert",
396
+ atmosphere: { show: true }
397
+ };
398
+ if (series.length > 0) {
399
+ base.series = series;
400
+ }
401
+ return { ...base, ...extraOption };
402
+ }, [title, globe, series, extraOption]);
403
+ return /* @__PURE__ */ jsx(
404
+ EChart3DBase,
405
+ {
406
+ option,
407
+ style,
408
+ className,
409
+ ...rest
410
+ }
411
+ );
412
+ };
413
+ Component.displayName = "EChart3D.Globe";
414
+ return Component;
415
+ }
416
+ var EChart3D = Object.assign(EChart3DBase, {
417
+ Bar: create3DSeriesComponent("bar3D", "EChart3D.Bar"),
418
+ Scatter: create3DSeriesComponent("scatter3D", "EChart3D.Scatter"),
419
+ Line: create3DSeriesComponent("line3D", "EChart3D.Line"),
420
+ Surface: create3DSeriesComponent("surface", "EChart3D.Surface"),
421
+ Globe: createGlobeComponent()
422
+ });
423
+ var DEFAULT_STYLE3 = { width: "100%", height: 400 };
424
+ var EChartGraphic = forwardRef(
425
+ ({
426
+ elements,
427
+ option: extraOption = {},
428
+ theme,
429
+ renderer,
430
+ notMerge,
431
+ lazyUpdate,
432
+ showLoading,
433
+ loadingOption,
434
+ onEvents,
435
+ autoResize = true,
436
+ style,
437
+ className,
438
+ ...rest
439
+ }, _ref) => {
440
+ const option = useMemo(() => {
441
+ return {
442
+ graphic: {
443
+ elements
444
+ },
445
+ ...extraOption
446
+ };
447
+ }, [elements, extraOption]);
448
+ const { chartRef } = useECharts({
449
+ option,
450
+ theme,
451
+ renderer,
452
+ notMerge,
453
+ lazyUpdate,
454
+ showLoading,
455
+ loadingOption,
456
+ onEvents,
457
+ autoResize
458
+ });
459
+ return /* @__PURE__ */ jsx(
460
+ "div",
461
+ {
462
+ ref: chartRef,
463
+ style: { ...DEFAULT_STYLE3, ...style },
464
+ className,
465
+ ...rest
466
+ }
467
+ );
468
+ }
469
+ );
470
+ EChartGraphic.displayName = "EChartGraphic";
471
+ var allCharts = [
472
+ LineChart,
473
+ BarChart,
474
+ PieChart,
475
+ ScatterChart,
476
+ RadarChart,
477
+ HeatmapChart,
478
+ GaugeChart,
479
+ FunnelChart,
480
+ TreemapChart,
481
+ SunburstChart,
482
+ SankeyChart,
483
+ GraphChart,
484
+ CandlestickChart,
485
+ BoxplotChart,
486
+ ParallelChart,
487
+ ThemeRiverChart,
488
+ MapChart,
489
+ CustomChart,
490
+ EffectScatterChart,
491
+ PictorialBarChart
492
+ ];
493
+ var allComponents = [
494
+ GridComponent,
495
+ TooltipComponent,
496
+ TitleComponent,
497
+ LegendComponent,
498
+ DataZoomComponent,
499
+ ToolboxComponent,
500
+ VisualMapComponent,
501
+ GeoComponent,
502
+ ParallelComponent,
503
+ CalendarComponent,
504
+ GraphicComponent,
505
+ PolarComponent,
506
+ RadarComponent,
507
+ DatasetComponent,
508
+ MarkLineComponent,
509
+ MarkPointComponent,
510
+ MarkAreaComponent,
511
+ TimelineComponent,
512
+ BrushComponent,
513
+ SingleAxisComponent
514
+ ];
515
+ var allRenderers = [CanvasRenderer, SVGRenderer];
516
+ var registered = false;
517
+ function registerAll() {
518
+ if (registered) return;
519
+ use([...allCharts, ...allComponents, ...allRenderers]);
520
+ registered = true;
521
+ }
522
+ function registerCharts(...chartTypes) {
523
+ use(chartTypes);
524
+ }
525
+ function registerComponents(...components) {
526
+ use(components);
527
+ }
528
+ var darkTheme = {
529
+ backgroundColor: "#1a1a2e",
530
+ textStyle: { color: "#e0e0e0" },
531
+ title: { textStyle: { color: "#ffffff" } },
532
+ legend: { textStyle: { color: "#cccccc" } },
533
+ categoryAxis: {
534
+ axisLine: { lineStyle: { color: "#444" } },
535
+ splitLine: { lineStyle: { color: "#333" } },
536
+ axisLabel: { color: "#aaa" }
537
+ },
538
+ valueAxis: {
539
+ axisLine: { lineStyle: { color: "#444" } },
540
+ splitLine: { lineStyle: { color: "#333" } },
541
+ axisLabel: { color: "#aaa" }
542
+ },
543
+ color: [
544
+ "#5470c6",
545
+ "#91cc75",
546
+ "#fac858",
547
+ "#ee6666",
548
+ "#73c0de",
549
+ "#3ba272",
550
+ "#fc8452",
551
+ "#9a60b4",
552
+ "#ea7ccc"
553
+ ]
554
+ };
555
+ var vintageTheme = {
556
+ color: [
557
+ "#d87c7c",
558
+ "#919e8b",
559
+ "#d7ab82",
560
+ "#6e7074",
561
+ "#61a0a8",
562
+ "#efa18d",
563
+ "#787464",
564
+ "#cc7e63",
565
+ "#724e58",
566
+ "#4b565b"
567
+ ],
568
+ backgroundColor: "#fef8ef",
569
+ textStyle: {},
570
+ title: { textStyle: { color: "#333333" } },
571
+ categoryAxis: {
572
+ axisLine: { lineStyle: { color: "#ccc" } },
573
+ splitLine: { lineStyle: { color: "#eee" } }
574
+ },
575
+ valueAxis: {
576
+ axisLine: { lineStyle: { color: "#ccc" } },
577
+ splitLine: { lineStyle: { color: "#eee" } }
578
+ }
579
+ };
580
+ var pastelTheme = {
581
+ color: [
582
+ "#c4b5fd",
583
+ "#a5f3fc",
584
+ "#fca5a5",
585
+ "#fde68a",
586
+ "#a7f3d0",
587
+ "#fbcfe8",
588
+ "#c7d2fe",
589
+ "#fed7aa"
590
+ ],
591
+ backgroundColor: "#fafafa",
592
+ textStyle: { color: "#555" },
593
+ title: { textStyle: { color: "#333" } }
594
+ };
595
+ function registerTheme(name, theme) {
596
+ registerTheme$1(name, theme);
597
+ }
598
+ function registerBuiltinThemes() {
599
+ registerTheme("dark-preset", darkTheme);
600
+ registerTheme("vintage", vintageTheme);
601
+ registerTheme("pastel", pastelTheme);
602
+ }
603
+
604
+ export { EChart, EChart3D, EChartGraphic, darkTheme, pastelTheme, registerAll, registerBuiltinThemes, registerCharts, registerComponents, registerTheme, useECharts, useResizeObserver, vintageTheme };
605
+ //# sourceMappingURL=index.js.map
606
+ //# sourceMappingURL=index.js.map