第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. 切换菜单离开页面,图表实例自动销毁,无内存泄漏。
相关推荐
u0111026754 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
雪芽蓝域zzs10 小时前
第 7 节:多边形点击弹窗 + 清空绘制按钮
vue.js
溪语流沙10 小时前
【Web全栈进阶】Composition API与组件通信:props深入、emit、插槽
前端·css·vue.js
顽疲13 小时前
Java vue 养老系统源码详解:入住核算单 live-check 缴费入账与预交金收据实践
java·vue.js·python·java 养老·springboot 养老·vue养老
志尊宝14 小时前
Vue3 零基础每日笔记(088·完结):从零到一——一个完整 Vue3 项目的成长复盘
前端·javascript·vue.js·笔记·ecmascript·#vue.js
桔筐14 小时前
Vue中DOM的data-*自定义属性(dataset)与Vue data响应式变量区别详解
前端·javascript·vue.js
用户17335980753716 小时前
纯前端 PDF 按书签拆分避坑指南:拆分后章节对不上?
前端·javascript·vue.js
雪芽蓝域zzs17 小时前
Webstorm打开uniapp uvue文件报红处理方案
vue.js
撸串-研究生18 小时前
面向景区的综合服务管理平台设计——以稻城亚丁景区为例【附源码】
java·开发语言·vue.js·前后端分离·稻城亚丁景区
志尊宝1 天前
Vue3 零基础每日笔记(082):文件上传实战——el-upload 校验、自定义上传、头像预览
前端·javascript·vue.js·笔记·#javascript·#vue.js