@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.
@@ -0,0 +1,152 @@
1
+ # Registration
2
+
3
+ ECharts uses a modular architecture. You must register chart types and components before using them. This package provides helpers for both quick-start and tree-shaking-optimized approaches.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import {
9
+ registerAll,
10
+ registerCharts,
11
+ registerComponents,
12
+ // Individual charts
13
+ LineChart, BarChart, PieChart, ScatterChart, RadarChart,
14
+ HeatmapChart, GaugeChart, FunnelChart, TreemapChart, SunburstChart,
15
+ SankeyChart, GraphChart, CandlestickChart, BoxplotChart, ParallelChart,
16
+ ThemeRiverChart, MapChart, CustomChart, EffectScatterChart, PictorialBarChart,
17
+ // Components
18
+ GridComponent, TooltipComponent, TitleComponent, LegendComponent,
19
+ DataZoomComponent, ToolboxComponent, VisualMapComponent, GeoComponent,
20
+ CalendarComponent, GraphicComponent, PolarComponent, DatasetComponent,
21
+ // Renderers
22
+ CanvasRenderer, SVGRenderer,
23
+ } from "@particle-academy/fancy-echarts";
24
+ ```
25
+
26
+ ## Quick Start: registerAll
27
+
28
+ Registers all chart types, all components, and both renderers. Convenient but not tree-shakeable.
29
+
30
+ ```tsx
31
+ // Call once at app entry (e.g., main.tsx)
32
+ import { registerAll } from "@particle-academy/fancy-echarts";
33
+ registerAll();
34
+ ```
35
+
36
+ Calling `registerAll()` multiple times is safe -- it no-ops after the first call.
37
+
38
+ ## Selective Registration
39
+
40
+ ### registerCharts
41
+
42
+ Register only the chart types you need.
43
+
44
+ ```tsx
45
+ import {
46
+ registerCharts,
47
+ LineChart,
48
+ BarChart,
49
+ PieChart,
50
+ } from "@particle-academy/fancy-echarts";
51
+
52
+ registerCharts(LineChart, BarChart, PieChart);
53
+ ```
54
+
55
+ ### registerComponents
56
+
57
+ Register only the UI components you need.
58
+
59
+ ```tsx
60
+ import {
61
+ registerComponents,
62
+ GridComponent,
63
+ TooltipComponent,
64
+ TitleComponent,
65
+ LegendComponent,
66
+ } from "@particle-academy/fancy-echarts";
67
+
68
+ registerComponents(GridComponent, TooltipComponent, TitleComponent, LegendComponent);
69
+ ```
70
+
71
+ ### Manual Registration
72
+
73
+ For full control, import and register directly via `echarts/core`:
74
+
75
+ ```tsx
76
+ import { use } from "echarts/core";
77
+ import { LineChart } from "@particle-academy/fancy-echarts";
78
+ import { GridComponent, TooltipComponent } from "@particle-academy/fancy-echarts";
79
+ import { CanvasRenderer } from "@particle-academy/fancy-echarts";
80
+
81
+ use([LineChart, GridComponent, TooltipComponent, CanvasRenderer]);
82
+ ```
83
+
84
+ ## Available Charts
85
+
86
+ | Export | ECharts Type |
87
+ |--------|-------------|
88
+ | `LineChart` | `line` |
89
+ | `BarChart` | `bar` |
90
+ | `PieChart` | `pie` |
91
+ | `ScatterChart` | `scatter` |
92
+ | `RadarChart` | `radar` |
93
+ | `HeatmapChart` | `heatmap` |
94
+ | `GaugeChart` | `gauge` |
95
+ | `FunnelChart` | `funnel` |
96
+ | `TreemapChart` | `treemap` |
97
+ | `SunburstChart` | `sunburst` |
98
+ | `SankeyChart` | `sankey` |
99
+ | `GraphChart` | `graph` |
100
+ | `CandlestickChart` | `candlestick` |
101
+ | `BoxplotChart` | `boxplot` |
102
+ | `ParallelChart` | `parallel` |
103
+ | `ThemeRiverChart` | `themeRiver` |
104
+ | `MapChart` | `map` |
105
+ | `CustomChart` | `custom` |
106
+ | `EffectScatterChart` | `effectScatter` |
107
+ | `PictorialBarChart` | `pictorialBar` |
108
+
109
+ ## Available Components
110
+
111
+ | Export | Purpose |
112
+ |--------|---------|
113
+ | `GridComponent` | Cartesian grid layout |
114
+ | `TooltipComponent` | Hover tooltips |
115
+ | `TitleComponent` | Chart title |
116
+ | `LegendComponent` | Series legend |
117
+ | `DataZoomComponent` | Zoom/pan controls |
118
+ | `ToolboxComponent` | Save, restore, data view tools |
119
+ | `VisualMapComponent` | Color/size mapping |
120
+ | `GeoComponent` | Geographic coordinate system |
121
+ | `CalendarComponent` | Calendar heatmap layout |
122
+ | `GraphicComponent` | Custom graphic elements |
123
+ | `PolarComponent` | Polar coordinate system |
124
+ | `DatasetComponent` | Dataset-driven charts |
125
+
126
+ ## Renderers
127
+
128
+ | Export | Description |
129
+ |--------|-------------|
130
+ | `CanvasRenderer` | Canvas-based rendering (default, better performance) |
131
+ | `SVGRenderer` | SVG-based rendering (better for small charts, CSS styling) |
132
+
133
+ ## Recommended Setup
134
+
135
+ For production apps, register only what you use:
136
+
137
+ ```tsx
138
+ // chart-setup.ts
139
+ import { registerCharts, registerComponents, CanvasRenderer } from "@particle-academy/fancy-echarts";
140
+ import { LineChart, BarChart, PieChart } from "@particle-academy/fancy-echarts";
141
+ import { GridComponent, TooltipComponent, TitleComponent, LegendComponent } from "@particle-academy/fancy-echarts";
142
+ import { use } from "echarts/core";
143
+
144
+ registerCharts(LineChart, BarChart, PieChart);
145
+ registerComponents(GridComponent, TooltipComponent, TitleComponent, LegendComponent);
146
+ use([CanvasRenderer]);
147
+ ```
148
+
149
+ ```tsx
150
+ // main.tsx
151
+ import "./chart-setup";
152
+ ```
package/docs/themes.md ADDED
@@ -0,0 +1,152 @@
1
+ # Themes
2
+
3
+ Built-in theme presets and utilities for registering custom themes with ECharts.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import {
9
+ darkTheme,
10
+ vintageTheme,
11
+ pastelTheme,
12
+ registerTheme,
13
+ registerBuiltinThemes,
14
+ } from "@particle-academy/fancy-echarts";
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ Register all built-in themes at app entry:
20
+
21
+ ```tsx
22
+ import { registerBuiltinThemes } from "@particle-academy/fancy-echarts";
23
+ registerBuiltinThemes();
24
+ ```
25
+
26
+ Then use by name:
27
+
28
+ ```tsx
29
+ <EChart option={myOption} theme="vintage" />
30
+ <EChart option={myOption} theme="pastel" />
31
+ <EChart option={myOption} theme="dark-preset" />
32
+ ```
33
+
34
+ ## Built-in Themes
35
+
36
+ ### darkTheme
37
+
38
+ Registered as `"dark-preset"`. Dark background (`#1a1a2e`) with light text and muted axis lines.
39
+
40
+ | Property | Value |
41
+ |----------|-------|
42
+ | Background | `#1a1a2e` |
43
+ | Text color | `#e0e0e0` |
44
+ | Title color | `#ffffff` |
45
+ | Axis lines | `#444` |
46
+ | Palette | `#5470c6`, `#91cc75`, `#fac858`, `#ee6666`, `#73c0de`, `#3ba272`, `#fc8452`, `#9a60b4`, `#ea7ccc` |
47
+
48
+ ### vintageTheme
49
+
50
+ Registered as `"vintage"`. Warm parchment background (`#fef8ef`) with earthy tones.
51
+
52
+ | Property | Value |
53
+ |----------|-------|
54
+ | Background | `#fef8ef` |
55
+ | Title color | `#333333` |
56
+ | Axis lines | `#ccc` |
57
+ | Palette | `#d87c7c`, `#919e8b`, `#d7ab82`, `#6e7074`, `#61a0a8`, `#efa18d`, `#787464`, `#cc7e63`, `#724e58`, `#4b565b` |
58
+
59
+ ### pastelTheme
60
+
61
+ Registered as `"pastel"`. Light background (`#fafafa`) with soft pastel colors.
62
+
63
+ | Property | Value |
64
+ |----------|-------|
65
+ | Background | `#fafafa` |
66
+ | Text color | `#555` |
67
+ | Title color | `#333` |
68
+ | Palette | `#c4b5fd`, `#a5f3fc`, `#fca5a5`, `#fde68a`, `#a7f3d0`, `#fbcfe8`, `#c7d2fe`, `#fed7aa` |
69
+
70
+ ## API
71
+
72
+ ### registerTheme
73
+
74
+ Register a custom theme by name. Wraps `echarts.registerTheme()`.
75
+
76
+ ```ts
77
+ function registerTheme(name: string, theme: object): void
78
+ ```
79
+
80
+ ```tsx
81
+ registerTheme("corporate", {
82
+ color: ["#003f5c", "#58508d", "#bc5090", "#ff6361", "#ffa600"],
83
+ backgroundColor: "#ffffff",
84
+ textStyle: { color: "#333" },
85
+ title: { textStyle: { color: "#003f5c" } },
86
+ });
87
+ ```
88
+
89
+ ### registerBuiltinThemes
90
+
91
+ Registers all three built-in themes (`"dark-preset"`, `"vintage"`, `"pastel"`). Call once at app startup.
92
+
93
+ ```ts
94
+ function registerBuiltinThemes(): void
95
+ ```
96
+
97
+ ## Using Themes
98
+
99
+ ### By registered name
100
+
101
+ ```tsx
102
+ <EChart option={option} theme="vintage" />
103
+ ```
104
+
105
+ ### By object (inline, no registration needed)
106
+
107
+ ```tsx
108
+ <EChart option={option} theme={darkTheme} />
109
+ <EChart option={option} theme={{ color: ["#e63946", "#457b9d", "#1d3557"] }} />
110
+ ```
111
+
112
+ ### Auto Dark Mode
113
+
114
+ When `theme` is omitted, `useECharts` auto-detects the system `prefers-color-scheme: dark` preference and applies ECharts' built-in `"dark"` theme (not `darkTheme` from this package). The background is set to `transparent` so the chart inherits the page background.
115
+
116
+ ```tsx
117
+ {/* Automatically switches between light and dark based on OS setting */}
118
+ <EChart option={option} />
119
+ ```
120
+
121
+ To opt out, pass any explicit theme (including `undefined` as a string or object):
122
+
123
+ ```tsx
124
+ <EChart option={option} theme="" />
125
+ ```
126
+
127
+ ## Custom Theme Example
128
+
129
+ ```tsx
130
+ import { registerTheme } from "@particle-academy/fancy-echarts";
131
+
132
+ const neonTheme = {
133
+ backgroundColor: "#0a0a0a",
134
+ textStyle: { color: "#00ff88" },
135
+ title: { textStyle: { color: "#00ff88" } },
136
+ color: ["#00ff88", "#ff0080", "#00ccff", "#ffcc00", "#ff4400"],
137
+ categoryAxis: {
138
+ axisLine: { lineStyle: { color: "#333" } },
139
+ axisLabel: { color: "#888" },
140
+ },
141
+ valueAxis: {
142
+ axisLine: { lineStyle: { color: "#333" } },
143
+ splitLine: { lineStyle: { color: "#222" } },
144
+ axisLabel: { color: "#888" },
145
+ },
146
+ };
147
+
148
+ registerTheme("neon", neonTheme);
149
+
150
+ // Then use it
151
+ <EChart option={option} theme="neon" />
152
+ ```
@@ -0,0 +1,129 @@
1
+ # useECharts
2
+
3
+ Low-level hook that initializes an ECharts instance on a div ref, manages option updates, event binding, loading state, and auto-resize. Used internally by `EChart`, `EChart3D`, and `EChartGraphic`.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { useECharts } from "@particle-academy/fancy-echarts";
9
+ import type { UseEChartsOptions, UseEChartsReturn } from "@particle-academy/fancy-echarts";
10
+ ```
11
+
12
+ ## Signature
13
+
14
+ ```ts
15
+ function useECharts(options: UseEChartsOptions): UseEChartsReturn
16
+ ```
17
+
18
+ ## Options
19
+
20
+ | Option | Type | Default | Description |
21
+ |--------|------|---------|-------------|
22
+ | `option` | `EChartsOption` | **required** | ECharts option object |
23
+ | `theme` | `string \| object` | `undefined` | Theme name or object. When omitted, auto-detects dark mode |
24
+ | `renderer` | `"canvas" \| "svg"` | `"canvas"` | Rendering engine |
25
+ | `notMerge` | `boolean` | `false` | Replace option instead of merging |
26
+ | `lazyUpdate` | `boolean` | `false` | Delay chart update |
27
+ | `showLoading` | `boolean` | `false` | Show loading animation |
28
+ | `loadingOption` | `object` | `undefined` | Customize loading spinner |
29
+ | `onEvents` | `Record<string, (params) => void>` | `undefined` | Event handlers keyed by event name |
30
+ | `autoResize` | `boolean` | `true` | Auto-resize via `ResizeObserver` |
31
+
32
+ ## Return Value
33
+
34
+ | Property | Type | Description |
35
+ |----------|------|-------------|
36
+ | `chartRef` | `RefObject<HTMLDivElement \| null>` | Ref to attach to a container div |
37
+ | `instance` | `ECharts \| null` | The ECharts instance (null before init) |
38
+
39
+ ## Behavior
40
+
41
+ - **Dark mode auto-detection:** When `theme` is omitted, the hook listens to `prefers-color-scheme: dark` and applies ECharts' built-in `"dark"` theme reactively. In auto-dark mode, `backgroundColor` is set to `"transparent"` so the chart blends with the page background.
42
+ - **Re-initialization:** The chart instance is disposed and re-created when `theme` or `renderer` changes.
43
+ - **StrictMode safe:** Handles React 18 StrictMode double-mount by disposing any existing instance on the same DOM element.
44
+ - **Event cleanup:** Event listeners are bound/unbound cleanly via `useEffect` cleanup.
45
+ - **Resize:** Uses `useResizeObserver` internally to call `chart.resize()` on container size changes.
46
+
47
+ ## Basic Usage
48
+
49
+ ```tsx
50
+ function MyChart({ data }) {
51
+ const option = useMemo(() => ({
52
+ xAxis: { type: "category", data: ["A", "B", "C"] },
53
+ yAxis: { type: "value" },
54
+ series: [{ type: "bar", data }],
55
+ }), [data]);
56
+
57
+ const { chartRef } = useECharts({ option });
58
+
59
+ return <div ref={chartRef} style={{ width: "100%", height: 400 }} />;
60
+ }
61
+ ```
62
+
63
+ ## Accessing the Instance
64
+
65
+ ```tsx
66
+ function ExportableChart() {
67
+ const { chartRef, instance } = useECharts({
68
+ option: { /* ... */ },
69
+ });
70
+
71
+ const handleExport = () => {
72
+ if (instance) {
73
+ const dataUrl = instance.getDataURL({ type: "png" });
74
+ // download or display dataUrl
75
+ }
76
+ };
77
+
78
+ return (
79
+ <div>
80
+ <div ref={chartRef} style={{ width: "100%", height: 400 }} />
81
+ <button onClick={handleExport}>Export PNG</button>
82
+ </div>
83
+ );
84
+ }
85
+ ```
86
+
87
+ ## Event Handling
88
+
89
+ ```tsx
90
+ const { chartRef } = useECharts({
91
+ option: myOption,
92
+ onEvents: {
93
+ click: (params) => console.log("Clicked:", params.name),
94
+ mouseover: (params) => console.log("Hover:", params.data),
95
+ legendselectchanged: (params) => console.log("Legend:", params.selected),
96
+ },
97
+ });
98
+ ```
99
+
100
+ ## Custom Theme
101
+
102
+ ```tsx
103
+ const { chartRef } = useECharts({
104
+ option: myOption,
105
+ theme: "vintage", // registered theme name
106
+ renderer: "svg", // SVG instead of canvas
107
+ autoResize: false, // manual resize control
108
+ });
109
+ ```
110
+
111
+ ## useResizeObserver
112
+
113
+ A utility hook used internally. Calls a callback whenever the referenced element's size changes.
114
+
115
+ ```ts
116
+ import { useResizeObserver } from "@particle-academy/fancy-echarts";
117
+
118
+ function useResizeObserver(
119
+ ref: RefObject<HTMLElement | null>,
120
+ callback: () => void
121
+ ): void
122
+ ```
123
+
124
+ ```tsx
125
+ const divRef = useRef<HTMLDivElement>(null);
126
+ useResizeObserver(divRef, () => {
127
+ console.log("Container resized");
128
+ });
129
+ ```
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@particle-academy/fancy-echarts",
3
+ "version": "1.2.0",
4
+ "description": "React component library wrapping Apache ECharts with typed components for every chart type",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Particle-Academy/fancy-echarts.git"
8
+ },
9
+ "homepage": "https://github.com/Particle-Academy/fancy-echarts#readme",
10
+ "bugs": "https://github.com/Particle-Academy/fancy-echarts/issues",
11
+ "type": "module",
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "import": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "require": {
22
+ "types": "./dist/index.d.cts",
23
+ "default": "./dist/index.cjs"
24
+ }
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "docs",
30
+ "README.md"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsup",
34
+ "dev": "tsup --watch",
35
+ "lint": "tsc --noEmit",
36
+ "clean": "rm -rf dist",
37
+ "prepublishOnly": "tsup"
38
+ },
39
+ "keywords": [
40
+ "react",
41
+ "echarts",
42
+ "charts",
43
+ "visualization",
44
+ "components"
45
+ ],
46
+ "peerDependencies": {
47
+ "react": "^18.0.0 || ^19.0.0",
48
+ "react-dom": "^18.0.0 || ^19.0.0"
49
+ },
50
+ "dependencies": {
51
+ "echarts": "^5.6.0",
52
+ "echarts-gl": "^2.0.9"
53
+ },
54
+ "devDependencies": {
55
+ "@types/react": "^19.0.0",
56
+ "@types/react-dom": "^19.0.0",
57
+ "react": "^19.0.0",
58
+ "react-dom": "^19.0.0",
59
+ "tsup": "^8.5.0",
60
+ "typescript": "^5.8.0"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public"
64
+ },
65
+ "license": "MIT"
66
+ }