Recharts/Chart.js能否创建径向堆叠条形图?项目图表库选型咨询
径向堆叠条形图在Recharts和Chart.js中的实现方案
Recharts和Chart.js(搭配react-chart-js2)都没有开箱即用的这类图表组件,但可以通过自定义扩展来实现,以下是具体思路:
Recharts 实现方式
- 以
Radar组件为基础,它自带的极坐标体系(中心0点、径向轴、角度分类轴)刚好匹配需求的布局。 - 关闭雷达图默认的折线、面积填充,只保留轴网格作为参考。
- 使用Recharts的
Customized组件,在图表的SVG容器内手动绘制每个堆叠条形:- 按角度(类别)分组处理数据,计算每个堆叠条的起始半径和终止半径——从中心(半径0)开始,依次累加每个系列的数值,前一个条的终止半径就是下一个条的起始半径。
- 计算每个角度对应的扇形区间宽度,将条形绘制在对应角度的中心位置,确保条形不超出角度区间。
- 用SVG的
rect元素或path元素绘制条形,通过极坐标转笛卡尔坐标的公式计算元素位置。
Chart.js (react-chart-js2) 实现方式
- 先配置一个空的极坐标雷达图,隐藏默认的折线、填充和不必要的网格,只保留角度轴和径向轴。
- 通过Chart.js的自定义插件实现绘制逻辑:
- 在
afterDraw钩子中获取图表的Canvas上下文,遍历每个角度和数据系列。 - 按角度分组计算堆叠条的起始/终止半径,和Recharts的逻辑一致。
- 利用Canvas的坐标转换和绘图API,将极坐标转换为笛卡尔坐标后,绘制矩形或弧形堆叠条。
- 自定义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
相关产品推荐
相关产品推荐

