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

如何在ChartJS/react-chartjs-2中实现单柱状图分双数据段展示

实现思路与方案(基于react-chartjs-2/Chart.js)

你的需求完全可以实现,核心是利用Chart.js的分组堆叠柱状图能力,把每个年度的柱子拆分为「阳性检测数」和「总检测数-阳性检测数」两个堆叠段,同时按机构分组展示各年度的柱子组。以下是具体实现思路:

一、数据结构转换

首先需要把你的原始数据(每个机构对应3个年度的Total/Pos),转换为Chart.js所需的多数据集格式:

  • 每个年度拆分为两个数据集:「年度阳性数」和「年度非阳性数(Total-Pos)」
  • 所有数据集的data数组长度与机构数量一致,对应每个机构的数值

举个数据转换的示例(假设原始数据是数组):

// 原始数据示例
const rawData = [
  { institution: 'De Regenboog', Year1Total: 34, Year1Pos: 4, Year2Total: 40, Year2Pos: 6, Year3Total: 38, Year3Pos: 5 },
  { institution: 'AnotherOrg', Year1Total: 28, Year1Pos: 3, Year2Total: 32, Year2Pos: 4, Year3Total: 30, Year3Pos: 2 }
];

// 转换为Chart.js数据集
const datasets = [
  // 2021年阳性
  {
    label: '2021 阳性',
    data: rawData.map(item => item.Year1Pos),
    backgroundColor: '#ff4d4f', // 自定义阳性颜色
    stack: '2021' // 标记同年度的堆叠组
  },
  // 2021年非阳性(Total-Pos)
  {
    label: '2021 总检测-阳性',
    data: rawData.map(item => item.Year1Total - item.Year1Pos),
    backgroundColor: '#d9d9d9', // 自定义非阳性颜色
    stack: '2021'
  },
  // 2022年阳性
  {
    label: '2022 阳性',
    data: rawData.map(item => item.Year2Pos),
    backgroundColor: '#ff4d4f',
    stack: '2022'
  },
  // 2022年非阳性
  {
    label: '2022 总检测-阳性',
    data: rawData.map(item => item.Year2Total - item.Year2Pos),
    backgroundColor: '#d9d9d9',
    stack: '2022'
  },
  // 2023年阳性
  {
    label: '2023 阳性',
    data: rawData.map(item => item.Year3Pos),
    backgroundColor: '#ff4d4f',
    stack: '2023'
  },
  // 2023年非阳性
  {
    label: '2023 总检测-阳性',
    data: rawData.map(item => item.Year3Total - item.Year3Pos),
    backgroundColor: '#d9d9d9',
    stack: '2023'
  }
];

// x轴标签为机构名称
const labels = rawData.map(item => item.institution);

二、Chart.js配置核心设置

在options中开启堆叠模式,并确保分组逻辑生效:

const options = {
  responsive: true,
  scales: {
    y: {
      stacked: true, // 开启y轴堆叠,让同stack的数据集合并为一个柱子
      title: {
        display: true,
        text: '检测数量'
      }
    },
    x: {
      title: {
        display: true,
        text: '机构名称'
      }
    }
  },
  plugins: {
    legend: {
      position: 'top',
      // 可选:自定义图例,把同年度的两个项合并显示
      labels: {
        generateLabels: (chart) => {
          const originalLabels = chart.data.datasets.map(ds => ds.label);
          // 去重只保留年度标识
          return [...new Set(originalLabels.map(l => l.split(' ')[0]))].map(year => ({
            text: year,
            fillStyle: '#ff4d4f', // 可调整为年度区分色,或保持阳性色
            strokeStyle: '#000'
          }));
        }
      }
    }
  }
};

三、react-chartjs-2组件使用

把转换好的数据和配置传入Bar组件:

import { Bar } from 'react-chartjs-2';
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend } from 'chart.js';

// 注册需要的组件
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);

export default function StackedGroupBarChart() {
  return (
    <Bar
      data={{ labels, datasets }}
      options={options}
    />
  );
}

关键逻辑说明

  1. 堆叠分组:通过给同年度的两个数据集设置相同的stack值,Chart.js会自动把它们堆叠成一个柱子,高度正好是总检测数(阳性+非阳性)
  2. 颜色区分:阳性段用醒目颜色,非阳性段用中性颜色,实现你需要的分段效果
  3. 多年度展示:每个机构下会自动生成三个柱子组(对应三个年度),满足多维度展示需求

Google Sheets无法实现是因为其图表自定义能力有限,而Chart.js作为开源可视化库,完全支持这种分组+堆叠的组合场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:43:11