canvas绘制饼图和柱状图核心是准备数据与用2d上下文api逐层绘制:先动态创建canvas并适配容器尺寸,再分别按扇形角度累加或坐标比例映射实现图形渲染,并可封装函数、响应式重绘及添加交互。

网页端用 Canvas 绘制饼图和柱状图,核心是两步:准备数据 + 用 2D 上下文 API 逐层绘制。不需要引入 ECharts 等库,纯原生 JS 就能实现,适合轻量需求或教学理解底层逻辑。
准备画布与绘图环境
先在 HTML 中放一个容器(如 div),再用 JS 动态创建 canvas 并挂载进去,避免硬编码宽高导致响应问题:
- 获取父容器元素,读取其
offsetWidth和offsetHeight - 创建
canvas元素,设置其width和height属性为实际像素值(注意:不是 CSS 宽高) - 调用
getContext('2d')获取绘图上下文ctx - 可选:用
ctx.scale或ctx.translate调整坐标原点,比如把原点移到左下角,更符合数学习惯
绘制饼图的关键步骤
饼图本质是多个首尾相接的扇形,每个扇形角度 = (数值 / 总和) × 360°,需从 0 弧度开始累加绘制:
- 先算出所有数据的总和,再遍历每项计算起始角和终止角(单位用弧度)
- 用
ctx.beginPath()→ctx.arc(圆心x, 圆心y, 半径, 起始弧度, 终止弧度)→ctx.closePath()描边/填充 - 为区分区块,每块用不同颜色;可用
ctx.fillStyle设置填充色,ctx.fill()执行填充 - 如需文字标注,用
ctx.fillText(text, x, y),位置可按扇形中点角度和半径估算
绘制柱状图的核心逻辑
柱状图重点在坐标系布局和比例换算,X 轴对齐类别,Y 轴映射数值大小:
- 预留左右、上下边距(如
padding: 40),定义绘图区域有效宽高 - X 方向:根据类别数量均分间距,每根柱子的中心横坐标 = 左边距 + i × 单位宽度
- Y 方向:需确定最大值,将数据值线性映射到像素高度,公式为:
barHeight = (value / maxValue) × 可用高度 - 柱子矩形用
ctx.fillRect(x, y, width, height),注意 Canvas 的 y 轴向下增长,所以柱子顶点 y = 原点 y − barHeight - 建议绘制 X/Y 轴线、刻度线、文字标签(如
ctx.textAlign = 'center')、网格线提升可读性
增强实用性的小技巧
让图表不只是“画出来”,还能用得上:
- 封装成函数或类,接收
containerId、data、type('pie'/'bar')等参数,复用性更高 - 监听窗口 resize,重新获取容器尺寸并重绘,保证响应式
- 添加简单交互:比如鼠标移入柱子时高亮、点击某扇形时弹出详情(用
ctx.isPointInPath()或手动计算范围) - 支持负数柱状图:Y 轴零线不在底部,而居中;高度方向需分正负处理











