求助:基于百分比分割的空心环形图实现(HTML Canvas)
用HTML Canvas实现精准占比的空心环形统计图
当然可以!HTML Canvas完全能实现按百分比精准分割的空心环形图,你之前的问题大概率是角度计算逻辑出了问题——毕竟环形图的核心就是把360°(也就是2π弧度)按比例分配给每个颜色区块。我给你一个完整的可运行示例,附带详细注释,你可以直接参考:
完整实现代码
<!DOCTYPE html> <html> <head> <style> .ring-chart { margin: 20px; width: 200px; height: 200px; } </style> </head> <body> <canvas class="ring-chart" id="ringChart"></canvas> <script> // 获取Canvas元素和绘图上下文 const canvas = document.getElementById('ringChart'); const ctx = canvas.getContext('2d'); // 设置Canvas实际尺寸(避免模糊) canvas.width = canvas.offsetWidth * 2; canvas.height = canvas.offsetHeight * 2; ctx.scale(2, 2); // 环形图基础参数 const centerX = canvas.offsetWidth / 2; const centerY = canvas.offsetHeight / 2; const outerRadius = 80; // 外半径 const innerRadius = 50; // 内半径(空心部分) const totalAngle = Math.PI * 2; // 总角度:2π弧度=360° let startAngle = -Math.PI / 2; // 起始角度设为顶部(默认0°是右侧) // 你的数据:按百分比分配,总和尽量接近100%(这里补了1%让总和为100) const data = [ { percent: 0.33, color: '#e74c3c' }, { percent: 0.33, color: '#2ecc71' }, { percent: 0.34, color: '#3498db' } ]; // 遍历每个数据块绘制环形区块 data.forEach(item => { // 计算当前区块的结束角度 const endAngle = startAngle + (totalAngle * item.percent); ctx.beginPath(); // 绘制外圆弧 ctx.arc(centerX, centerY, outerRadius, startAngle, endAngle); // 连线到内圆的结束点 ctx.lineTo(centerX + innerRadius * Math.cos(endAngle), centerY + innerRadius * Math.sin(endAngle)); // 反向绘制内圆弧(从结束点到起始点) ctx.arc(centerX, centerY, innerRadius, endAngle, startAngle, true); // 连线回外圆的起始点,闭合路径 ctx.lineTo(centerX + outerRadius * Math.cos(startAngle), centerY + outerRadius * Math.sin(startAngle)); // 设置填充颜色并填充 ctx.fillStyle = item.color; ctx.fill(); // 更新起始角度,为下一个区块做准备 startAngle = endAngle; }); </script> </body> </html>
关键逻辑说明
- 角度计算:每个区块的角度 = 总角度(2π) × 占比,这样能保证完全按百分比分配,不会出现偏差。
- 起始角度调整:默认Canvas的0°是右侧,我把起始角度设为
-Math.PI/2(也就是顶部),符合大多数环形图的视觉习惯,你也可以根据需求修改成其他起始位置。 - 空心实现:通过先画外圆弧,再连线到内圆,反向画内圆弧,最后闭合路径的方式,填充出来的就是环形的区块,完美实现空心效果。
- 高清适配:设置Canvas实际尺寸为显示尺寸的2倍并缩放,避免图形在高分屏上模糊。
你可以把自己的数据替换进去,只要保证所有percent的总和为1(即100%),就能得到精准的占比分割效果。
内容的提问来源于stack exchange,提问作者Akki619
相关产品推荐
相关产品推荐

