canvas饼图核心是将数据按比例转为弧度并用arc()绘制扇形:先累加计算起始/终止弧度,再通过beginpath→moveto→arc→closepath→fill绘制闭合扇形,最后添加居中百分比标签与悬停高亮交互。

Canvas 饼图的核心在于:把每个数据项转换为对应的角度(占 360° 的比例),再用 arc() 绘制扇形,并通过颜色、标签和高亮等增强可读性。
计算角度与起始/终止弧度
饼图本质是圆的分段,每项占比 = 值 ÷ 总和,对应角度 = 占比 × 360°,转为弧度需乘以 Math.PI / 180。关键点是扇形必须首尾相接,所以需累积角度确定每个扇形的起始弧度:
- 初始化
startAngle = 0 - 对每一项:计算
angle = (value / total) * 2 * Math.PI - 调用
ctx.arc(cx, cy, radius, startAngle, startAngle + angle) - 更新
startAngle += angle
绘制填充扇形与描边分隔
为避免扇形间重叠或留缝,推荐先清空路径、再逐个闭合绘制:
- 每次循环前调用
ctx.beginPath() - 用
ctx.moveTo(cx, cy)移动到圆心,再调用ctx.arc(...)画弧 - 紧接着
ctx.closePath()连回圆心,形成闭合扇形 -
ctx.fill()填充,ctx.stroke()可选加细白边提升视觉分离感
添加文字标签与百分比标注
标签应放在扇形中点方向上,距离圆心约 70%–80% 半径处,避免重叠:
- 中点弧度 =
startAngle + angle / 2 - x =
cx + Math.cos(midAngle) * labelRadius - y =
cy + Math.sin(midAngle) * labelRadius - 用
ctx.fillText(`${(ratio * 100).toFixed(1)}%`, x, y)居中显示(配合textBaseline = 'middle'和textAlign = 'center')
支持交互:鼠标悬停高亮某一块
监听 mousemove,将鼠标坐标反算极角和半径,判断落在哪个扇形区间内:
- 计算相对圆心偏移:
dx = x - cx,dy = y - cy - 极角:
angle = Math.atan2(dy, dx)(注意:Canvas 0° 在右,且atan2返回 [-π, π],需统一转为 [0, 2π)) - 半径:
dist = Math.sqrt(dx*dx + dy*dy),确保在饼图有效半径内 - 遍历扇形角度区间,若
angle ∈ [start, start+angle),则重绘该扇形(如放大半径或加深颜色)
不复杂但容易忽略:角度累加需用浮点高精度,最后扇形可能因舍入误差未闭合,建议对最后一项强制设为 2*Math.PI - accumulated 来兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











