react-use-echarts 0.0.10 → 1.0.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/README.md +548 -26
- package/dist/__tests__/hooks/theme-change.test.d.ts +1 -0
- package/dist/__tests__/hooks/use-echarts.test.d.ts +1 -0
- package/dist/__tests__/hooks/use-lazy-init.test.d.ts +1 -0
- package/dist/__tests__/themes/index.test.d.ts +1 -0
- package/dist/__tests__/utils/connect.test.d.ts +1 -0
- package/dist/__tests__/utils/instance-cache.test.d.ts +1 -0
- package/dist/hooks/use-echarts.d.ts +10 -0
- package/dist/hooks/use-lazy-init.d.ts +8 -0
- package/dist/index.d.ts +32 -131
- package/dist/index.es.js +1096 -80
- package/dist/index.umd.js +5 -1
- package/dist/themes/index.d.ts +42 -0
- package/dist/themes/presets/dark.json.d.ts +398 -0
- package/dist/themes/presets/light.json.d.ts +398 -0
- package/dist/themes/presets/macarons.json.d.ts +419 -0
- package/dist/types/index.d.ts +118 -0
- package/dist/utils/connect.d.ts +49 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/instance-cache.d.ts +42 -0
- package/package.json +29 -24
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://github.com/chensid/react-use-echarts/pulls)
|
|
8
8
|
[](https://github.com/chensid/react-use-echarts/blob/main/LICENSE.txt)
|
|
9
9
|
|
|
10
|
-
A
|
|
10
|
+
A React hooks library for Apache ECharts with full TypeScript support. Simple, lightweight, and gets out of your way.
|
|
11
11
|
|
|
12
12
|
## ✨ Features
|
|
13
13
|
|
|
@@ -16,7 +16,18 @@ A powerful React hooks library for Apache ECharts, making it easy to use ECharts
|
|
|
16
16
|
- 📦 **Lightweight** - Zero dependencies except for React and ECharts
|
|
17
17
|
- 🛠 **Flexible** - Full access to ECharts instance and options
|
|
18
18
|
- ⚡ **Auto-updating** - Automatically updates chart when data or options change
|
|
19
|
-
- 📱 **Responsive** - Handles container resizing automatically
|
|
19
|
+
- 📱 **Responsive** - Handles container resizing automatically with ResizeObserver
|
|
20
|
+
- 🎯 **Event handling** - Easy to use event system with flexible configuration
|
|
21
|
+
- 🎭 **Built-in themes** - Includes light, dark, and macarons themes out of the box
|
|
22
|
+
- 🔗 **Chart linkage** - Connect multiple charts for synchronized interactions
|
|
23
|
+
- 🦥 **Lazy initialization** - Only initialize charts when they enter the viewport
|
|
24
|
+
|
|
25
|
+
## 📋 Requirements
|
|
26
|
+
|
|
27
|
+
- React 19.x
|
|
28
|
+
- ECharts 6.x
|
|
29
|
+
|
|
30
|
+
> **Note**: This library is designed for client-side rendering (CSR) only. Server-side rendering (SSR) is not supported as ECharts requires DOM access.
|
|
20
31
|
|
|
21
32
|
## 📦 Installation
|
|
22
33
|
|
|
@@ -34,10 +45,17 @@ pnpm add react-use-echarts echarts
|
|
|
34
45
|
## 🔨 Usage
|
|
35
46
|
|
|
36
47
|
```tsx
|
|
37
|
-
import {
|
|
48
|
+
import { useRef } from 'react';
|
|
49
|
+
import { useEcharts } from 'react-use-echarts';
|
|
50
|
+
import type { EChartsOption } from 'echarts';
|
|
38
51
|
|
|
39
52
|
function MyChart() {
|
|
40
|
-
const
|
|
53
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
54
|
+
|
|
55
|
+
const options: EChartsOption = {
|
|
56
|
+
title: {
|
|
57
|
+
text: 'Basic Line Chart Example'
|
|
58
|
+
},
|
|
41
59
|
xAxis: {
|
|
42
60
|
type: 'category',
|
|
43
61
|
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
|
@@ -47,15 +65,356 @@ function MyChart() {
|
|
|
47
65
|
},
|
|
48
66
|
series: [{
|
|
49
67
|
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
|
50
|
-
type: 'line'
|
|
68
|
+
type: 'line',
|
|
69
|
+
smooth: true
|
|
51
70
|
}]
|
|
52
71
|
};
|
|
53
72
|
|
|
54
|
-
|
|
73
|
+
useEcharts(chartRef, {
|
|
55
74
|
option: options
|
|
56
75
|
});
|
|
57
76
|
|
|
58
|
-
return <div ref={chartRef} style={{ width: '100%', height: '
|
|
77
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 🚀 Advanced Usage
|
|
82
|
+
|
|
83
|
+
### Event Handling
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { useRef } from 'react';
|
|
87
|
+
import { useEcharts } from 'react-use-echarts';
|
|
88
|
+
import type { EChartsOption } from 'echarts';
|
|
89
|
+
|
|
90
|
+
function InteractiveChart() {
|
|
91
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
92
|
+
|
|
93
|
+
const options: EChartsOption = {
|
|
94
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
95
|
+
yAxis: { type: 'value' },
|
|
96
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
useEcharts(chartRef, {
|
|
100
|
+
option: options,
|
|
101
|
+
onEvents: {
|
|
102
|
+
click: {
|
|
103
|
+
handler: (params) => {
|
|
104
|
+
console.log('Clicked:', params);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
mouseover: {
|
|
108
|
+
handler: (params) => {
|
|
109
|
+
console.log('Hover:', params);
|
|
110
|
+
},
|
|
111
|
+
query: 'series' // Only trigger on series elements
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Loading State
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { useState, useEffect, useRef } from 'react';
|
|
124
|
+
import { useEcharts } from 'react-use-echarts';
|
|
125
|
+
|
|
126
|
+
function ChartWithLoading() {
|
|
127
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
128
|
+
const [loading, setLoading] = useState(true);
|
|
129
|
+
const [data, setData] = useState<number[]>([]);
|
|
130
|
+
|
|
131
|
+
// Simulate data fetching
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
setTimeout(() => {
|
|
134
|
+
setData([820, 932, 901, 934, 1290, 1330, 1320]);
|
|
135
|
+
setLoading(false);
|
|
136
|
+
}, 2000);
|
|
137
|
+
}, []);
|
|
138
|
+
|
|
139
|
+
useEcharts(chartRef, {
|
|
140
|
+
option: {
|
|
141
|
+
xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
|
|
142
|
+
yAxis: { type: 'value' },
|
|
143
|
+
series: [{ data, type: 'line' }]
|
|
144
|
+
},
|
|
145
|
+
showLoading: loading
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Dynamic Updates
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { useState, useRef } from 'react';
|
|
156
|
+
import { useEcharts } from 'react-use-echarts';
|
|
157
|
+
|
|
158
|
+
function DynamicChart() {
|
|
159
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
160
|
+
const [data, setData] = useState([120, 200, 150, 80, 70, 110, 130]);
|
|
161
|
+
|
|
162
|
+
const { setOption } = useEcharts(chartRef, {
|
|
163
|
+
option: {
|
|
164
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C', 'D', 'E', 'F', 'G'] },
|
|
165
|
+
yAxis: { type: 'value' },
|
|
166
|
+
series: [{ data, type: 'bar' }]
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const updateData = () => {
|
|
171
|
+
const newData = data.map(() => Math.floor(Math.random() * 200));
|
|
172
|
+
setData(newData);
|
|
173
|
+
setOption({
|
|
174
|
+
series: [{ data: newData }]
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<div>
|
|
180
|
+
<button onClick={updateData}>Update Data</button>
|
|
181
|
+
<div ref={chartRef} style={{ width: '100%', height: '400px' }} />
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Built-in Themes
|
|
188
|
+
|
|
189
|
+
The library includes three built-in themes: `light`, `dark`, and `macarons`.
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
import { useRef } from 'react';
|
|
193
|
+
import { useEcharts } from 'react-use-echarts';
|
|
194
|
+
|
|
195
|
+
function ThemedChart() {
|
|
196
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
197
|
+
|
|
198
|
+
useEcharts(chartRef, {
|
|
199
|
+
option: {
|
|
200
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
201
|
+
yAxis: { type: 'value' },
|
|
202
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
203
|
+
},
|
|
204
|
+
theme: 'dark' // 'light' | 'dark' | 'macarons'
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Custom Theme
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { useRef } from 'react';
|
|
215
|
+
import { useEcharts } from 'react-use-echarts';
|
|
216
|
+
|
|
217
|
+
function CustomThemedChart() {
|
|
218
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
219
|
+
|
|
220
|
+
const customTheme = {
|
|
221
|
+
color: ['#fc8452', '#9a60b4', '#ea7ccc'],
|
|
222
|
+
backgroundColor: '#1e1e1e'
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
useEcharts(chartRef, {
|
|
226
|
+
option: {
|
|
227
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
228
|
+
yAxis: { type: 'value' },
|
|
229
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
230
|
+
},
|
|
231
|
+
theme: customTheme
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Chart Linkage
|
|
239
|
+
|
|
240
|
+
Connect multiple charts to synchronize their interactions (e.g., tooltip, highlight).
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import { useRef } from 'react';
|
|
244
|
+
import { useEcharts } from 'react-use-echarts';
|
|
245
|
+
|
|
246
|
+
function LinkedCharts() {
|
|
247
|
+
const chartRef1 = useRef<HTMLDivElement>(null);
|
|
248
|
+
const chartRef2 = useRef<HTMLDivElement>(null);
|
|
249
|
+
|
|
250
|
+
const xAxisData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
|
251
|
+
|
|
252
|
+
useEcharts(chartRef1, {
|
|
253
|
+
option: {
|
|
254
|
+
xAxis: { type: 'category', data: xAxisData },
|
|
255
|
+
yAxis: { type: 'value' },
|
|
256
|
+
tooltip: { trigger: 'axis' },
|
|
257
|
+
series: [{ data: [120, 200, 150, 80, 70, 110, 130], type: 'line' }]
|
|
258
|
+
},
|
|
259
|
+
group: 'my-chart-group'
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
useEcharts(chartRef2, {
|
|
263
|
+
option: {
|
|
264
|
+
xAxis: { type: 'category', data: xAxisData },
|
|
265
|
+
yAxis: { type: 'value' },
|
|
266
|
+
tooltip: { trigger: 'axis' },
|
|
267
|
+
series: [{ data: [220, 180, 191, 234, 290, 330, 310], type: 'bar' }]
|
|
268
|
+
},
|
|
269
|
+
group: 'my-chart-group'
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<div>
|
|
274
|
+
<div ref={chartRef1} style={{ width: '100%', height: '300px' }} />
|
|
275
|
+
<div ref={chartRef2} style={{ width: '100%', height: '300px' }} />
|
|
276
|
+
</div>
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Lazy Initialization
|
|
282
|
+
|
|
283
|
+
Only initialize charts when they enter the viewport, great for pages with many charts.
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
import { useRef } from 'react';
|
|
287
|
+
import { useEcharts } from 'react-use-echarts';
|
|
288
|
+
|
|
289
|
+
function LazyChart() {
|
|
290
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
291
|
+
|
|
292
|
+
useEcharts(chartRef, {
|
|
293
|
+
option: {
|
|
294
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
295
|
+
yAxis: { type: 'value' },
|
|
296
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
297
|
+
},
|
|
298
|
+
lazyInit: true // Chart will only initialize when scrolled into view
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// With custom IntersectionObserver options
|
|
305
|
+
function LazyChartWithOptions() {
|
|
306
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
307
|
+
|
|
308
|
+
useEcharts(chartRef, {
|
|
309
|
+
option: {
|
|
310
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
311
|
+
yAxis: { type: 'value' },
|
|
312
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
313
|
+
},
|
|
314
|
+
lazyInit: {
|
|
315
|
+
rootMargin: '100px', // Pre-load when 100px away from viewport
|
|
316
|
+
threshold: 0.1
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### SVG Renderer
|
|
325
|
+
|
|
326
|
+
Use SVG renderer instead of Canvas for better accessibility and print quality.
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
import { useRef } from 'react';
|
|
330
|
+
import { useEcharts } from 'react-use-echarts';
|
|
331
|
+
|
|
332
|
+
function SVGChart() {
|
|
333
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
334
|
+
|
|
335
|
+
useEcharts(chartRef, {
|
|
336
|
+
option: {
|
|
337
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
338
|
+
yAxis: { type: 'value' },
|
|
339
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
340
|
+
},
|
|
341
|
+
renderer: 'svg'
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Accessing ECharts Instance
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
import { useRef } from 'react';
|
|
352
|
+
import { useEcharts } from 'react-use-echarts';
|
|
353
|
+
|
|
354
|
+
function ChartWithInstance() {
|
|
355
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
356
|
+
|
|
357
|
+
const { getInstance } = useEcharts(chartRef, {
|
|
358
|
+
option: {
|
|
359
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
360
|
+
yAxis: { type: 'value' },
|
|
361
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
const exportImage = () => {
|
|
366
|
+
const instance = getInstance();
|
|
367
|
+
if (instance) {
|
|
368
|
+
const url = instance.getDataURL({
|
|
369
|
+
type: 'png',
|
|
370
|
+
pixelRatio: 2,
|
|
371
|
+
backgroundColor: '#fff'
|
|
372
|
+
});
|
|
373
|
+
// Download or use the image URL
|
|
374
|
+
const link = document.createElement('a');
|
|
375
|
+
link.download = 'chart.png';
|
|
376
|
+
link.href = url;
|
|
377
|
+
link.click();
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
return (
|
|
382
|
+
<div>
|
|
383
|
+
<button onClick={exportImage}>Export as Image</button>
|
|
384
|
+
<div ref={chartRef} style={{ width: '100%', height: '400px' }} />
|
|
385
|
+
</div>
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Manual Resize
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
import { useRef } from 'react';
|
|
394
|
+
import { useEcharts } from 'react-use-echarts';
|
|
395
|
+
|
|
396
|
+
function ResizableChart() {
|
|
397
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
398
|
+
|
|
399
|
+
const { resize } = useEcharts(chartRef, {
|
|
400
|
+
option: {
|
|
401
|
+
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
|
|
402
|
+
yAxis: { type: 'value' },
|
|
403
|
+
series: [{ data: [120, 200, 150], type: 'bar' }]
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Manually trigger resize after some container size change
|
|
408
|
+
const handleContainerResize = () => {
|
|
409
|
+
resize();
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
return (
|
|
413
|
+
<div>
|
|
414
|
+
<button onClick={handleContainerResize}>Trigger Resize</button>
|
|
415
|
+
<div ref={chartRef} style={{ width: '100%', height: '400px' }} />
|
|
416
|
+
</div>
|
|
417
|
+
);
|
|
59
418
|
}
|
|
60
419
|
```
|
|
61
420
|
|
|
@@ -65,38 +424,201 @@ function MyChart() {
|
|
|
65
424
|
|
|
66
425
|
The main hook for using ECharts in React components.
|
|
67
426
|
|
|
427
|
+
#### Parameters
|
|
428
|
+
|
|
68
429
|
```tsx
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
430
|
+
import { useRef } from 'react';
|
|
431
|
+
import type { EChartsOption } from 'echarts';
|
|
432
|
+
import type { UseEchartsOptions } from 'react-use-echarts';
|
|
433
|
+
import { useEcharts } from 'react-use-echarts';
|
|
434
|
+
|
|
435
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
436
|
+
|
|
437
|
+
const someEchartsOption: EChartsOption = {
|
|
438
|
+
xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] },
|
|
439
|
+
yAxis: { type: 'value' },
|
|
440
|
+
series: [{ type: 'line', data: [120, 200, 150] }],
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
const options: UseEchartsOptions = {
|
|
444
|
+
option: someEchartsOption, // Required: ECharts options
|
|
445
|
+
theme: 'dark', // Optional: 'light' | 'dark' | 'macarons' | custom object | null
|
|
446
|
+
renderer: 'canvas', // Optional: 'canvas' | 'svg' (default: 'canvas')
|
|
447
|
+
lazyInit: false, // Optional: boolean | IntersectionObserverInit
|
|
448
|
+
group: 'my-group', // Optional: Group ID for chart linkage
|
|
449
|
+
setOptionOpts: { notMerge: false }, // Optional: Default setOption options
|
|
450
|
+
showLoading: false, // Optional: Show loading state
|
|
451
|
+
loadingOption: { text: 'Loading…' }, // Optional: Loading options
|
|
452
|
+
onEvents: {
|
|
453
|
+
click: {
|
|
454
|
+
handler: (params) => {
|
|
455
|
+
console.log(params);
|
|
456
|
+
},
|
|
457
|
+
query: 'series', // Optional: Event query
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
const { setOption, getInstance, resize } = useEcharts(chartRef, options);
|
|
84
463
|
```
|
|
85
464
|
|
|
465
|
+
#### Options
|
|
466
|
+
|
|
467
|
+
| Property | Type | Default | Description |
|
|
468
|
+
|----------|------|---------|-------------|
|
|
469
|
+
| `option` | `EChartsOption` | **required** | ECharts configuration options |
|
|
470
|
+
| `theme` | `'light' \| 'dark' \| 'macarons' \| object \| null` | `null` | Theme name or custom theme object |
|
|
471
|
+
| `renderer` | `'canvas' \| 'svg'` | `'canvas'` | Renderer type |
|
|
472
|
+
| `lazyInit` | `boolean \| IntersectionObserverInit` | `false` | Lazy initialization config |
|
|
473
|
+
| `group` | `string` | - | Group ID for chart linkage |
|
|
474
|
+
| `setOptionOpts` | `SetOptionOpts` | - | Default options for setOption |
|
|
475
|
+
| `showLoading` | `boolean` | `false` | Show loading state |
|
|
476
|
+
| `loadingOption` | `object` | - | Loading configuration |
|
|
477
|
+
| `onEvents` | `EChartsEvents` | - | Event handlers |
|
|
478
|
+
|
|
86
479
|
#### Returns
|
|
87
480
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
481
|
+
```tsx
|
|
482
|
+
{
|
|
483
|
+
setOption: (option: EChartsOption, opts?: SetOptionOpts) => void;
|
|
484
|
+
getInstance: () => ECharts | undefined;
|
|
485
|
+
resize: () => void;
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
- **`setOption`**: Update chart options dynamically
|
|
490
|
+
- **`getInstance`**: Get the ECharts instance (returns `undefined` before initialization)
|
|
491
|
+
- **`resize`**: Manually trigger chart resize
|
|
492
|
+
|
|
493
|
+
### Theme Utilities
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
import {
|
|
497
|
+
registerBuiltinThemes,
|
|
498
|
+
getBuiltinTheme,
|
|
499
|
+
isBuiltinTheme,
|
|
500
|
+
registerCustomTheme,
|
|
501
|
+
getAvailableThemes,
|
|
502
|
+
} from 'react-use-echarts';
|
|
503
|
+
|
|
504
|
+
// Get all available built-in theme names
|
|
505
|
+
const themes = getAvailableThemes(); // ['light', 'dark', 'macarons']
|
|
506
|
+
|
|
507
|
+
// Check if a theme name is built-in
|
|
508
|
+
isBuiltinTheme('dark'); // true
|
|
509
|
+
isBuiltinTheme('custom'); // false
|
|
510
|
+
|
|
511
|
+
// Get built-in theme configuration
|
|
512
|
+
const darkTheme = getBuiltinTheme('dark');
|
|
513
|
+
|
|
514
|
+
// Register a custom theme globally
|
|
515
|
+
registerCustomTheme('my-theme', { color: ['#ff0000', '#00ff00'] });
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### useLazyInit
|
|
519
|
+
|
|
520
|
+
A standalone hook for lazy initialization using IntersectionObserver.
|
|
521
|
+
|
|
522
|
+
```tsx
|
|
523
|
+
import { useRef } from 'react';
|
|
524
|
+
import { useLazyInit } from 'react-use-echarts';
|
|
525
|
+
|
|
526
|
+
function MyComponent() {
|
|
527
|
+
const elementRef = useRef<HTMLDivElement>(null);
|
|
528
|
+
|
|
529
|
+
// Returns true when element enters viewport
|
|
530
|
+
const isInView = useLazyInit(elementRef, {
|
|
531
|
+
rootMargin: '50px',
|
|
532
|
+
threshold: 0.1
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
return (
|
|
536
|
+
<div ref={elementRef}>
|
|
537
|
+
{isInView ? <ExpensiveComponent /> : <Placeholder />}
|
|
538
|
+
</div>
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
```
|
|
91
542
|
|
|
92
543
|
## 🤝 Contributing
|
|
93
544
|
|
|
94
545
|
We welcome all contributions. Please read our [contributing guidelines](CONTRIBUTING.md) first. You can submit any ideas as [pull requests](https://github.com/chensid/react-use-echarts/pulls) or as [GitHub issues](https://github.com/chensid/react-use-echarts/issues).
|
|
95
546
|
|
|
547
|
+
## 🔄 Migration Guide
|
|
548
|
+
|
|
549
|
+
### From v0.0.11 to v1.0
|
|
550
|
+
|
|
551
|
+
#### Breaking Change: External Ref Management
|
|
552
|
+
|
|
553
|
+
The `useEcharts` hook no longer returns a `chartRef`. Instead, you now create and manage the ref externally:
|
|
554
|
+
|
|
555
|
+
**Before (v0.0.11):**
|
|
556
|
+
```tsx
|
|
557
|
+
import { useEcharts } from 'react-use-echarts';
|
|
558
|
+
|
|
559
|
+
function MyChart() {
|
|
560
|
+
const { chartRef, setOption, getInstance } = useEcharts({
|
|
561
|
+
option: { /* ... */ }
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**After (v1.0):**
|
|
569
|
+
```tsx
|
|
570
|
+
import { useRef } from 'react';
|
|
571
|
+
import { useEcharts } from 'react-use-echarts';
|
|
572
|
+
|
|
573
|
+
function MyChart() {
|
|
574
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
575
|
+
|
|
576
|
+
const { setOption, getInstance, resize } = useEcharts(chartRef, {
|
|
577
|
+
option: { /* ... */ }
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
#### New Features in v1.0
|
|
585
|
+
|
|
586
|
+
- **Built-in themes**: Use `theme: 'light' | 'dark' | 'macarons'` or pass a custom theme object
|
|
587
|
+
- **Chart linkage**: Connect charts using the `group` option
|
|
588
|
+
- **Lazy initialization**: Use `lazyInit: true` or custom `IntersectionObserverInit` options
|
|
589
|
+
- **SVG renderer**: Use `renderer: 'svg'` for better accessibility and print quality
|
|
590
|
+
- **Manual resize**: New `resize()` function returned from the hook
|
|
591
|
+
|
|
592
|
+
#### Important Notes for Custom Themes
|
|
593
|
+
|
|
594
|
+
When using custom theme objects, **memoize them** to avoid unnecessary chart recreation:
|
|
595
|
+
|
|
596
|
+
```tsx
|
|
597
|
+
import { useRef, useMemo } from 'react';
|
|
598
|
+
import { useEcharts } from 'react-use-echarts';
|
|
599
|
+
|
|
600
|
+
function MyChart() {
|
|
601
|
+
const chartRef = useRef<HTMLDivElement>(null);
|
|
602
|
+
|
|
603
|
+
// ✅ Good: Memoized theme object
|
|
604
|
+
const customTheme = useMemo(() => ({
|
|
605
|
+
color: ['#fc8452', '#9a60b4', '#ea7ccc'],
|
|
606
|
+
backgroundColor: '#1e1e1e'
|
|
607
|
+
}), []);
|
|
608
|
+
|
|
609
|
+
useEcharts(chartRef, {
|
|
610
|
+
option: { /* ... */ },
|
|
611
|
+
theme: customTheme
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
|
|
615
|
+
}
|
|
616
|
+
```
|
|
617
|
+
|
|
96
618
|
## 📝 Changelog
|
|
97
619
|
|
|
98
620
|
Detailed changes for each release are documented in the [release notes](https://github.com/chensid/react-use-echarts/releases).
|
|
99
621
|
|
|
100
622
|
## 📄 License
|
|
101
623
|
|
|
102
|
-
[MIT](./LICENSE.txt) © [
|
|
624
|
+
[MIT](./LICENSE.txt) © [Ethan](https://github.com/chensid)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UseEchartsOptions, UseEchartsReturn } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* React hook for Apache ECharts integration (v1.0)
|
|
4
|
+
* Apache ECharts React Hook (v1.0)
|
|
5
|
+
* @param ref React ref to the chart container element
|
|
6
|
+
* @param options Configuration options
|
|
7
|
+
* @returns Chart control methods
|
|
8
|
+
*/
|
|
9
|
+
declare function useEcharts(ref: React.RefObject<HTMLDivElement | null>, options: UseEchartsOptions): UseEchartsReturn;
|
|
10
|
+
export default useEcharts;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for lazy initialization using IntersectionObserver
|
|
3
|
+
* 使用 IntersectionObserver 的懒加载 Hook
|
|
4
|
+
* @param elementRef Element reference to observe
|
|
5
|
+
* @param options IntersectionObserver options or false to disable lazy init
|
|
6
|
+
* @returns Whether the element is in viewport (or true if lazy init is disabled)
|
|
7
|
+
*/
|
|
8
|
+
export declare function useLazyInit(elementRef: React.RefObject<Element | null>, options?: boolean | IntersectionObserverInit): boolean;
|