如何在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
相关产品推荐
相关产品推荐

