svg实现复杂饼图和雷达图的关键在于路径计算与极坐标转换:饼图依赖的a指令精确绘制扇形,需处理起始角、large-arc-flag和sweep-flag;雷达图通过cos/sin公式将数据映射为多边形顶点坐标,用绘制网格与数据层,并支持无障碍、响应式及图例联动等扩展能力。

SVG 能实现复杂饼图和雷达图,但关键在于“复杂”二字——它不指视觉花哨,而指数据维度高、交互多、响应式强、需导出或无障碍支持。Canvas 更适合动态渲染和性能敏感场景;SVG 的优势在语义性、可访问性、缩放保真和 DOM 可控性。下面分两类讲清核心实现逻辑与实操要点。
SVG 饼图:路径计算 + 弧线指令是核心
SVG 没有原生 <pie></pie> 标签,所有扇形都靠 <path></path> 的 A(椭圆弧)指令绘制。难点不在画圆,而在精确控制起点、扫角方向、大弧/小弧标志。
- 每个扇区角度 = 对应值 ÷ 总和 × 360°,再转为弧度参与计算
- 起始角从 0 开始累加,终止角 = 起始角 + 当前扇区弧度
-
A rx ry x-axis-rotation large-arc-flag sweep-flag x y中:
—large-arc-flag决定走优弧还是劣弧(通常用 0)
—sweep-flag控制顺时针(1)或逆时针(0),统一设为 1 可避免反向 - 推荐封装一个
getArcPath(cx, cy, r, startAngle, endAngle)函数,返回完整 d 字符串,避免手动拼接出错 - 环形图只需叠加两个同心圆路径:外圈用
stroke-width模拟环宽,内圈用<circle></circle>或透明<path></path>挖空
SVG 雷达图:极坐标转换 + 多边形填充
雷达图本质是正多边形嵌套+数据点连线。SVG 中不用 canvas 坐标系,而是直接用 <polygon></polygon> 或 <path></path> 描点,更易调试和样式控制。
- 每维轴角 =
2 * Math.PI / 维度数,第 i 个顶点角度 =i * 单轴角 - 点坐标公式:
x = cx + r * cos(θ),y = cy + r * sin(θ),注意 SVG 原点在左上,需偏移居中 - 网格层用多个
<polygon></polygon>绘制不同半径的正多边形(如 20%、40%、60%、80%、100%),配合stroke-opacity区分层级 - 数据层用单个
<polygon></polygon>连接归一化后的各维坐标,fill 用半透色;标签用<text></text>定位在顶点外侧,结合text-anchor和dominant-baseline对齐 - 悬停交互直接给
<polygon></polygon>绑定onmouseover,或用 CSS class +:hover控制 stroke 和 opacity,无需重绘
真正影响“复杂度”的不是画法,而是扩展能力
纯 SVG 实现饼图或雷达图,一旦需要以下功能,就不再是“手写几行 path”的事:
- 数据动态更新:需清除旧
<path></path>或<polygon></polygon>,重新生成并插入 DOM —— 手动管理节点比 Canvas 的 clearRect() 更繁琐 - 无障碍支持:为每个扇区添加
role="region"、aria-label和aria-valuenow,雷达图还需描述轴含义与数值范围 - 打印适配:确保 viewBox 和单位一致,禁用依赖屏幕像素的 stroke-width,优先用 em 或 %
- 响应式缩放:必须用
viewBox+preserveAspectRatio,不能只靠 width/height 百分比 - 图例联动:点击图例项高亮对应扇区或雷达维度,需维护 DOM 元素与数据索引的映射关系
什么时候该放弃纯 SVG?
如果你的项目需要实时刷新、动画过渡、上百数据点、服务端导出 PNG、或快速对接 BI 系统,别硬扛 SVG 手写逻辑。Chart.js(底层 Canvas)、ECharts(Canvas/SVG 双模)或 D3.js(SVG 为主)会更稳。SVG 适合你掌控每一像素、需 SEO 友好、要 PDF 导出、或团队强调可访问性标准的场景。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











