【Vue3 + SVG 饼图组件单一数据类别显示异常问题】
问题描述在项目统计功能模块中章节状态分布饼图存在显示异常问题❌单状态场景当统计数据仅包含单个状态类别时饼图显示错误✅多状态场景当统计数据包含两个及以上状态类别时饼图显示正常问题定位1. 代码分析问题出现在src/views/ProjectStatsDashboard.vue文件中的饼图路径计算逻辑。关键代码片段修复前constpieChartPathscomputed((){// ... 省略其他代码if(Math.abs(angle-360)0.01){// Full circle - handle edge case with two semicirclesreturn{status:item.status,d:M${pieChartCenter}${pieChartCenter-pieChartRadius}A${pieChartRadius}${pieChartRadius}0 1 1${pieChartCenter-0.01}${pieChartCenter-pieChartRadius}A${pieChartRadius}${pieChartRadius}0 1 1${pieChartCenter}${pieChartCenter-pieChartRadius},fill:item.color,};}// ...});2. 根本原因分析当只有单一数据类别时角度计算为360度完整圆原有的全圆SVG路径绘制逻辑使用了两个半圆的组合方式M cx cy A r r 0 1 1 cx-0.01 cy A r r 0 1 1 cx cy这种方式在某些SVG渲染引擎中可能导致渲染异常原因是两个连续的A命令在起点和终点非常接近时可能产生路径重叠或渲染冲突微小的浮点精度误差如cx - 0.01可能导致路径闭合不完整修复方案修复内容修改全圆路径的绘制方式从双半圆组合改为标准圆形路径指令if(Math.abs(angle-360)0.01){// Full circle - use a simple circle pathreturn{status:item.status,d:M${pieChartCenter}${pieChartCenter}m 0 -${pieChartRadius}a${pieChartRadius}${pieChartRadius}0 1 1 0${pieChartRadius*2}a${pieChartRadius}${pieChartRadius}0 1 1 0 -${pieChartRadius*2},fill:item.color,};}修复原理新的路径指令解析命令参数说明M cx cy移动到圆心设置起点为圆心m 0 -r相对移动到顶部从圆心向上移动半径距离a r r 0 1 1 0 2r顺时针画下半圆从顶部顺时针画到底部a r r 0 1 1 0 -2r顺时针画上半圆从底部顺时针回到顶部这种方式确保了路径从圆心开始通过相对移动定位到起始点使用两个a命令分别绘制上下半圆形成完整闭合路径避免了浮点精度问题路径端点精确重合完整修复代码// src/views/ProjectStatsDashboard.vueconstpieChartPathscomputed((){consttotaltotalChapters.value;if(total0){return[];}letcurrentAngle-90;returnpieChartData.value.filter((item)item.count0).map((item){constangle(item.count/total)*360;conststartAnglecurrentAngle;constendAnglecurrentAngleangle;currentAngleendAngle;conststartRad(startAngle*Math.PI)/180;constendRad(endAngle*Math.PI)/180;constx1pieChartCenterpieChartRadius*Math.cos(startRad);consty1pieChartCenterpieChartRadius*Math.sin(startRad);constx2pieChartCenterpieChartRadius*Math.cos(endRad);consty2pieChartCenterpieChartRadius*Math.sin(endRad);constlargeArcangle180?1:0;if(Math.abs(angle-360)0.01){// Full circle - use a simple circle pathreturn{status:item.status,d:M${pieChartCenter}${pieChartCenter}m 0 -${pieChartRadius}a${pieChartRadius}${pieChartRadius}0 1 1 0${pieChartRadius*2}a${pieChartRadius}${pieChartRadius}0 1 1 0 -${pieChartRadius*2},fill:item.color,};}return{status:item.status,d:M${pieChartCenter}${pieChartCenter}L${x1}${y1}A${pieChartRadius}${pieChartRadius}0${largeArc}1${x2}${y2}Z,fill:item.color,};});});验证测试测试场景场景测试数据预期结果实际结果空数据[]显示暂无章节提示✅ 通过单状态[{status: draft, count: 5}]显示完整圆形中心显示5章节✅ 通过双状态[{status: draft, count: 3}, {status: final, count: 2}]显示两个扇形比例正确✅ 通过多状态5种状态各1章显示5个扇形比例正确✅ 通过构建验证npmrun build# ✅ 构建成功无编译错误总结问题根源SVG全圆路径绘制方式不当导致单一数据类别场景下饼图无法正确渲染。修复要点使用标准SVG圆形路径指令替代双半圆组合方式确保路径端点精确重合避免浮点精度问题保持代码简洁性和可读性经验教训SVG路径绘制需要特别注意边界情况如完整圆当使用Arc命令绘制闭合路径时应确保起点和终点精确匹配测试时应覆盖所有边界场景空数据、单数据、多数据修复时间2026年5月8日修复位置src/views/ProjectStatsDashboard.vue第136-145行影响范围章节状态分布饼图组件参考链接SVG Path 规范SVG Arc 命令详解