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

Chart.js单向圆角环形图异常:首尾分段显示不符预期

Chart.js环形图分段单向圆角显示异常修复

问题现状

当前自定义环形图存在两个核心问题:

  • 所有分段首尾均显示圆角,不符合「单向圆角」的需求
  • 首尾分段衔接处显示异常,间隙与圆角效果不符合预期

当前效果:
当前环形图异常效果

预期目标

实现环形图每个分段仅结束端显示圆角,分段之间保留白色边框间隙,首尾衔接处显示正常:
预期环形图效果

问题原因分析

  1. 原代码使用ctx.lineCap = 'round'会同时渲染线段首尾圆角,无法实现单向圆角控制
  2. 通过叠加白色粗边框模拟间隙的方式,未考虑环形闭合特性,导致首尾分段出现重叠异常
  3. 未对分段角度范围做精准调整,间隙宽度无法稳定控制

修复后的代码

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>

修复说明

  1. 单向圆角实现:不再依赖lineCap属性,而是单独绘制分段结束端的圆形填充,精准控制仅显示单侧圆角
  2. 间隙控制:通过调整每个分段的起始/结束角度预留间隙,直接绘制白色间隙段,避免叠加导致的异常
  3. 首尾衔接优化:最后一个分段跳过间隙绘制,确保环形闭合处显示正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:21:11