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

如何基于recharts堆叠柱状图数据集自定义YAxis刻度与显示规则?

解决Recharts堆叠柱状图百分比显示与Tooltip实际值需求

实现思路

先预处理原始数据,为每个数据项添加基于dt和internet总和计算的百分比字段,同时保留原始数值。这样图表渲染使用百分比数据,Tooltip直接读取原始数值展示,兼顾两种需求。

完整代码实现

const StackBarChart = ({
  title,
  xDataKey,
  dataKeyA,
  dataKeyB,
  data,
}: StackChartPropType) => {
  const TICK_COLOR = "#C7C7C7";

  // 预处理数据:计算百分比字段,保留原始数值
  const processedData = data.map(item => {
    const total = item[dataKeyA] + item[dataKeyB];
    return {
      ...item,
      [`${dataKeyA}Percent`]: total ? (item[dataKeyA] / total) * 100 : 0,
      [`${dataKeyB}Percent`]: total ? (item[dataKeyB] / total) * 100 : 0,
    };
  });

  return (
    <Card className="bg-gradient-to-tl from-gray-50 to-slate-100">
      <CardHeader>
        <CardTitle>{title}</CardTitle>
      </CardHeader>
      <CardContent>
        <ResponsiveContainer width="100%" height={260}>
          <BarChart data={processedData}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis
              dataKey={xDataKey}
              angle={-30}
              textAnchor="end"
              height={70}
              tick={<CustomizedAxisTick />}
              tickLine={true}
            />
            {/* Y轴配置为百分比刻度 */}
            <YAxis
              tick={{ stroke: TICK_COLOR, strokeOpacity: 0.1, fontSize: 12 }}
              tickLine={true}
              type="number"
              includeHidden
              tickFormatter={(value) => `${Math.round(value)}%`}
              domain={[0, 100]}
            />
            {/* 自定义Tooltip显示原始实际数值 */}
            <Tooltip
              content={({ active, payload, label }) => {
                if (active && payload && payload.length) {
                  const originalItem = data.find(item => item[xDataKey] === label);
                  return (
                    <div className="bg-white p-3 border rounded shadow">
                      <p className="font-bold">{label}</p>
                      <p style={{ color: "#8884d8" }}>{dataKeyA}: {originalItem[dataKeyA]}</p>
                      <p style={{ color: "#82ca9d" }}>{dataKeyB}: {originalItem[dataKeyB]}</p>
                    </div>
                  );
                }
                return null;
              }}
            />
            <Legend formatter={customLegendFormatter} />
            {/* 第一个堆叠柱:用百分比数据渲染,标签显示百分比 */}
            <Bar dataKey={`${dataKeyA}Percent`} stackId="a" fill="#8884d8">
              <LabelList
                dataKey={`${dataKeyA}Percent`}
                position="insideStart"
                formatter={(value) => `${Math.round(value)}%`}
              />
            </Bar>
            {/* 第二个堆叠柱:用百分比数据渲染,标签显示百分比 */}
            <Bar dataKey={`${dataKeyB}Percent`} stackId="a" fill="#82ca9d">
              <LabelList
                dataKey={`${dataKeyB}Percent`}
                position="insideTop"
                formatter={(value) => `${Math.round(value)}%`}
              />
            </Bar>
          </BarChart>
        </ResponsiveContainer>
      </CardContent>
    </Card>
  );
};

关键细节说明

  • 数据预处理时判断total是否为0,避免除以0的报错情况
  • 使用Math.round()对百分比取整,保证显示简洁直观
  • 自定义Tooltip通过label匹配原始数据项,确保展示的是真实的原始数值
  • Y轴限定domain=[0,100],确保百分比刻度的显示范围正确

内容的提问来源于stack exchange,提问作者K M Jiaul Islam Jibon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:14:53