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

如何使用ReactEcharts创建带分组底部标注的分类子类别

在React Echarts中实现分组带底部标注的分类子类别图表

1. 数据预处理

先把扁平的原始数据转换成适配Echarts分组展示的结构:按source(entrance)分组,整理出包含子类别的x轴类目,同时记录每个分组的位置信息,方便后续添加底部标注。

示例处理代码:

// 原始数据
const rawData = [
  { name: 'entered', value: 40, time: '09:00', source: 'entrance 1' },
  { name: 'exit', value: 60, time: '09:00', source: 'entrance 1' },
  { name: 'entered', value: 35, time: '09:00', source: 'entrance 2' },
  { name: 'exit', value: 55, time: '09:00', source: 'entrance 2' },
  { name: 'entered', value: 50, time: '09:00', source: 'entrance 3' },
  { name: 'exit', value: 45, time: '09:00', source: 'entrance 3' },
  { name: 'entered', value: 28, time: '09:00', source: 'entrance 4' },
  { name: 'exit', value: 62, time: '09:00', source: 'entrance 4' },
  { name: 'entered', value: 42, time: '09:00', source: 'entrance 5' },
  { name: 'exit', value: 58, time: '09:00', source: 'entrance 5' },
];

// 按source分组
const groupedData = {};
rawData.forEach(item => {
  if (!groupedData[item.source]) {
    groupedData[item.source] = [];
  }
  groupedData[item.source].push(item);
});

// 生成x轴类目、系列数据,记录分组位置
const xAxisData = [];
const seriesData = [];
const groupPositions = [];

let currentIndex = 0;
Object.keys(groupedData).forEach(source => {
  const items = groupedData[source];
  const startIndex = currentIndex;
  items.forEach(item => {
    xAxisData.push(`${source}-${item.name}`);
    seriesData.push(item.value);
    currentIndex++;
  });
  // 计算分组中间位置,用于标注定位
  groupPositions.push({
    name: source,
    midPos: (startIndex + currentIndex - 1) / 2
  });
});

2. 配置Echarts Option(核心实现)

通过配置x轴隐藏原始类目、设置柱子分组间隔,再用graphic组件添加底部分组标注,实现需求效果:

import ReactECharts from 'echarts-for-react';

const EntranceChart = () => {
  const getOption = () => {
    return {
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '15%', // 预留底部标注空间
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: xAxisData,
        axisLabel: { show: false }, // 隐藏原始子类别文字
        axisTick: { show: false },
        axisLine: { show: false }
      },
      yAxis: {
        type: 'value',
        axisLabel: { formatter: '{value}' }
      },
      series: [
        {
          name: '流量',
          type: 'bar',
          data: seriesData,
          itemStyle: {
            // 区分entered和exit的柱子颜色
            color: (params) => params.name.includes('entered') ? '#5470c6' : '#91cc75'
          },
          barGap: 0, // 子类别柱子无间隔
          barCategoryGap: '30%' // 分组之间留间隔
        }
      ],
      // 添加底部分组标注
      graphic: groupPositions.map(pos => ({
        type: 'text',
        left: 'center',
        bottom: '5%',
        // 按分组中间位置计算偏移量,精准定位
        x: `calc(50% + ${(pos.midPos - (xAxisData.length - 1)/2) * 100 / (xAxisData.length - 1)}%)`,
        style: {
          text: pos.name,
          fontSize: 12,
          fill: '#333'
        }
      }))
    };
  };

  return <ReactECharts option={getOption()} style={{ height: '400px' }} />;
};

export default EntranceChart;

3. 关键细节说明

  • 分组间隔控制:通过barCategoryGap设置不同entrance分组之间的间隔,让分组边界清晰。
  • 标注精准定位:利用graphic组件的相对计算,把标注文字放在每个分组的正下方。
  • 子类别样式区分:通过itemStyle的回调,根据子类别名称设置不同颜色,直观区分entered和exit。

内容的提问来源于stack exchange,提问作者Николай Петров

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:55:09