效果如图:
思路
- 随机生成数据,渲染3条带markArea的折线,legend设为全选
- 标签显隐通过
markArea.label.show控制,标域显隐通过markArea.itemStyle.opacity控制 - 点击图例隐藏Line2,再点击隐藏标域按钮,发现markArea隐藏的同时Line2显示,因为option不是响应式的,
legend.selected会一直保持图表实例化时的值,需要通过监听legendselectchanged事件手动更新
代码
Vue函数、生命周期钩子等已通过unplugin-auto-import自动导入
<template>
<div class="container">
<button class="btn" @click="toggleMarkarea(markareaVisible)">
{{ markareaVisible ? '隐藏' : '显示' }}标域
</button>
<div ref="chartRef" style="height: 100%"></div>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
const chartRef = shallowRef()
let chart
const option = {
grid: { left: '1%', right: '1%', bottom: '1%', containLabel: true },
legend: {
selected: {}
},
xAxis: {
type: 'category',
data: []
},
yAxis: { type: 'value' },
series: [],
animation: false
}
const markareaVisible = ref(true)
const toggleMarkarea = (visible) => {
if (!chart) return
option.series.forEach((item) => {
item.markArea.itemStyle.opacity = visible ? 0 : 1
item.markArea.label.show = !visible
})
chart.clear()
chart.setOption(option)
markareaVisible.value = !visible
}
function renderChart() {
if (chart) chart.clear()
option.xAxis.data.length = 0
option.series.length = 0
/* 重置结束 */
option.xAxis.data = Array.from({ length: 90 }, (_, i) => `Day${i + 1}`)
for (let i = 0; i < 3; i++) {
const lineName = `Line${i + 1}`
option.series.push({
type: 'line',
name: lineName,
data: Array.from({ length: 90 }, () => Math.random() * 200),
markArea: {
data: [[{ name: `${lineName} Markarea`, xAxis: 30 * i }, { xAxis: 30 * (i + 1) }]],
itemStyle: { opacity: 1 },
label: { show: true }
}
})
option.legend.selected[lineName] = true
}
nextTick(() => {
if (!chart) chart = echarts.init(chartRef.value)
chart.setOption(option)
chart.on('legendselectchanged', (params) => {
option.legend.selected = params.selected
})
})
}
onBeforeMount(() => {
renderChart()
})
onBeforeUnmount(() => {
if (chart) chart.dispose()
})
</script>
<style lang="scss" scoped>
.container {
position: relative;
height: 400px;
border: 1px solid #ccc;
}
.btn {
position: absolute;
top: 12px;
right: 12px;
z-index: 1;
}
</style>