优先选用Chart.js、ApexCharts或uPlot等成熟图表库,而非直接用canvas/svg手写;Chart.js入门快但高频更新需禁动画,ApexCharts适配WebSocket,uPlot适合超大数据量;需注意DOM就绪、宽高设置、响应式配置、实时更新优化及无障碍支持。

用 canvas 或 svg 直接绘图不现实,优先选成熟图表库
HTML5 本身不提供图表绘制能力, 和 只是渲染容器,从零实现折线图、坐标轴、动画、响应式缩放,开发成本远超业务需求。真实项目中几乎没人手写——容易出错、难维护、不支持交互和导出。
推荐直接使用轻量级、无依赖的库:Chart.js(适合静态+简单动态)、ApexCharts(原生支持实时流数据)、uPlot(高性能时序图,10万点不卡)。它们都基于 或 封装,但暴露的是语义化 API。
-
Chart.js入门最快,但默认不支持毫秒级高频更新(需手动.update()+animation: false) -
ApexCharts的updateSeries()和addPoint()天然适配 WebSocket 推送场景 - 若数据点超 5 万/秒,别用
Chart.js,uPlot的增量渲染更稳
Chart.js 嵌入 HTML5 页面的最小可行步骤
不需要构建工具,CDN 引入即可运行。关键是 DOM 存在后再初始化,且 必须有明确宽高(CSS 设置会模糊)。
-
responsive: false必须设,否则宽高会被重置导致渲染异常 - 标签名(
labels)和数据(data)必须同长度,否则图表空白不报错 - 修改数据后调用
chart.data.datasets[0].data.push(newVal),再执行chart.update()
实时更新时,setInterval 不等于“实时”,要防堆积
前端每秒接收 10 条数据,但 setInterval(() => { updateChart() }, 100) 可能因 JS 主线程阻塞导致多次回调合并执行,图表跳变或卡顿。
立即学习“前端免费学习笔记(深入)”;
- 用
requestAnimationFrame替代setInterval,让更新节奏对齐屏幕刷新率 - 数据缓存用数组队列,每次只取最新 N 个点(如
data.slice(-50)),避免内存膨胀 - 调用
chart.update('active')比chart.update()更快——跳过动画计算 - WebSocket 场景下,服务端推送前做采样(如每 200ms 合并一次均值),比前端硬扛更可靠
移动端缩放、暗色模式、无障碍这些细节容易被忽略
图表在 iPhone 上双指放大后无法恢复?夜间模式下线条看不见?屏幕阅读器读不出数据?这些问题不是“锦上添花”,而是上线后真实被反馈的缺陷。
-
options.plugins.legend.display = false在小屏上可提升可读性;用options.responsive = true+options.maintainAspectRatio = false才真正适配横竖屏切换 - 颜色别只靠 RGB,加图标或文字标注(
plugins.tooltip.callbacks.label可定制) - 给
加aria-label,并在options.plugins.title.text中写明图表含义,否则视障用户完全无法理解 - 暗色模式下,
background-color默认是透明的,canvas 背景会透出深色页底——显式设options.backgroundColor = '#ffffff'









