You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在echarts-for-react中关联两个图表的图例

实现单个图例控制两个独立ECharts图表(echarts-for-react)

核心思路是通过监听左侧图表的图例交互事件,用ECharts的dispatchAction方法同步控制右侧图表的图例状态,完全基于两个独立图表实现,无需合并。

步骤1:保存图表实例引用

用useRef存储两个echarts-for-react的实例,方便后续操作:

import ReactECharts from 'echarts-for-react';
import { useRef, useEffect } from 'react';

function DualChart() {
  const leftChartRef = useRef(null);
  const rightChartRef = useRef(null);

  // 获取ECharts实例的工具函数
  const getEchartInstance = (ref) => ref?.current?.getEchartsInstance();
  
  // 后续代码...
}

步骤2:监听左侧图例事件并同步状态

给左侧图表绑定legendselectchanged事件,当图例点击时,同步右侧图表的选中状态:

// 左侧图表的事件配置
const leftChartEvents = {
  legendselectchanged: (params) => {
    const rightChart = getEchartInstance(rightChartRef);
    if (!rightChart) return;

    // 遍历所有图例项,同步右侧图表的选中状态
    Object.entries(params.selected).forEach(([name, isSelected]) => {
      if (isSelected) {
        rightChart.dispatchAction({ type: 'legendSelect', name });
      } else {
        rightChart.dispatchAction({ type: 'legendUnselect', name });
      }
    });
  }
};

步骤3:隐藏右侧图表的图例

在右侧图表的配置项中设置legend: { show: false },只保留左侧图例:

// 基础配置模板,根据你的实际图表类型(饼图/柱状图)修改
const getChartOption = (isLeftChart, seriesData) => ({
  legend: {
    show: isLeftChart // 左侧显示图例,右侧隐藏
  },
  // 你的图表坐标轴、系列配置,示例为柱状图
  xAxis: { type: 'category', data: ['A', 'B', 'C', 'D'] },
  yAxis: { type: 'value' },
  series: [
    { name: '系列1', type: 'bar', data: seriesData.s1 },
    { name: '系列2', type: 'bar', data: seriesData.s2 }
  ]
});

步骤4:初始化时同步默认图例状态

如果左侧图有默认选中/未选中的项,在组件挂载后同步到右侧:

useEffect(() => {
  const leftChart = getEchartInstance(leftChartRef);
  const rightChart = getEchartInstance(rightChartRef);

  if (!leftChart || !rightChart) return;

  const legendConfig = leftChart.getOption().legend?.[0];
  if (legendConfig?.selected) {
    Object.entries(legendConfig.selected).forEach(([name, isSelected]) => {
      if (!isSelected) {
        rightChart.dispatchAction({ type: 'legendUnselect', name });
      }
    });
  }
}, []);

完整组件示例

import ReactECharts from 'echarts-for-react';
import { useRef, useEffect } from 'react';

function DualControlledChart() {
  const leftChartRef = useRef(null);
  const rightChartRef = useRef(null);

  const getEchartInstance = (ref) => ref?.current?.getEchartsInstance();

  const leftChartEvents = {
    legendselectchanged: (params) => {
      const rightChart = getEchartInstance(rightChartRef);
      if (!rightChart) return;

      Object.entries(params.selected).forEach(([name, isSelected]) => {
        isSelected 
          ? rightChart.dispatchAction({ type: 'legendSelect', name })
          : rightChart.dispatchAction({ type: 'legendUnselect', name });
      });
    }
  };

  useEffect(() => {
    const leftChart = getEchartInstance(leftChartRef);
    const rightChart = getEchartInstance(rightChartRef);

    if (!leftChart || !rightChart) return;

    const legendConfig = leftChart.getOption().legend?.[0];
    if (legendConfig?.selected) {
      Object.entries(legendConfig.selected).forEach(([name, isSelected]) => {
        if (!isSelected) {
          rightChart.dispatchAction({ type: 'legendUnselect', name });
        }
      });
    }
  }, []);

  const getChartOption = (isLeftChart, seriesData) => ({
    legend: { show: isLeftChart },
    xAxis: { type: 'category', data: ['A', 'B', 'C', 'D'] },
    yAxis: { type: 'value' },
    series: [
      { name: '系列1', type: 'bar', data: seriesData.s1 },
      { name: '系列2', type: 'bar', data: seriesData.s2 }
    ]
  });

  return (
    <div style={{ display: 'flex', gap: '20px', padding: '20px' }}>
      <ReactECharts
        ref={leftChartRef}
        option={getChartOption(true, { s1: [10, 20, 30, 40], s2: [15, 25, 35, 45] })}
        onEvents={leftChartEvents}
        style={{ width: '50%', height: '400px' }}
      />
      <ReactECharts
        ref={rightChartRef}
        option={getChartOption(false, { s1: [20, 30, 40, 50], s2: [25, 35, 45, 55] })}
        style={{ width: '50%', height: '400px' }}
      />
    </div>
  );
}

export default DualControlledChart;

补充说明

  • 确保两个图表的图例name完全一致,否则无法同步状态
  • 如果需要支持图例的其他交互(如全选、反选),可以在左侧图表绑定对应事件(如legendselectall),再给右侧图表dispatch对应的action即可
  • 这种方案无需修改原有图表的系列结构,改动小,适合已有双图表的场景

内容的提问来源于stack exchange,提问作者Alberto Movio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:35:32