项目概述与架构总览
深入了解 @antv/g -- AntV 底层高性能 2D/3D 可视化渲染引擎的设计理念、整体架构与核心组成。本模块将从宏观视角建立对整个项目的完整认知。
@antv/g 是什么
@antv/g 是蚂蚁集团 AntV 可视化技术栈的底层渲染引擎。它为上层产品(如 G2、G6、S2、L7 等)提供一致且高性能的 2D / 3D 图形渲染能力,能够适配 Web 端所有底层渲染 API:
Canvas2D
基于 HTML5 Canvas 的 2D 上下文渲染,兼容性最好,适合大多数 2D 场景。
SVG
基于矢量图形标准的渲染器,支持 DOM 操作和 CSS 样式,天然支持无损缩放。
WebGL
基于 GPU 的高性能渲染,支持 WebGL 1/2,可处理大规模数据可视化。
WebGPU
下一代 GPU API,提供更低开销的渲染和 GPGPU 计算能力。
CanvasKit (Skia)
基于 Google Skia 引擎的 WASM 渲染器,支持 Lottie 动画、粒子效果等。
服务端渲染
支持 Node.js 环境的服务端渲染,用于生成图片和 PDF 等离屏场景。
核心定位:G 不是一个图表库,也不是一个可视化框架 -- 它是图表库和框架的底层引擎。就像浏览器中 DOM 和渲染引擎的关系,G 提供了图形世界的 "DOM" 和渲染能力。
快速上手示例
以下代码展示了 G 的基本用法 -- 创建画布、添加图形、绑定事件:
// 1. 安装依赖
// npm install @antv/g @antv/g-canvas
import { Circle, Canvas, CanvasEvent } from '@antv/g';
import { Renderer as CanvasRenderer } from '@antv/g-canvas';
// 2. 创建画布,指定渲染器
const canvas = new Canvas({
container: 'container',
width: 500,
height: 500,
renderer: new CanvasRenderer(),
});
// 3. 创建图形(API 兼容 DOM Element)
const circle = new Circle({
style: {
cx: 100,
cy: 100,
r: 50,
fill: '#1890ff',
stroke: '#0050b3',
lineWidth: 3,
},
});
// 4. 画布就绪后添加图形
canvas.addEventListener(CanvasEvent.READY, () => {
canvas.appendChild(circle); // 等同 DOM 的 appendChild
// 5. 绑定事件(API 兼容 DOM Event)
circle.addEventListener('click', () => {
circle.style.fill = '#52c41a';
});
});TypeScript
API 亮点:注意 appendChild、addEventListener、style 这些方法 -- 如果你熟悉 DOM API,就已经会用 G 了!这是刻意为之的设计。
设计理念
1. DOM 兼容 API
G 的图形和事件系统兼容 DOM Element 和 Event API。每个图形对象(如 Circle、Rect)都像一个 DOM 节点,支持 appendChild、removeChild、querySelector 等方法。事件系统兼容 addEventListener,支持冒泡、捕获、阻止传播等完整的事件流。
这意味着 Web 生态中大量依赖 DOM API 的库可以几乎零成本接入 G,例如:
- D3.js -- 数据驱动的可视化库,可直接操作 G 的场景图
- Hammer.js -- 手势识别库,可直接绑定到 G 的图形对象
- interact.js -- 拖拽交互库
2. Web Animations API 兼容
动画系统兼容 Web Animations API,使用 element.animate() 来创建动画,支持关键帧、缓动函数、播放控制等:
// 和浏览器原生 Web Animations API 一致
circle.animate(
[
{ transform: 'scale(1)', fill: '#1890ff' },
{ transform: 'scale(1.5)', fill: '#f5222d' },
],
{
duration: 1000,
iterations: Infinity,
direction: 'alternate',
easing: 'ease-in-out',
}
);TypeScript
3. 渲染后端无关
核心 API 层与渲染实现完全解耦。通过切换渲染器,同一套业务代码可以运行在 Canvas2D、SVG、WebGL、WebGPU 等不同环境中,无需修改任何逻辑:
import { Renderer as CanvasRenderer } from '@antv/g-canvas';
import { Renderer as SVGRenderer } from '@antv/g-svg';
import { Renderer as WebGLRenderer } from '@antv/g-webgl';
// 只需更换渲染器,其他代码完全不变
const canvas = new Canvas({
container: 'container',
width: 600,
height: 400,
renderer: new CanvasRenderer(), // 换成 SVGRenderer() 或 WebGLRenderer() 即可
});TypeScript
4. 插件化架构
G 采用高度插件化的架构,渲染器本身就是一组插件的集合。用户可以按需引入拾取、交互、物理引擎、布局引擎等插件,避免不必要的包体积膨胀。
设计权衡:DOM 兼容 API 虽然降低了学习成本和生态对接成本,但也意味着引擎需要维护一套完整的类 DOM 树结构(场景图),这在超大规模数据场景下会有内存开销。G 提供了 g-lite 精简版来应对此场景。
整体架构图
下图展示了 G 的分层架构,从上层应用到底层渲染 API 的完整链路:
架构分层说明
| 层级 | 包名 | 职责 |
|---|---|---|
| 应用层 | G2, G6, S2, L7 等 | 使用 G 引擎的上层可视化产品 |
| 完整包 | @antv/g |
= g-lite + Web Animations API + 高级相机 + 扩展组件 |
| 核心层 | @antv/g-lite |
场景图、事件系统、CSS 属性解析、图形对象、渲染器抽象 |
| 渲染器 | g-canvas / g-svg / g-webgl / ... |
具体的渲染实现,每种包含一组渲染/拾取/交互插件 |
| 插件层 | g-plugin-* |
可插拔的功能扩展:3D、拖拽、物理引擎、布局、GPGPU 等 |
| 基础设施 | @antv/g-math |
几何计算工具(贝塞尔曲线、路径计算等) |
包结构总览
G 采用 Monorepo 架构(基于 pnpm workspace),所有包位于 packages/ 目录下。截至当前版本共有 32 个子包,可分为以下几类:
核心包
| 包名 | 版本 | 说明 |
|---|---|---|
@antv/g |
v6.3.1 | 完整版核心包,包含 g-lite + 动画 + 高级相机 + 扩展组件 |
@antv/g-lite |
v2.7.0 | 精简核心,场景图 / 事件 / CSS 属性 / 图形对象 / 渲染器抽象 |
@antv/g-math |
v3.1.0 | 几何数学工具库(贝塞尔曲线、线段、弧线等运算) |
渲染器包
| 包名 | 版本 | 渲染技术 | 适用场景 |
|---|---|---|---|
@antv/g-canvas |
v2.2.0 | Canvas2D | 通用 2D 场景,兼容性最好 |
@antv/g-svg |
v2.1.1 | SVG | 需要 DOM 操作、CSS 样式、无损缩放 |
@antv/g-webgl |
v2.1.1 | WebGL 1/2 | 大数据量、需 GPU 加速的 2D/3D 场景 |
@antv/g-webgpu |
v2.1.1 | WebGPU | 下一代 GPU 渲染 + GPGPU 计算 |
@antv/g-canvaskit |
v1.1.1 | CanvasKit (Skia) | 高品质渲染、Lottie 动画、粒子效果 |
@antv/g-mobile-canvas |
- | Canvas2D (Mobile) | 移动端 Canvas 渲染适配 |
@antv/g-mobile-svg |
- | SVG (Mobile) | 移动端 SVG 渲染适配 |
@antv/g-mobile-webgl |
- | WebGL (Mobile) | 移动端 WebGL 渲染适配 |
插件包
| 包名 | 类别 | 说明 |
|---|---|---|
g-plugin-device-renderer |
渲染 | 基于 GPUDevice 的统一渲染实现(WebGL/WebGPU 共用) |
g-plugin-3d |
渲染 | 3D 扩展能力(Mesh、Geometry、Material 等) |
g-plugin-rough-canvas-renderer |
渲染 | 使用 rough.js 实现手绘风格渲染(Canvas2D 版) |
g-plugin-rough-svg-renderer |
渲染 | 使用 rough.js 实现手绘风格渲染(SVG 版) |
g-plugin-dragndrop |
交互 | 基于 PointerEvents 的拖放功能 |
g-plugin-control |
交互 | 3D 场景的相机交互控制(旋转/缩放/平移) |
g-plugin-gesture |
交互 | 手势识别插件 |
g-plugin-annotation |
交互 | 标注功能插件 |
g-plugin-box2d |
物理 | Box2D 物理引擎集成 |
g-plugin-matterjs |
物理 | Matter.js 物理引擎集成 |
g-plugin-physx |
物理 | NVIDIA PhysX 物理引擎集成 |
g-plugin-yoga |
布局 | 基于 Yoga 引擎的 Flex 布局能力 |
g-plugin-gpgpu |
计算 | 基于 WebGPU 的通用 GPU 计算(GPGPU) |
g-plugin-css-select |
选择器 | CSS 选择器查询场景图节点 |
g-plugin-a11y |
无障碍 | 可访问性(Accessibility)支持 |
g-plugin-zdog-canvas-renderer |
渲染 | Zdog 风格伪 3D 渲染(Canvas 版) |
g-plugin-zdog-svg-renderer |
渲染 | Zdog 风格伪 3D 渲染(SVG 版) |
工具与扩展包
| 包名 | 说明 |
|---|---|
@antv/g-shader-components |
可复用的 GLSL Shader 片段集合 |
@antv/g-lottie-player |
Lottie 动画播放器 |
@antv/g-web-components |
基于 WebComponents 的声明式用法 |
@antv/react-g |
React 渲染器绑定 |
@antv/g-devtool |
浏览器开发者工具(场景图检查器) |
核心包 vs 渲染器 vs 插件的关系
理解三者之间的依赖关系是掌握 G 架构的关键。以下用依赖流方向来说明:
数学工具
核心精简
完整核心
// 依赖关系(箭头表示 "依赖于")
// 核心链路:
@antv/g ─────── 依赖 ──▶ @antv/g-lite ─── 依赖 ──▶ @antv/g-math
// 渲染器 依赖 核心:
@antv/g-canvas ─── 依赖 ──▶ @antv/g-lite + @antv/g-math
@antv/g-svg ─── 依赖 ──▶ @antv/g-lite
@antv/g-webgl ─── 依赖 ──▶ @antv/g-lite + g-plugin-device-renderer
@antv/g-webgpu ─── 依赖 ──▶ @antv/g-lite + g-plugin-device-renderer
// 插件 依赖 核心(不依赖具体渲染器):
g-plugin-3d ─── 依赖 ──▶ @antv/g-lite + g-plugin-device-renderer
g-plugin-dragndrop ─── 依赖 ──▶ @antv/g-lite
g-plugin-control ─── 依赖 ──▶ @antv/g-lite依赖关系
关键设计原则
核心包是抽象层
g-lite 定义了所有图形对象、事件、渲染器的抽象接口(AbstractRenderer),不包含任何渲染实现。
渲染器是插件集合
每个渲染器(如 g-canvas)实际上是将多个插件打包在一起:canvas-renderer + canvas-picker + dom-interaction。
插件不依赖渲染器
插件只依赖核心抽象层,因此可以跨渲染器复用。比如拖拽插件在 Canvas、SVG、WebGL 中都能工作。
渲染器的插件组成
以 @antv/g-canvas 为例,它实际上注册了以下内置插件:
// g-canvas 渲染器内部组成(简化示意)
class Renderer extends AbstractRenderer {
constructor() {
super();
// 内置插件集
this.registerPlugin(new CanvasRendererPlugin()); // 渲染
this.registerPlugin(new CanvasPickerPlugin()); // 拾取(点击检测)
this.registerPlugin(new DOMInteractionPlugin()); // DOM 事件绑定
this.registerPlugin(new HTMLRendererPlugin()); // HTML 元素渲染
}
}
// 用户可以额外注册插件
const renderer = new Renderer();
renderer.registerPlugin(new DragndropPlugin()); // 添加拖拽能力
renderer.registerPlugin(new A11yPlugin()); // 添加无障碍支持TypeScript
技术栈
| 技术 | 用途 | 说明 |
|---|---|---|
| TypeScript | 主要开发语言 | 全量 TypeScript 编写,提供完整类型定义 |
| gl-matrix | 矩阵与向量运算 | 高性能线性代数库,用于变换矩阵计算 |
| eventemitter3 | 事件发射器 | 轻量级事件系统基础设施 |
| pnpm workspace | Monorepo 管理 | 管理 32+ 子包的依赖与构建 |
| Rollup | 打包构建 | 每个子包独立 rollup 构建,输出 CJS/ESM/UMD |
| Jest | 测试框架 | 单元测试 + 视觉回归测试 |
| Changesets | 版本管理 | Monorepo 下的独立版本发布与变更日志 |
| Vite | 开发服务器 | 本地 demo 预览与开发 |
| @antv/g-device-api | GPU 设备抽象 | 统一 WebGL/WebGPU 的 GPU 设备 API |
g-lite 核心源码结构
@antv/g-lite 是整个引擎的心脏,其源码按职责划分为以下模块:
packages/g-lite/src/
├── Canvas.ts // 画布 - 顶层容器,管理渲染循环
├── AbstractRenderer.ts // 渲染器抽象基类,定义插件注册机制
├── global-runtime.ts // 全局运行时配置
├── camera/
│ ├── Camera.ts // 相机实现(正交/透视投影)
│ └── Landmark.ts // 相机地标(视角保存/恢复)
├── components/
│ ├── Transform.ts // 变换组件(位移/旋转/缩放矩阵)
│ ├── Renderable.ts // 可渲染组件(包围盒/脏标记)
│ ├── Cullable.ts // 裁剪组件(视锥剔除)
│ ├── Sortable.ts // 排序组件(渲染顺序/zIndex)
│ └── Geometry.ts // 几何组件
├── css/
│ ├── CSS.ts // CSS 属性解析引擎
│ ├── StyleValueRegistry.ts // 样式值注册表
│ ├── cssom/ // CSS 对象模型(颜色、渐变、关键字等)
│ ├── parser/ // 属性值解析器(颜色/尺寸/变换/路径等)
│ └── properties/ // 各 CSS 属性的处理器(18 个)
├── display-objects/
│ ├── DisplayObject.ts // 所有图形的基类
│ ├── Circle.ts // 圆
│ ├── Ellipse.ts // 椭圆
│ ├── Rect.ts // 矩形
│ ├── Line.ts // 线段
│ ├── Path.ts // 路径
│ ├── Polygon.ts // 多边形
│ ├── Polyline.ts // 折线
│ ├── Text.ts // 文本
│ ├── Image.ts // 图片
│ ├── HTML.ts // HTML 元素
│ ├── Group.ts // 分组容器
│ └── CustomElement.ts // 自定义元素
├── dom/
│ ├── Node.ts // DOM Node 接口实现
│ ├── Element.ts // DOM Element 接口实现
│ ├── Document.ts // DOM Document 接口实现
│ ├── EventTarget.ts // 事件目标基类
│ ├── FederatedEvent.ts // 联合事件(跨渲染器统一)
│ ├── FederatedPointerEvent.ts // 指针事件
│ ├── FederatedMouseEvent.ts // 鼠标事件
│ └── MutationObserver.ts // DOM 变更观察器
└── plugins/
├── EventPlugin.ts // 事件处理插件
├── DirtyCheckPlugin.ts // 脏检查优化插件
├── CullingPlugin.ts // 视锥剔除插件
└── PrepareRendererPlugin.ts // 渲染准备插件目录结构
与其他图形库的对比
为了更好地理解 G 的定位,我们将它与其他流行的 Web 图形库进行对比:
| 特性 | @antv/g | PixiJS | Fabric.js | Konva | Three.js |
|---|---|---|---|---|---|
| 定位 | 2D/3D 渲染引擎 | 2D 渲染引擎 | Canvas 绘图库 | Canvas 框架 | 3D 渲染引擎 |
| DOM 兼容 API | 完全兼容 | 部分 | 不兼容 | 不兼容 | 不兼容 |
| 多渲染后端 | 6 种 | Canvas + WebGL | 仅 Canvas | 仅 Canvas | WebGL + WebGPU |
| SVG 渲染 | 支持 | 不支持 | SVG 解析 | 不支持 | 不支持 |
| 3D 支持 | 插件扩展 | 不支持 | 不支持 | 不支持 | 原生支持 |
| GPGPU | WebGPU | 不支持 | 不支持 | 不支持 | 有限支持 |
| CSS 属性系统 | 完整实现 | 不支持 | 不支持 | 不支持 | 不支持 |
| D3 生态兼容 | 原生兼容 | 需适配 | 需适配 | 需适配 | 需适配 |
| 插件系统 | 17+ 插件 | 有 | 有限 | 有限 | 丰富生态 |
| 物理引擎 | 3 种集成 | 不内置 | 不支持 | 不支持 | 需第三方 |
| 场景图 | DOM 树结构 | 容器树 | 扁平结构 | 层/组结构 | Object3D 树 |
| 语言 | TypeScript | TypeScript | JavaScript | TypeScript | JavaScript |
核心差异化:G 的最大特色在于 DOM 兼容的 API 设计和 多渲染后端支持。这两个特性使得它能够无缝对接 Web 生态(D3、手势库等),同时在不同平台和设备上选择最佳渲染方案。而 Three.js 专注 3D,PixiJS 专注 2D 高性能渲染,各有侧重。
G 的最佳适用场景
- 企业级数据可视化 -- 图表引擎(G2)、图分析引擎(G6)等产品的底层
- 需要多渲染后端的场景 -- 同一套代码在桌面端用 Canvas、移动端用 WebGL、服务端渲染
- 与 D3 生态深度集成 -- 利用 DOM 兼容 API,直接复用 D3 的布局和数据处理能力
- 需要 2D + 3D 混合的可视化场景 -- 通过插件扩展 3D 能力
- 需要 GPU 加速计算的图分析场景 -- GPGPU 插件
本模块小结
身份定位
G 是 AntV 的底层渲染引擎,为上层图表/图分析产品提供一致的 2D/3D 图形渲染能力。
设计哲学
DOM 兼容 API + 多渲染后端 + 插件化架构,降低学习成本,最大化复用 Web 生态。
架构分层
g-math (数学) -> g-lite (核心) -> g (完整) -> 渲染器 -> 插件,层次清晰、职责分明。
技术选型
TypeScript + gl-matrix + pnpm monorepo + Rollup 构建,32+ 子包协同工作。
下一步:在下一模块中,我们将深入 G 最核心的数据结构 -- 场景图(Scene Graph),了解 G 如何用类 DOM 的树结构来组织和管理图形对象。