第22章:ECharts 图表联动(多图表交互联动)

第22章:ECharts 图表联动(多图表交互联动)

功能说明:页面放置2 个独立图表 ,点击第一个图表的数据项,第二个图表自动刷新对应明细数据;同时复用我们已经封装好的 useEcharts,自带防抖 resize、实例就绪等待、导出功能。

页面完整代码

复制代码
<template>
  <div class="chart-link-page">
    <el-card style="margin-bottom:20px">
      <template #header>
        <div>图表联动演示|点击上方柱状图,下方饼图自动切换明细</div>
      </template>
      <el-row :gutter="20">
        <el-col :span="12">
          <div ref="chartRef1" style="width:100%;height:350px;border:1px solid #eee"></div>
        </el-col>
        <el-col :span="12">
          <div ref="chartRef2" style="width:100%;height:350px;border:1px solid #eee"></div>
        </el-col>
      </el-row>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useEcharts } from '@/composables/echartHelper'

// 实例化两个独立图表,每个图表单独调用useEcharts
const {
  chartRef: chartRef1,
  setChartOption: setOption1,
  onChartEvent: onEvent1
} = useEcharts()

const {
  chartRef: chartRef2,
  setChartOption: setOption2
} = useEcharts()

// 模拟总数据
const totalData = [
  { name: '1月', value: 120, detail: [{ name: 'A产品', val: 70 }, { name: 'B产品', val: 50 }] },
  { name: '2月', value: 200, detail: [{ name: 'A产品', val: 110 }, { name: 'B产品', val: 90 }] },
  { name: '3月', value: 150, detail: [{ name: 'A产品', val: 80 }, { name: 'B产品', val: 70 }] },
  { name: '4月', value: 280, detail: [{ name: 'A产品', val: 160 }, { name: 'B产品', val: 120 }] },
]

// 左侧柱状图配置
const barOption = {
  title: { text: '月度总销售额', left: 'center' },
  tooltip: { trigger: 'axis' },
  xAxis: {
    type: 'category',
    data: totalData.map(item => item.name)
  },
  yAxis: { type: 'value', name: '万元' },
  series: [
    {
      name: '销售额',
      type: 'bar',
      data: totalData.map(item => item.value),
      itemStyle: { color: '#409EFF' }
    }
  ]
}

// 初始化饼图(默认显示1月数据)
function initPie(dataItem) {
  const pieOption = {
    title: { text: `${dataItem.name}产品明细`, left: 'center' },
    tooltip: { trigger: 'item' },
    series: [
      {
        type: 'pie',
        radius: ['40%', '70%'],
        data: dataItem.detail.map(d => ({ name: d.name, value: d.val }))
      }
    ]
  }
  setOption2(pieOption)
}

onMounted(async () => {
  // 渲染柱状图
  await setOption1(barOption)
  // 默认加载第一个月饼图
  initPie(totalData[0])
})

// 核心联动逻辑:点击柱状图,更新饼图
onEvent1('click', (params) => {
  const clickItem = totalData.find(item => item.name === params.name)
  if (clickItem) {
    initPie(clickItem)
  }
})
</script>

核心知识点

  1. 多个图表就要多次调用useEcharts(),每个图表拥有独立实例、独立 ref,互不干扰;
  2. 利用onChartEvent监听点击事件,拿到点击的参数,筛选对应明细数据;
  3. 调用setChartOption更新第二个图表,内部自带notMerge:true,会完全覆盖旧图表配置,不会出现残留文字;
  4. 自带窗口 resize 防抖,两个图表都会自动自适应。

🧪 测试清单

  1. 保存页面,刷新浏览器;
  2. 页面左右两个图表正常渲染,右侧饼图默认展示 1 月明细;
  3. 点击左侧柱状图的【2 月】柱子,右侧饼图自动切换为 2 月 A/B 产品数据;
  4. 切换浏览器窗口大小,两张图表同时自适应缩放;
  5. 切换菜单离开页面,图表实例自动销毁,无内存泄漏。
相关推荐
小郎君65817 分钟前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
yilaisai34 分钟前
前端开发遇到的一些细节问题整理
vue.js
华玥作者1 小时前
Vue 3 + TypeScript + uni-app 组件库推荐:hy-app(华玥组件库)
vue.js·typescript·uni-app
阿琳a_2 小时前
b-map-viewer:面向 Vue 3 的地图可视化 SDK,从接入到展示再到交互分析
前端·javascript·vue.js·gis·数据可视化·地图
齐 飞3 小时前
VUE2常用语法总结
javascript·vue.js
北城笑笑3 小时前
Vue 106 ,上篇:前端桌面端应用实现方案( Electron 框架详细介绍,Vue + Electron )
前端·javascript·vue.js·python·electron
不磕了还不行4 小时前
用 Vue + Element UI 把元宝搜索的返回值做成“能点开检查的证据卡片”
前端·vue.js·ui
FRing0314 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
徐小夕17 小时前
深度剖析 30k star 的编码 Agent DeepSeek-Reasonix:长会话 Token 成本直降 80%
前端·vue.js·github
ruanno_top20 小时前
1 万行表格只渲染 18 行:虚拟滚动让我放弃了三个功能
vue.js