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

如何在React中使用Chart.js实现柱状图沿水平阈值线分段显示多色

实现方案

核心逻辑是利用已开启的堆叠柱状图特性,将单根柱子拆为上下两个堆叠的分段,分别对应100以下的灰色段和超出100的绿色段,即可实现需求。

具体修改说明

  • 拆分数据集:将原单组数据拆为两组堆叠数据
    • 底段数据集:每个值取原数值和100的较小值,固定背景色为灰色
    • 超量段数据集:每个值取原数值减100后和0的较大值,固定背景色为绿色
  • 调整数据标签:仅在有效段显示总数值,避免重复展示
  • 调整圆角样式:仅给最上层的超量段设置顶部圆角,保证柱子视觉连贯
  • 修正原有注解配置位置:chartjs-plugin-annotation的配置需要放在plugins.annotation层级下才会生效

完整修改后代码

import { Bar, Chart } from 'react-chartjs-2';
import annotationPlugin from "chartjs-plugin-annotation";
import ChartDataLabels from "chartjs-plugin-datalabels";

// 修正插件注册写法
Chart.register(annotationPlugin, ChartDataLabels);

const chartColors = {
  yellow: '#F4D068',
  green: '#4CC26F',
  gray: '#EBEBEB'
};

// 原数据单独抽离
const originalData = [65, 140, 130, 200, 56, 35, 80];
const colorChangeValue = 100;

const data = {
  labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], // 补全对应7个数据的标签
  datasets: [
    // 底段灰色数据集
    {
      label: 'base',
      backgroundColor: chartColors.gray,
      borderColor: '#EBEBEB',
      borderWidth: 1,
      borderRadius: 0,
      data: originalData.map(v => Math.min(v, colorChangeValue)),
    },
    // 超量绿色数据集
    {
      label: 'exceed',
      backgroundColor: chartColors.green,
      borderColor: '#EBEBEB',
      borderWidth: 1,
      // 仅设置顶部圆角
      borderRadius: {
        topLeft: 10,
        topRight: 10,
        bottomLeft: 0,
        bottomRight: 0
      },
      data: originalData.map(v => Math.max(v - colorChangeValue, 0)),
    }
  ],
};

export default function BarChart() {
  return (
    <Bar
      data={data}
      width={100}
      height={70}
      options={{
        scales: {
          x: {
            stacked: true,
            grid: {
              display: false,
            },
          },
          y: {
            stacked: true,
            grid: {},
            ticks: {
              maxTicksLimit: 1
            }
          }
        },
        plugins: {
          legend: {
            display: false
          },
          title: {
            display: true,
            text: "범례1",
            padding: {
              bottom: 30
            },
            weight: "bold",
            color: "#00325c",
            font: {
              size: 13
            },
            align: "start"
          },
          datalabels: {
            display: function(context) {
              // 仅在顶层展示标签,超量段值为0时在底段展示
              return context.datasetIndex === 1 || originalData[context.dataIndex] < colorChangeValue;
            },
            color: "black",
            anchor: 'end',
            align: 'top',
            formatter: function (value, ctx) {
              // 计算并显示总数值
              const total = originalData[ctx.dataIndex];
              return total + "%";
            }
          },
          annotation: {
            annotations: {
              myHorizontalLine: {
                type: "line",
                scaleID: "y",
                borderWidth: 3,
                borderColor: "#333333",
                value: 100,
                borderDash: [8, 8],
                label: {
                  font: {
                    weight: "normal"
                  },
                  rotation: "auto",
                  enabled: true
                }
              }
            }
          }
        }
      }}
    />
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:36:03