ECharts 图表
基于 ECharts 封装的图表组件,支持动态更新、自适应、主题切换等功能。
基础用法
最基础的图表展示用法。
vue
<template>
<NVueEchart :option="chartOption" />
</template>
<script setup>
import { ref } from 'vue'
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
</script>柱状图
vue
<template>
<NVueEchart :option="chartOption" />
</template>
<script setup>
import { ref } from 'vue'
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar',
},
],
})
</script>饼图
vue
<template>
<NVueEchart :option="chartOption" />
</template>
<script setup>
import { ref } from 'vue'
const chartOption = ref({
series: [
{
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' },
],
},
],
})
</script>动态更新
图表会自动监听 option 变化并更新。
vue
<template>
<NVueEchart :option="chartOption" />
<NButton @click="updateData">更新数据</NButton>
</template>
<script setup>
import { ref } from 'vue'
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const updateData = () => {
chartOption.value = {
...chartOption.value,
series: [
{
...chartOption.value.series[0],
data: [280, 190, 210, 180, 250, 170, 300],
},
],
}
}
</script>自适应容器
设置 autoresize 属性使图表自适应容器大小。
vue
<template>
<div style="width: 100%; height: 400px;">
<NVueEchart :option="chartOption" autoresize />
</div>
</template>
<script setup>
import { ref } from 'vue'
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
</script>自定义尺寸
使用 width 和 height 属性来设置图表尺寸。
vue
<template>
<NVueEchart :option="chartOption" width="600px" height="400px" />
</template>
<script setup>
import { ref } from 'vue'
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
</script>加载状态
设置 loading 属性来显示加载状态。
vue
<template>
<NVueEchart :option="chartOption" :loading="loading" />
<NButton @click="toggleLoading">切换加载状态</NButton>
</template>
<script setup>
import { ref } from 'vue')
const loading = ref(true)
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const toggleLoading = () => {
loading.value = !loading.value
}
</script>空数据状态
设置 hasData 属性为 false 来显示空数据状态。
vue
<template>
<NVueEchart :option="chartOption" :hasData="hasData" />
<NButton @click="hasData = !hasData">切换数据状态</NButton>
</template>
<script setup>
import { ref } from 'vue')
const hasData = ref(true)
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
</script>SVG 渲染器
设置 renderer 属性为 'svg' 来使用 SVG 渲染器。
vue
<template>
<NVueEchart :option="chartOption" renderer="svg" />
</template>
<script setup>
import { ref } from 'vue')
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
</script>主题
使用 theme 属性来设置图表主题。
vue
<template>
<NVueEchart :option="chartOption" theme="dark" />
</template>
<script setup>
import { ref } from 'vue')
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
</script>图表联动
使用 group 属性来实现多个图表之间的联动。
vue
<template>
<div style="display: flex; gap: 20px;">
<NVueEchart :option="chartOption1" group="myGroup" style="flex: 1;" />
<NVueEchart :option="chartOption2" group="myGroup" style="flex: 1;" />
</div>
</template>
<script setup>
import { ref } from 'vue')
const chartOption1 = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const chartOption2 = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [280, 190, 210, 180, 250, 170, 300],
type: 'bar',
},
],
})
</script>不合并配置
设置 notMerge 属性为 true 来完全替换配置。
vue
<template>
<NVueEchart :option="chartOption" :notMerge="true" />
<NButton @click="switchChart">切换图表类型</NButton>
</template>
<script setup>
import { ref } from 'vue')
const isLine = ref(true)
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const switchChart = () => {
isLine.value = !isLine.value
chartOption.value = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: isLine.value ? 'line' : 'bar',
},
],
}
}
</script>事件监听
组件支持 ready、resize、click 等事件。
vue
<template>
<NVueEchart
:option="chartOption"
@ready="handleReady"
@resize="handleResize"
@click="handleClick"
/>
</template>
<script setup>
import { ref } from 'vue')
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const handleReady = (instance) => {
console.log('图表已准备好:', instance)
}
const handleResize = (size) => {
console.log('图表尺寸变化:', size)
}
const handleClick = (params) => {
console.log('图表点击:', params)
}
</script>获取图表实例
通过 ref 获取组件实例,调用 getInstance 方法获取 ECharts 实例。
vue
<template>
<NVueEchart ref="chartRef" :option="chartOption" />
<NButton @click="exportImage">导出图片</NButton>
</template>
<script setup>
import { ref } from 'vue')
const chartRef = ref(null)
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const exportImage = () => {
const instance = chartRef.value.getInstance()
if (instance) {
const url = instance.getDataURL({
type: 'png',
pixelRatio: 2,
backgroundColor: '#fff',
})
console.log('图片 URL:', url)
}
}
</script>手动设置配置
通过 ref 获取组件实例,调用 setOption 方法手动设置配置。
vue
<template>
<NVueEchart ref="chartRef" :option="chartOption" />
<NButton @click="updateOption">更新配置</NButton>
</template>
<script setup>
import { ref } from 'vue')
const chartRef = ref(null)
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const updateOption = () => {
chartRef.value.setOption({
series: [
{
data: [280, 190, 210, 180, 250, 170, 300],
},
],
})
}
</script>手动触发 resize
通过 ref 获取组件实例,调用 resize 方法手动触发 resize。
vue
<template>
<NVueEchart ref="chartRef" :option="chartOption" :autoresize="false" />
<NButton @click="handleResize">手动 resize</NButton>
</template>
<script setup>
import { ref } from 'vue')
const chartRef = ref(null)
const chartOption = ref({
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
},
],
})
const handleResize = () => {
chartRef.value.resize()
}
</script>API
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| option | ECharts 配置项 | ECOption | any | — |
| hasData | 是否有数据,用于显示空状态 | boolean | true |
| className | 根节点类名 | string | — |
| theme | 主题名称或主题对象 | string | Record<string, unknown> | — |
| autoresize | 父容器尺寸变化时是否自动触发图表 resize | boolean | true |
| renderer | 渲染器类型 | 'canvas' | 'svg' | 'canvas' |
| width | 图表容器的宽度 | string | '100%' |
| height | 图表容器的高度 | string | '360px' |
| loading | 是否显示加载状态 | boolean | false |
| notMerge | setOption 方法的 notMerge 参数,用于是否合并配置项 | boolean | false |
| lazyUpdate | setOption 方法的 lazyUpdate 参数,用于是否延迟更新 | boolean | true |
| replaceMerge | setOption 方法的 replaceMerge 参数,用于指定完全替换的配置部分 | string | string[] | — |
| group | 图表联动的 group 名称,用于实现多个图表之间的联动 | string | — |
Events
| 事件名 | 说明 | 类型 |
|---|---|---|
| ready | 图表实例创建完成后触发 | (instance: EChartsInstance) => void |
| resize | 图表触发尺寸调整时触发 | (size: { width: number; height: number }) => void |
| click | 图表触发点击事件时触发 | (params: unknown) => void |
方法
| 方法名 | 说明 | 类型 |
|---|---|---|
| getInstance | 获取当前的 ECharts 实例 | () => EChartsInstance | null |
| setOption | 设置图表配置,支持动态更新 | (option: ECOption, opts?: SetOptionOpts) => void |
| resize | 手动触发图表的 resize 方法 | (width?: number, height?: number) => void |