JavaScript绘图需依场景选Canvas(快但交互难)、SVG(矢量可交互)、Chart.js(省事但定制弱)或D3.js(高度定制但学习成本高),核心在于理解坐标系、上下文获取、样式设置时机及数据驱动更新机制。

JavaScript 本身没有内置绘图 API,但可以通过 Canvas 或 SVG 原生能力绘制图形;图表则需依赖第三方库(如 Chart.js、D3.js)或手动用 Canvas/SVG 实现。
用 canvas 绘制基础图形要先获取上下文
直接操作 元素不会自动绘图,必须调用 getContext('2d') 获取 2D 渲染上下文,所有绘图操作都通过它完成。漏掉这步,后续调用 fillRect、strokeLine 等方法会静默失败。
-
getContext('2d')返回CanvasRenderingContext2D对象,它是绘图的唯一入口 - 修改颜色、线宽等样式必须在绘图调用前设置,例如
ctx.fillStyle = '#f00'要写在ctx.fillRect()之前 - 坐标原点在左上角,x 向右递增,y 向下递增——和数学坐标系相反,容易画错位置
- 如果 canvas 没设 width/height 属性(不是 CSS 宽高),默认为 300×150,缩放后图像会模糊
用 SVG 绘图更适合矢量图形与交互
SVG 是基于 XML 的标记语言,每个图形元素(如 、)都是真实 DOM 节点,可绑定事件、用 CSS 控制样式、支持原生缩放不失真。
- 动态创建 SVG 图形建议用
document.createElementNS('http://www.w3.org/2000/svg', 'circle'),不能用普通createElement -
的d属性语法紧凑但难读,推荐用Path2D对象封装路径逻辑,再传给ctx.stroke(path)或svg.appendChild() - SVG 坐标系默认原点在左上角,但可通过
平移整个组,比 canvas 手动算偏移更直观
Chart.js 画图表最省事,但得避开常见配置坑
Chart.js 封装了 canvas 绘图逻辑,只需传入数据和配置对象。但它对容器尺寸、响应式、插件加载顺序很敏感,配错就白屏或图表不渲染。
立即学习“Java免费学习笔记(深入)”;
- 确保父容器有明确宽度(如
width: 400px),否则responsive: true可能计算出 0 高度 - 使用
plugins(如 tooltip、legend)时,必须在Chart.register()中显式注册,新版不再自动导入 - 时间轴(
time类型)需要date-fns或moment.js支持,否则报错Unable to determine axis type - 更新数据别直接改
chart.data.labels,要用chart.data.labels = newLabels; chart.update(),否则视图不刷新
D3.js 适合高度定制图表,但学习成本集中在数据映射
D3 的核心是 selection.data().enter().append() 这套数据驱动 DOM 更新机制,不是“画图 API”,而是“把数据映射成 SVG 元素”的工具链。新手常误以为它像 Chart.js 那样填数据就能出图。
- 先用
d3.scaleLinear()或d3.scaleBand()把原始数值转为像素坐标,这是最易卡住的一步 -
enter()处理新增数据,update()处理已有元素,exit()处理删除——三者缺一不可,否则图表状态错乱 - 过渡动画(
.transition().duration(300))必须在attr()或style()调用前链式调用,顺序反了无效 - 大量数据下,避免用
d3.selectAll('circle').data(...).enter()...全量重绘,应只更新变化部分
真正难的不是“怎么画一个圆”,而是“怎么让图形随数据实时、平滑、可访问地更新”。Canvas 快但难交互,SVG 灵活但节点多时性能下降,Chart.js 省事但定制边界明显,D3 强大但调试成本高——选哪个,取决于你愿为控制力付出多少调试时间。











