0
# Main Component
1
2
The core Vue component that renders ECharts instances with reactive props, comprehensive event handling, and automatic lifecycle management.
3
4
## Capabilities
5
6
### VChart Component
7
8
The main Vue component for rendering ECharts. Provides reactive chart updates, event handling, and full access to ECharts API methods.
9
10
```typescript { .api }
11
/**
12
* Vue component for rendering ECharts with reactive props
13
* Automatically manages chart lifecycle and provides method access
14
*/
15
declare const VChart: DefineComponent<
16
ChartProps & ChartEventProps,
17
{
18
root: Ref<HTMLElement | undefined>;
19
chart: Ref<EChartsType | undefined>;
20
},
21
{},
22
{},
23
ChartMethods
24
>;
25
26
interface ChartProps {
27
/** ECharts option configuration object */
28
option?: Option;
29
/** Chart theme (object or string name like 'dark') */
30
theme?: Theme;
31
/** ECharts initialization options */
32
initOptions?: InitOptions;
33
/** Chart update options */
34
updateOptions?: UpdateOptions;
35
/** Auto-resize configuration */
36
autoresize?: AutoResize;
37
/** Loading state */
38
loading?: boolean;
39
/** Loading animation options */
40
loadingOptions?: LoadingOptions;
41
/** Chart group name for linking charts */
42
group?: string;
43
/** Manual update mode - prevents automatic option watching */
44
manualUpdate?: boolean;
45
}
46
```
47
48
**Usage Examples:**
49
50
```vue
51
<template>
52
<v-chart
53
:option="chartOption"
54
:theme="chartTheme"
55
:autoresize="true"
56
:loading="isLoading"
57
@click="handleClick"
58
class="chart"
59
/>
60
</template>
61
62
<script setup>
63
import VChart from "vue-echarts";
64
import { ref } from "vue";
65
66
const chartOption = ref({
67
xAxis: { type: "category", data: ["A", "B", "C"] },
68
yAxis: { type: "value" },
69
series: [{ data: [120, 200, 150], type: "bar" }]
70
});
71
72
const chartTheme = ref("dark");
73
const isLoading = ref(false);
74
75
function handleClick(params) {
76
console.log("Chart clicked:", params);
77
}
78
</script>
79
```
80
81
### Component Events
82
83
Vue-ECharts supports all ECharts events through Vue event props. Event names are converted to Vue's `on*` format.
84
85
```typescript { .api }
86
type ChartEventProps = {
87
[key in keyof Emits as key extends string
88
? `on${Capitalize<key>}`
89
: never]?: Emits[key];
90
};
91
92
interface Emits {
93
// Mouse events
94
click: (params: ECElementEvent) => void;
95
dblclick: (params: ECElementEvent) => void;
96
mousedown: (params: ECElementEvent) => void;
97
mousemove: (params: ECElementEvent) => void;
98
mouseup: (params: ECElementEvent) => void;
99
mouseover: (params: ECElementEvent) => void;
100
mouseout: (params: ECElementEvent) => void;
101
contextmenu: (params: ECElementEvent) => void;
102
globalout: (params: ECElementEvent) => void;
103
104
// ZRender events (with zr: prefix)
105
"zr:click": (params: ElementEvent) => void;
106
"zr:mousewheel": (params: ElementEvent) => void;
107
"zr:drag": (params: ElementEvent) => void;
108
"zr:dragstart": (params: ElementEvent) => void;
109
"zr:dragend": (params: ElementEvent) => void;
110
"zr:dragenter": (params: ElementEvent) => void;
111
"zr:dragleave": (params: ElementEvent) => void;
112
"zr:dragover": (params: ElementEvent) => void;
113
"zr:drop": (params: ElementEvent) => void;
114
"zr:mousedown": (params: ElementEvent) => void;
115
"zr:mouseup": (params: ElementEvent) => void;
116
"zr:dblclick": (params: ElementEvent) => void;
117
"zr:contextmenu": (params: ElementEvent) => void;
118
119
// Chart-specific events
120
highlight: (params: any) => void;
121
downplay: (params: any) => void;
122
selectchanged: (params: any) => void;
123
legendselectchanged: (params: any) => void;
124
legendselected: (params: any) => void;
125
legendunselected: (params: any) => void;
126
legendselectall: (params: any) => void;
127
legendinverseselect: (params: any) => void;
128
legendscroll: (params: any) => void;
129
datazoom: (params: any) => void;
130
datarangeselected: (params: any) => void;
131
graphroam: (params: any) => void;
132
georoam: (params: any) => void;
133
treeroam: (params: any) => void;
134
timelinechanged: (params: any) => void;
135
timelineplaychanged: (params: any) => void;
136
restore: (params: any) => void;
137
dataviewchanged: (params: any) => void;
138
magictypechanged: (params: any) => void;
139
geoselectchanged: (params: any) => void;
140
geoselected: (params: any) => void;
141
geounselected: (params: any) => void;
142
axisareaselected: (params: any) => void;
143
brush: (params: any) => void;
144
brushEnd: (params: any) => void;
145
brushselected: (params: any) => void;
146
globalcursortaken: (params: any) => void;
147
148
// Lifecycle events
149
rendered: (params: { elapsedTime: number }) => void;
150
finished: () => void;
151
}
152
```
153
154
**Usage Examples:**
155
156
```vue
157
<template>
158
<v-chart
159
@click="handleClick"
160
@legend-select-changed="handleLegendChange"
161
@zr:click="handleZrClick"
162
@rendered="handleRendered"
163
/>
164
</template>
165
166
<script setup>
167
function handleClick(params) {
168
console.log("Data item clicked:", params.data);
169
}
170
171
function handleLegendChange(params) {
172
console.log("Legend selection changed:", params.selected);
173
}
174
175
function handleZrClick(params) {
176
console.log("Canvas clicked:", params);
177
}
178
179
function handleRendered(params) {
180
console.log("Chart rendered in:", params.elapsedTime, "ms");
181
}
182
</script>
183
```
184
185
### Component Methods
186
187
All ECharts instance methods are exposed through the component for programmatic control.
188
189
```typescript { .api }
190
interface ChartMethods {
191
/** Get chart width in pixels */
192
getWidth(): number;
193
/** Get chart height in pixels */
194
getHeight(): number;
195
/** Get chart DOM element */
196
getDom(): HTMLElement;
197
/** Get current chart option */
198
getOption(): Option;
199
/** Resize chart to fit container */
200
resize(): void;
201
/** Dispatch action to chart */
202
dispatchAction(payload: any): void;
203
/** Convert logical coordinate to pixel coordinate */
204
convertToPixel(finder: any, value: any): number[] | number;
205
/** Convert pixel coordinate to logical coordinate */
206
convertFromPixel(finder: any, value: any): number[] | number;
207
/** Check if pixel coordinate is in specified area */
208
containPixel(finder: any, value: number[]): boolean;
209
/** Get chart as data URL */
210
getDataURL(opts?: { type?: string; pixelRatio?: number; backgroundColor?: string; excludeComponents?: string[] }): string;
211
/** Get connected charts as data URL */
212
getConnectedDataURL(opts?: { type?: string; pixelRatio?: number; backgroundColor?: string; excludeComponents?: string[] }): string;
213
/** Append data to series */
214
appendData(opts: { seriesIndex: number; data: any[] }): void;
215
/** Clear chart */
216
clear(): void;
217
/** Check if chart is disposed */
218
isDisposed(): boolean;
219
/** Dispose chart instance */
220
dispose(): void;
221
/** Set chart option */
222
setOption(option: Option, updateOptions?: UpdateOptions): void;
223
/** Show loading animation */
224
showLoading(opts?: LoadingOptions): void;
225
/** Hide loading animation */
226
hideLoading(): void;
227
}
228
```
229
230
**Usage Examples:**
231
232
```vue
233
<template>
234
<v-chart ref="chartRef" :option="option" />
235
<button @click="exportChart">Export PNG</button>
236
<button @click="refreshChart">Refresh</button>
237
</template>
238
239
<script setup>
240
import { ref } from "vue";
241
242
const chartRef = ref();
243
244
function exportChart() {
245
const dataURL = chartRef.value.getDataURL({
246
type: "png",
247
pixelRatio: 2,
248
backgroundColor: "#fff"
249
});
250
// Use dataURL for download or display
251
}
252
253
function refreshChart() {
254
chartRef.value.clear();
255
chartRef.value.setOption(newOption, { notMerge: true });
256
}
257
</script>
258
```
259
260
### Native DOM Events
261
262
For native DOM events on the chart container, use the `native:` prefix:
263
264
```vue
265
<template>
266
<v-chart
267
@native:click="handleNativeClick"
268
@native:focus="handleFocus"
269
@native:blur="handleBlur"
270
/>
271
</template>
272
273
<script setup>
274
function handleNativeClick(event) {
275
console.log("Native DOM click:", event.target);
276
}
277
278
function handleFocus(event) {
279
console.log("Chart container focused");
280
}
281
282
function handleBlur(event) {
283
console.log("Chart container blurred");
284
}
285
</script>
286
```
287
288
### Manual Update Mode
289
290
When `manualUpdate` is true, the chart won't automatically react to option changes. Use `setOption` method for manual updates.
291
292
```vue
293
<template>
294
<v-chart
295
ref="chart"
296
:option="option"
297
:manual-update="true"
298
/>
299
<button @click="updateChart">Update Chart</button>
300
</template>
301
302
<script setup>
303
import { ref } from "vue";
304
305
const chart = ref();
306
const option = ref({ /* initial option */ });
307
308
function updateChart() {
309
const newOption = { /* updated option */ };
310
chart.value.setOption(newOption, { notMerge: true });
311
}
312
</script>
313
```
314
315
### Group Linking
316
317
Charts can be linked by setting the same group name, enabling coordinated interactions.
318
319
```vue
320
<template>
321
<v-chart :option="chart1Option" group="dashboard" />
322
<v-chart :option="chart2Option" group="dashboard" />
323
</template>
324
325
<script setup>
326
// Both charts will be linked for brush selection, data zoom, etc.
327
const chart1Option = ref({ /* ... */ });
328
const chart2Option = ref({ /* ... */ });
329
</script>
330
```
331
332
### Loading State Management
333
334
Advanced loading state patterns:
335
336
```vue
337
<template>
338
<div class="chart-container">
339
<v-chart
340
ref="chartRef"
341
:option="chartOption"
342
:loading="isLoading"
343
:loading-options="loadingConfig"
344
@rendered="onChartRendered"
345
/>
346
<div v-if="error" class="error-message">
347
{{ error }}
348
</div>
349
</div>
350
</template>
351
352
<script setup>
353
import { ref } from "vue";
354
import VChart from "vue-echarts";
355
356
const chartRef = ref();
357
const chartOption = ref(null);
358
const isLoading = ref(true);
359
const error = ref(null);
360
361
const loadingConfig = {
362
text: "Loading chart data...",
363
color: "#409eff",
364
textColor: "#000",
365
maskColor: "rgba(255, 255, 255, 0.8)",
366
showSpinner: true,
367
spinnerRadius: 10
368
};
369
370
// Simulate data loading
371
async function loadChartData() {
372
try {
373
isLoading.value = true;
374
error.value = null;
375
376
const response = await fetch("/api/chart-data");
377
const data = await response.json();
378
379
chartOption.value = {
380
xAxis: { type: "category", data: data.categories },
381
yAxis: { type: "value" },
382
series: [{ type: "bar", data: data.values }]
383
};
384
} catch (err) {
385
error.value = "Failed to load chart data";
386
console.error(err);
387
} finally {
388
isLoading.value = false;
389
}
390
}
391
392
function onChartRendered() {
393
console.log("Chart rendered successfully");
394
}
395
396
// Load data on mount
397
loadChartData();
398
</script>
399
```
400
401
### Dynamic Chart Updates
402
403
Handling complex chart updates with animation:
404
405
```vue
406
<template>
407
<div>
408
<v-chart
409
ref="chart"
410
:option="chartOption"
411
:update-options="updateConfig"
412
/>
413
<button @click="addDataPoint">Add Data</button>
414
<button @click="changeChartType">Toggle Type</button>
415
</div>
416
</template>
417
418
<script setup>
419
import { ref } from "vue";
420
421
const chart = ref();
422
const chartType = ref("bar");
423
424
const updateConfig = {
425
notMerge: false,
426
lazyUpdate: false,
427
silent: false
428
};
429
430
const chartOption = ref({
431
animation: true,
432
animationDuration: 1000,
433
xAxis: {
434
type: "category",
435
data: ["Jan", "Feb", "Mar", "Apr", "May"]
436
},
437
yAxis: { type: "value" },
438
series: [{
439
type: chartType.value,
440
data: [120, 200, 150, 80, 70],
441
animationDelay: (idx) => idx * 100
442
}]
443
});
444
445
function addDataPoint() {
446
const currentData = chartOption.value.series[0].data;
447
const months = chartOption.value.xAxis.data;
448
449
// Add new month and random data
450
const newMonth = `Month ${months.length + 1}`;
451
const newValue = Math.floor(Math.random() * 300) + 50;
452
453
chartOption.value = {
454
...chartOption.value,
455
xAxis: {
456
...chartOption.value.xAxis,
457
data: [...months, newMonth]
458
},
459
series: [{
460
...chartOption.value.series[0],
461
data: [...currentData, newValue]
462
}]
463
};
464
}
465
466
function changeChartType() {
467
chartType.value = chartType.value === "bar" ? "line" : "bar";
468
469
chartOption.value = {
470
...chartOption.value,
471
series: [{
472
...chartOption.value.series[0],
473
type: chartType.value
474
}]
475
};
476
}
477
</script>
478
```