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

如何将现有SVG路径转换为环形图(Donut Chart)的扇区?

我来帮你搞定环形图的路径计算问题,咱们一步步拆解:

核心问题分析

你当前的代码是把饼图的路径直接改成“外弧→圆心→内弧”,但环形图的扇区是两个同心圆弧+两条径向线组成的闭合区域,所以不能直接指向圆心,得调整Lineto和内弧的终点坐标,同时检查弧参数的正确性。

一、Lineto坐标的修正

原来的L1,1是指向饼图的圆心,但环形图的径向线应该是从外弧的终点连接到同角度的内弧终点,而不是圆心。

假设你的外半径是R=1,内半径是r=0.58,SVG的圆心在(1,1):

  • 外弧终点的单位向量是(endX, endY)(也就是GetXYVals(totalPercentage)返回的结果),那么外弧终点坐标是(1 + endX*R, 1 + endY*R)
  • 对应角度的内弧终点坐标就是(1 + endX*r, 1 + endY*r)——相当于把外弧的单位向量按内半径比例缩小,再加上圆心坐标。

所以你原来的L1,1要替换成这个内弧终点坐标,而不是圆心。

二、第二个Arcto(内弧)的终点坐标修正

你当前内弧的终点用了外弧的终点,这是错误的。内弧应该从刚才的内弧终点,回到当前扇区起始角度的内弧起点,这样才能闭合扇区。

扇区起始角度的单位向量是(xCurr, yCurr),对应的内弧起点坐标就是(1 + xCurr*r, 1 + yCurr*r)。

另外,内弧的sweepFlag(也就是Arc命令里的第6个参数)要和外弧相反:外弧用1(顺时针绘制),内弧就用0(逆时针绘制),这样路径才能正确绕回起点,形成闭合的环形扇区。

三、现有参数的适用性检查

  • largeArcFlag:这个参数是判断弧是否超过半圆,对于环形图的内外弧来说,因为对应的角度差完全一致,所以你原来的percent > 0.5 ? 1 : 0逻辑是完全适用的,不用改。
  • 半径参数:外弧用1,1,内弧用0.58,0.58,这个设置没问题,只要保持内外半径为固定值就行。
  • 最后建议给路径加上Z命令,自动闭合路径,这样就不用手动处理最后一段Lineto了,代码更简洁。

修正后的代码示例

调整你的C#代码中路径构造的部分:

int count = 0; 
double xCurr = 1; 
double yCurr = 0; 
double totalPercentage = 0; 
string slices = "";
double innerRadius = 0.58; // 内半径,可按需调整

for (int i = 0; i < array.Length; i++) { 
    double percent = GetPercentage(array[i], GetTotal()); 
    totalPercentage += percent; 
    int largeArcFlag = percent > 0.5 ? 1 : 0;
    // 获取结束角度的单位向量
    double[] endXY = GetXYVals(totalPercentage);
    // 计算各关键坐标
    double startOuterX = xCurr + 1;
    double startOuterY = yCurr + 1;
    double endOuterX = endXY[0] + 1;
    double endOuterY = endXY[1] + 1;
    double endInnerX = 1 + innerRadius * endXY[0];
    double endInnerY = 1 + innerRadius * endXY[1];
    double startInnerX = 1 + innerRadius * xCurr;
    double startInnerY = 1 + innerRadius * yCurr;

    // 构造闭合的环形扇区路径
    slices += $"<g><path fill='{GetColor(i)}' d='M{startOuterX},{startOuterY} A1,1,0,{largeArcFlag},1,{endOuterX},{endOuterY} L{endInnerX},{endInnerY} A{innerRadius},{innerRadius},0,{largeArcFlag},0,{startInnerX},{startInnerY} Z'></path></g>"; 

    // 更新起始坐标为当前扇区结束角度的单位向量
    xCurr = endXY[0]; 
    yCurr = endXY[1]; 
}

效果验证

用你提供的数据集45, 20, 2, 14, 24,修正后的代码会生成正确的环形图,每个扇区都是闭合的同心圆弧区域,不会出现路径错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:37:25