Chart.js单向圆角环形图异常:首尾分段显示不符预期
Chart.js环形图分段单向圆角显示异常修复
问题现状
当前自定义环形图存在两个核心问题:
- 所有分段首尾均显示圆角,不符合「单向圆角」的需求
- 首尾分段衔接处显示异常,间隙与圆角效果不符合预期
当前效果:
预期目标
实现环形图每个分段仅结束端显示圆角,分段之间保留白色边框间隙,首尾衔接处显示正常:
问题原因分析
- 原代码使用
ctx.lineCap = 'round'会同时渲染线段首尾圆角,无法实现单向圆角控制 - 通过叠加白色粗边框模拟间隙的方式,未考虑环形闭合特性,导致首尾分段出现重叠异常
- 未对分段角度范围做精准调整,间隙宽度无法稳定控制
修复后的代码
JavaScript 部分
// 创建自定义单向圆角环形图控制器 Chart.defaults.RoundedDoughnut = Chart.helpers.clone(Chart.defaults.doughnut); Chart.controllers.RoundedDoughnut = Chart.controllers.doughnut.extend({ draw: function(ease) { var ctx = this.chart.ctx; var easingDecimal = ease || 1; var arcs = this.getMeta().data; var gapAngle = 0.08; // 分段间白色间隙的角度值,可按需调整 var thickness = (this.chart.options.cutoutPercentage) ? (this.chart.innerRadius + this.chart.outerRadius) / 2 - this.chart.innerRadius : (this.chart.outerRadius - this.chart.innerRadius) / 2; Chart.helpers.each(arcs, function(arc, i) { var vm = arc._view; // 调整角度,预留间隙空间 var startAngle = vm.startAngle + gapAngle / 2; var endAngle = vm.endAngle - gapAngle / 2; var radius = (vm.outerRadius + vm.innerRadius) / 2; ctx.save(); ctx.translate(vm.x, vm.y); ctx.lineWidth = thickness * 2; // 绘制分段主体(无圆角的直线段部分) ctx.beginPath(); ctx.arc(0, 0, radius, startAngle, endAngle); ctx.strokeStyle = vm.backgroundColor; ctx.lineCap = 'butt'; ctx.stroke(); // 绘制结束端的圆角 var endRadian = endAngle; ctx.beginPath(); ctx.arc( radius * Math.cos(endRadian), radius * Math.sin(endRadian), thickness, endRadian - Math.PI / 2, endRadian + Math.PI / 2 ); ctx.fillStyle = vm.backgroundColor; ctx.fill(); // 绘制分段间白色间隙(最后一个分段跳过,避免重复) if (i !== arcs.length - 1) { ctx.beginPath(); ctx.arc(0, 0, radius, endAngle, endAngle + gapAngle); ctx.strokeStyle = '#FFFFFF'; ctx.stroke(); } ctx.restore(); }); } }); // 初始化图表 window.onload = function() { new Chart(document.getElementById('usersChart'), { type: 'RoundedDoughnut', data: { datasets: [{ data: [10, 10, 10, 10, 10, 10, 10, 10], backgroundColor: [ '#5da4e7', '#8fbbe7', '#addbf0', '#4b8de7', '#4da466', '#8ec486', '#b3dba8', '#63b571' ], borderWidth: 0 }] }, options: { cutoutPercentage: 70, tooltips: { enabled: false } } }); };
HTML 部分
<canvas id="usersChart" width="400" height="400"></canvas>
修复说明
- 单向圆角实现:不再依赖
lineCap属性,而是单独绘制分段结束端的圆形填充,精准控制仅显示单侧圆角 - 间隙控制:通过调整每个分段的起始/结束角度预留间隙,直接绘制白色间隙段,避免叠加导致的异常
- 首尾衔接优化:最后一个分段跳过间隙绘制,确保环形闭合处显示正常
内容的提问来源于stack exchange,提问作者user28142193
相关产品推荐
相关产品推荐

