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

Recharts/Chart.js能否创建径向堆叠条形图?项目图表库选型咨询

径向堆叠条形图在Recharts和Chart.js中的实现方案

Recharts和Chart.js(搭配react-chart-js2)都没有开箱即用的这类图表组件,但可以通过自定义扩展来实现,以下是具体思路:

Recharts 实现方式

  • 以Radar组件为基础,它自带的极坐标体系(中心0点、径向轴、角度分类轴)刚好匹配需求的布局。
  • 关闭雷达图默认的折线、面积填充,只保留轴网格作为参考。
  • 使用Recharts的Customized组件,在图表的SVG容器内手动绘制每个堆叠条形:
    1. 按角度(类别)分组处理数据,计算每个堆叠条的起始半径和终止半径——从中心(半径0)开始,依次累加每个系列的数值,前一个条的终止半径就是下一个条的起始半径。
    2. 计算每个角度对应的扇形区间宽度,将条形绘制在对应角度的中心位置,确保条形不超出角度区间。
    3. 用SVG的rect元素或path元素绘制条形,通过极坐标转笛卡尔坐标的公式计算元素位置。

Chart.js (react-chart-js2) 实现方式

  • 先配置一个空的极坐标雷达图,隐藏默认的折线、填充和不必要的网格,只保留角度轴和径向轴。
  • 通过Chart.js的自定义插件实现绘制逻辑:
    1. 在afterDraw钩子中获取图表的Canvas上下文,遍历每个角度和数据系列。
    2. 按角度分组计算堆叠条的起始/终止半径,和Recharts的逻辑一致。
    3. 利用Canvas的坐标转换和绘图API,将极坐标转换为笛卡尔坐标后,绘制矩形或弧形堆叠条。
    4. 自定义tooltip和hover效果,监听鼠标位置判断是否落在某个堆叠条上,显示对应数据。

核心通用逻辑

数据预处理

先把原始数据转换成便于堆叠计算的格式,示例代码:

const rawData = [
  { category: '类别1', 系列A: 20, 系列B: 30, 系列C: 15 },
  { category: '类别2', 系列A: 15, 系列B: 25, 系列C: 20 },
];

// 处理成每个类别下的堆叠半径信息
const processedData = rawData.map(item => {
  const seriesValues = [item['系列A'], item['系列B'], item['系列C']];
  const stackInfo = [];
  let currentStartRadius = 0;
  
  seriesValues.forEach(val => {
    stackInfo.push({
      start: currentStartRadius,
      end: currentStartRadius + val
    });
    currentStartRadius += val;
  });
  
  return { category: item.category, stacks: stackInfo };
});

极坐标转笛卡尔坐标

不管用SVG还是Canvas,都需要把半径和角度转换成画布上的坐标,公式如下:

// centerX、centerY是图表中心坐标
// theta是角度转成的弧度(注意:多数图表库以顶部为0度,顺时针递增)
const x = centerX + radius * Math.cos(theta);
const y = centerY + radius * Math.sin(theta);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:22:56