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

如何让SVG环形图(Donut Chart)的所有弧段无缝连接?

解决SVG环形图(circle元素)弧段间隙问题

你的问题出在偏移量计算错误,以及元素位置未对齐,导致弧段之间出现间隙。以下是修正方案:

问题根源

  1. 偏移量计算中多余的1 * i:这会让每个切片的起始位置额外偏移i个单位,强制拉开了切片间隙。
  2. circle元素位置未与SVG viewBox中心对齐:导致环形图整体偏移,可能加剧视觉上的间隙感。
  3. pathLength的冗余设置:不需要结合数组长度计算,统一设为100即可让百分比直接对应dash长度。

修正后的完整代码

JavaScript

var DonutSlice = [{
      id: 1,
      percent: 60,
      color: 'DarkSeaGreen',
      label: 'Slice 1'
    },
    {
      id: 2,
      percent: 30,
      color: 'DarkOrchid',
      label: 'Slice 2'
    },
    {
      id: 3,
      percent: 10,
      color: 'Tomato',
      label: 'Slice 3'
    }
];

var circlecontainer = document.getElementById('circlecontainer');
var output = document.getElementById('output');

circlecontainer.innerHTML = DonutSlice.map((item, i, arr) => {
  // 去掉多余的1*i,仅计算前面所有切片的百分比总和作为偏移
  let offset = arr.filter((item, j) => j < i)
    .reduce((total, item) => total + item.percent, 0);
  return `<circle data-id="${item.id}" stroke="${item.color}"
      cx="87" cy="87" r="79" class="slice"
      pathLength="100"
      stroke-dasharray="${item.percent} 100"
      stroke-dashoffset="-${offset}" />`;
}).join('');

circlecontainer.addEventListener('mouseover', e => {
  let slice = e.target.closest('.slice');
  if (slice) {
    item = DonutSlice.find(item => item.id == parseInt(slice.dataset.id));
    output.innerHTML = `${item.label} was hovered`;
  }
});

CSS

.slice {
  /* stroke-linecap: round; */
  stroke-width: 15;
  fill: none;
  cursor: pointer;
}

p#output {
  text-align: center;
}

HTML

<div style="width: 200px">
  <svg class="svg2" width="174" height="174" preserveAspectRatio="xMinYMin meet"
      xmlns="http://www.w3.org/2000/svg" viewBox="0 0 174 174" version="1.1">
    <circle fill="#000000" cx="87" cy="87" r="87" />
    <g id="circlecontainer" transform="rotate(-90 87 87)"></g>
  </svg>
  <p id="output"></p>
</div>

额外优化说明

  • 给circlecontainer添加了rotate(-90 87 87):默认SVG环形的起始点在右侧,旋转-90度后起始点会移到顶部,符合常见环形图的视觉习惯。
  • 修正了鼠标事件的提示文本:原代码写的是"clicked"但实际是mouseover事件,改为"hovered"更准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:25:30