html canvas 实现折线图和柱状图的核心是数据到画布坐标的映射、原生 api 绘制及坐标计算,需处理 y 轴翻转、批量坐标预计算、局部重绘、自动布局、响应式适配与交互封装。

用 HTML Canvas 实现折线图和柱状图,核心是把数据映射到画布坐标、用原生 API 绘制路径或矩形,并做好坐标计算、样式控制和更新逻辑。它不依赖第三方库,轻量可控,适合嵌入式、高频更新或定制化强的场景。
折线图:单路径批量绘制 + 坐标预计算
避免每帧重复算坐标、避免频繁调用 moveTo/lineTo 是性能关键:
- 数据加载后,立刻把所有 (value → canvasY) 批量转成像素坐标,存为
[x0,y0,x1,y1,...]平铺数组;y 要翻转(Canvas 原点在左上):canvasY = height - paddingBottom - scaleY * (value - minValue) - 绘图时只调一次
ctx.beginPath(),然后ctx.moveTo(x0, y0)起笔,后续全用ctx.lineTo(x1, y1)追加,最后ctx.stroke() - 开启硬件加速优化:
ctx.imageSmoothingEnabled = false,设ctx.lineCap = 'butt',线宽用奇数(如 1px 或 3px)提升清晰度 - 动态更新时,只重绘变化区域——比如滚动显示最近 60 个点,就只清掉最左一列 + 画最右新增点,不用全屏 clear
柱状图:按数据逐个绘制矩形 + 自动对齐布局
重点在柱子宽度、间距、Y 轴对齐和标签位置的自动适配:
- 先算出可用绘图宽度:
chartWidth = canvas.width - leftPad - rightPad,再均分或按比例分配每根柱子的barWidth - 柱高 =
(value / maxValue) * usableHeight,注意 Canvas Y 向下增长,所以矩形 y 坐标是originY - barHeight(originY 是 X 轴所在像素行) - 用
ctx.fillRect(x, y, width, height)画柱子,配合ctx.fillStyle设颜色;数值标签用ctx.fillText(value, x + width/2, y - 5)居中顶上 - 横坐标标签(如“1月”“2月”)放在柱子正下方,x 对齐柱中,y 固定在 originY + 20 左右,字体大小建议 12–14px 避免拥挤
共用基础:坐标系与响应式适配
两者都依赖稳定、可复用的绘图框架:
- 统一留白(padding):上下左右各设 30–50px,留出坐标轴、标题、图例空间
- X 轴和 Y 轴用
ctx.beginPath() + moveTo/lineTo + stroke()手动画,Y 轴刻度值可用循环生成并fillText标注 - 监听
window.resize,重新设置 canvas.width/height,并调用canvas.style.width = '100%'+canvas.style.height = 'auto',再按新尺寸重算缩放比例 - 数据为空或极值(如全零)时,加兜底逻辑:显示“暂无数据”文案,或自动调整 scale 避免除零
进阶提示:交互与复用封装
让图表真正可用,不止于“能画”:
- 鼠标 hover 柱子或折线点时,用
isPointInPath()或简易距离判断,高亮对应项并显示 tooltip(用临时 div 浮层) - 把绘图逻辑封装成类,例如
new LineChart(ctx, data, options),支持切换主题、导出 PNG(canvas.toDataURL('image/png')) - 多系列折线?每条线独立 path;多组柱状?横向分组或堆叠,调整 x 偏移即可;混合图表?先画柱、再叠加折线路径
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











