- 数据可视化
- 前端
- 图表库
【免费下载链接】G6
♾ A Graph Visualization Framework in JavaScript.
本指南围绕 G6 官方仓库中的 SSR 扩展包 packages/g6-ssr/README.md 展开,讲解如何在没有浏览器、没有 DOM的 Node.js 服务端环境中完成图可视化渲染,并将结果导出为 PNG、JPEG、SVG、PDF 等文件或内存 Buffer。读完本文,你将掌握@antv/g6-ssr的 JavaScript API 与 CLI 两种用法、输出格式控制、自定义扩展注册、渲染插件接入,以及其底层「双画布 + 延迟等待」的实现原理。
一、什么是 @antv/g6-ssr
G6 5.0 本身是面向浏览器的图可视化框架,画布渲染依赖 DOM 与浏览器能力。而@antv/g6-ssr是 G6 官方提供的SSR(Server-Side Rendering)扩展包,它的目标非常明确:在 Node.js 服务端完成 canvas 渲染,从而支持服务端生成图片、PDF、SVG 等静态产物。其定位在包描述中写得很清楚——"Support SSR for G6"(见 packages/g6-ssr/package.json)。
它适合以下典型场景:
- 服务端定时生成图报表快照,发给用户或嵌入邮件;
- CI / 构建流水线中把图导出为静态资源;
- 文档站或分享页需要预渲染的图预览图;
- 在不启动浏览器的轻量环境中批量渲染多张图。
从源码结构看,该包体积很小,核心只有四个文件:入口 src/index.ts(导出createGraph、createCanvas、register等 API)、图创建逻辑 src/graph.ts、画布创建逻辑 src/canvas.ts 以及类型定义 src/types.ts。它的核心思路是:用 node-canvas(canvas包)在 Node 中创建离屏画布,再通过@antv/g-canvas的 Renderer 驱动 G6 完成渲染,从而完全绕开浏览器环境。
二、安装与环境准备
npm install @antv/g6-ssr安装时需要注意以下两点前提(依据 packages/g6-ssr/package.json 的依赖声明):
- 该包依赖原生模块
canvas(node-canvas,版本 ^3),因此运行环境需要能编译或预装 node-canvas 的原生依赖(如 cairo 相关系统库)。如果使用 Docker,建议选择带 canvas 原生依赖的 Node 基础镜像。 - 依赖
@antv/g(^6.1.24)、@antv/g-canvas(^2.0.43)与@antv/g6(同仓库 workspace 版本),安装时会被一并拉取。
在 G6 仓库中该包位于 packages/g6-ssr,构建产物为 CJS 格式的dist/g6-ssr.cjs(main字段),并对外提供bin/g6-ssr.js命令行入口(构建配置见 rollup.config.mjs,其中fs、path、canvas被标记为 external)。
三、JavaScript API:createGraph 渲染与导出
3.1 基本用法
@antv/g6-ssr的核心入口是异步函数createGraph,它接收一份「几乎等同于 G6 Graph 配置」的 options,返回一个包装后的图实例:
import { createGraph } from '@antv/g6-ssr'; const graph = await createGraph({ width: 500, height: 500, imageType: 'png', // 或 'jpeg' data: { nodes: [{ id: '0' }, { id: '1' }], edges: [{ source: '0', target: '1' }], }, // 其他 G6 Graph 配置项,如 node / edge / layout / behaviors 等 }); graph.exportToFile('image'); // -> 生成 image.png graph.toBuffer(); // -> 得到图片 Buffer要点说明:
createGraph是异步函数,内部会等待graph.render()完成后再返回,因此调用处必须await;- 返回的实例不是 G6 原生
Graph,而是带exportToFile/toBuffer/toDataURL等导出方法的包装对象; - 配置项中
width、height为必填,其余绝大多数可透传 G6 的 GraphOptions(如data、node、edge、layout、autoFit、behaviors等)。
3.2 Options 参数速查表
依据 src/types.ts 的类型定义,Options在 G6GraphOptions基础上(排除renderer、container,这两个由内部接管)新增了以下字段:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
width/height | number | 必填 | 画布宽高,单位 px |
outputType | 'image' \| 'pdf' \| 'svg' | 'image' | 输出文件类型,决定导出的是图片、PDF 还是 SVG |
imageType | 'png' \| 'jpeg' | 'png' | 当outputType为'image'时的图片编码格式 |
waitForRender | number | 32(ms) | 渲染完成后额外等待的毫秒数,用于等待动画帧、异步图片等完成;代码实现见 src/graph.ts#L34 |
renderPlugins | RendererPlugin[] | [] | 透传给@antv/g-canvasRenderer 的渲染插件数组 |
background | string | 'white' | 画布背景色(在 canvas.ts 中解构设置,见 src/canvas.ts#L15) |
devicePixelRatio | number | 2 | 输出像素比,控制导出图清晰度(默认 2 倍) |
提示:
waitForRender在类型注释中标注为 16ms,但运行时默认值以 src/graph.ts#L34 的解构默认值32为准。
其余配置(如data、layout、node、edge、autoFit、behaviors等)与 G6 Graph 完全一致,完整的 G6 配置项说明可查阅仓库文档 site/docs/api/option.zh.md。
3.3 返回的 Graph 实例方法
createGraph返回对象实现了 src/types.ts#L39-L47 中定义的Graph接口:
| 方法 | 签名 | 说明 |
|---|---|---|
exportToFile | (file: string, meta?: MetaData) => void | 将渲染结果写入文件,自动补齐扩展名(见下文) |
toBuffer | (meta?: MetaData) => Buffer | 返回编码后的 Buffer,便于进一步处理(如上传 OSS、HTTP 响应) |
toDataURL | () => string | 返回 Data URL 字符串,可直接作为<img>的 src |
getGraph | () => G6Graph | 取回底层 G6 原生 Graph 实例 |
getCanvas | () => Canvas | 取回底层 node-canvas 实例 |
destroy | () => void | 销毁图实例,释放资源 |
其中MetaData类型为PdfConfig | PngConfig | JpegConfig(node-canvas 的编码配置),导出 PDF 时可传入title、author、creator、subject、keywords、creationDate、modDate等元信息(测试用例中的完整示例见 packages/g6-ssr/tests/graph.spec.ts#L215-L223)。
exportToFile的扩展名自动补齐逻辑在 src/graph.ts#L51-L56:如果传入的文件名已带对应扩展名则直接使用;否则若路径是已存在目录,则生成目录/image.<ext>;其余情况自动追加扩展名。
四、CLI:用 JSON 配置批量导出
@antv/g6-ssr通过bin字段暴露了g6-ssr命令(入口为 bin/g6-ssr.js,基于cac实现),核心子命令是export:
npx g6-ssr export -i [graph-options].json -o ./image参数说明:
| 参数 | 简写 | 说明 |
|---|---|---|
--input | -i | 存放 G6 配置项的 JSON 文件路径(必填) |
--output | -o | 导出文件路径 |
--type | -t | 文件类型,可选svg/pdf,不传则默认导出图片 |
命令还支持version子命令与--help。从 bin/g6-ssr.js#L24-L47 的源码可以看到 CLI 的处理流程:
- 校验
-i是否提供、文件是否存在,否则红色报错并退出; - 读取并
JSON.parse配置,非法 JSON 直接报错退出; - 如果配置中没有
outputType且命令行传了-t svg/-t pdf,则将outputType注入配置; - 调用
createGraph(graphOptions)渲染,再graph.exportToFile(output, type)落盘。
仓库自带一份可直接运行的完整配置示例 packages/g6-ssr/tests/graph-options.json,内容包含 34 个节点、circular 环形布局、autoFit: 'view'、半透明背景等配置,可直接作为-i的输入模板:
{ "width": 500, "height": 500, "autoFit": "view", "background": "rgba(100, 80, 180, 0.4)", "data": { "nodes": [{ "id": "0" }, { "id": "1" }], "edges": [{ "source": "0", "target": "1" }] }, "node": { "style": { "labelFill": "#fff", "labelPlacement": "center" } }, "layout": { "type": "circular" } }package.json 中的test:bin脚本也演示了 CLI 的官方用法(packages/g6-ssr/package.json#L25):
node ./bin/g6-ssr.js export -i ./__tests__/graph-options.json -o __tests__/assets/bin五、导出 SVG / PDF:两种方式
5.1 JavaScript API:outputType 选项
在createGraph中传入outputType即可切换导出格式:
const graph = await createGraph({ width: 500, height: 500, data: { // data }, outputType: 'svg', // 或 'pdf' // 其他配置 });5.2 CLI:-t / --type 选项
npx g6-ssr export -i [graph-options].json -o ./file -t pdf5.3 输出格式与 MIME 的映射规则
文件扩展名与 MIME 类型由 src/graph.ts#L13-L20 的getInfoOf函数决定:
| 配置 | 扩展名 | MIME 类型 |
|---|---|---|
outputType: 'pdf' | .pdf | application/pdf |
outputType: 'svg' | .svg | 无(undefined) |
imageType: 'jpeg'(默认 image 模式) | .jpeg | image/jpeg |
| 默认(image + png) | .png | image/png |
值得说明的是,outputType会同时传给底层的 node-canvas 创建逻辑(src/canvas.ts#L16 中的createNodeCanvas(width, height, outputType)),即画布本身的创建方式就随输出类型变化,这与纯前端「画完再编码」的思路不同——SSR 是「先按目标格式创建画布,再渲染」。
六、注册自定义 G6 扩展
服务端渲染同样支持 G6 的自定义扩展体系。使用@antv/g6-ssr重新导出的registry函数(其来源是@antv/g6的注册方法,见 src/index.ts#L3)即可注册自定义节点、边、Combo、布局等:
import { createGraph, registry } from '@antv/g6-ssr'; import { BaseNode, ExtensionCategory } from '@antv/g6'; class CustomNode extends BaseNode { // 自定义节点实现 } registry(ExtensionCategory.Node, 'custom-node', CustomNode); const graph = await createGraph({ width: 500, height: 500, node: { type: 'custom-node', // 其他节点配置 }, // 其他配置 });ExtensionCategory是 G6 的扩展类别枚举(Node / Edge / Combo / Layout 等),注册后即可在配置中通过type引用。若需要读取或管理已注册的扩展,@antv/g6-ssr还从 G6 导出了getExtension与getExtensions。
七、接入渲染插件(renderPlugins)
G6-SSR 允许透传@antv/g生态的渲染插件,在服务端渲染中同样生效。以手绘风格渲染插件@antv/g-plugin-rough-canvas-renderer为例:
import { createGraph } from '@antv/g6-ssr'; import { Plugin as RoughCanvasPlugin } from '@antv/g-plugin-rough-canvas-renderer'; const graph = await createGraph({ width: 500, height: 500, renderPlugins: [new RoughCanvasPlugin()], data: { // data }, });插件的装配逻辑在 src/canvas.ts#L19-L44:createCanvas会读取options.renderPlugins,在构建@antv/g-canvas的Renderer时逐个registerPlugin。同时有两个值得注意的细节:
- 服务端没有 DOM,因此源码会主动unregister 掉
html-renderer与dom-interaction两个插件(src/canvas.ts#L39-L42),这与 G6 在前端默认启用 HTML 渲染能力的行为不同; - 仓库测试覆盖了该插件场景——
image png with render plugin用例(packages/g6-ssr/tests/graph.spec.ts#L179-L200)会用 RoughCanvasPlugin 渲染并与快照assets/image-rough.png对比,可作参考实现。
八、源码级原理:createGraph 的完整渲染链路
结合 src/graph.ts 与 src/canvas.ts,一次 SSR 渲染的内部流程大致如下:
- 创建双画布:
createCanvas(options)调用 node-canvas 的createNodeCanvas(width, height, outputType)创建「真实」节点画布,再创建一块 1×1 的offscreenCanvas作为离屏画布; - 构造 G6 Canvas:用
G6Canvas(来自@antv/g6)包裹节点画布,设置width、height、background(默认'white')、devicePixelRatio(默认 2)、enableMultiLayer: false,并注入createImage: () => new NodeImage()以支持图片加载; - 创建 G6 Graph:在
createGraph中实例化new G6Graph({ animation: false, ...restOptions, container: g6Canvas })——注意服务端渲染强制关闭动画(src/graph.ts#L35-L39); - 渲染并等待:
await graph.render()完成首帧渲染后,再sleep(waitForRender)等待异步资源(如图片、字体)落地; - 导出:通过
nodeCanvas.toBuffer(mimeType, meta)编码输出,exportToFile负责落盘、toBuffer返回 Buffer。
测试 packages/g6-ssr/tests/graph.spec.ts 是理解各能力的最直接入口,它覆盖了:PNG / JPEG / PDF / SVG 四种导出、RoughCanvasPlugin 渲染插件、devicePixelRatio: 1与默认 2 的输出差异、以及带远程图片节点(iconSrc,配合waitForRender: 1000等待图片加载)等场景,并基于toMatchFile自定义匹配器与assets/下的快照逐一比对字节。
九、注意事项与限制
基于源码实现,使用时有以下几点值得留意:
- 原生依赖:依赖 node-canvas(
canvas^3),需要系统具备其编译/运行环境; - 无 DOM 能力:
html-renderer与dom-interaction插件被移除,因此HTML 节点等依赖 DOM 的渲染方式在 SSR 中不可用; - 动画被禁用:
createGraph内部强制animation: false,服务端渲染只关心最终静态帧; - 异步图片需要等待:若节点使用远程图片(如
iconSrc),建议调大waitForRender(测试中用了 1000ms),否则图片可能来不及加载; - 输出与导入的对应:
outputType需在渲染前确定,因为它同时决定了 node-canvas 的创建方式与最终文件扩展名/MIME; - 导出 PDF 元信息:通过
exportToFile(file, metadata)/toBuffer(metadata)的第二个参数传入PdfConfig等元数据配置。
十、快速上手清单
npm install @antv/g6-ssr,确保 Node 环境支持canvas原生模块;- 脚本方式:
const graph = await createGraph({ width, height, data, layout, node, ... }),随后graph.exportToFile('out')或graph.toBuffer(); - CLI 方式:准备一份 graph-options.json 格式的配置,执行
npx g6-ssr export -i config.json -o ./out -t svg; - 需要自定义节点/边时,用
registry(ExtensionCategory.Node, 'xxx', CustomNode)注册后以type: 'xxx'引用; - 需要特殊渲染风格时,将
@antv/g生态插件放入renderPlugins数组即可。
该包许可证为 MIT,源码、测试与 CLI 实现均可直接在 packages/g6-ssr 目录下查阅。
- 数据可视化
- 前端
- 图表库
【免费下载链接】G6
♾ A Graph Visualization Framework in JavaScript.
相关推荐
LogicFlow 插件深度指南:使用 Snapshot 将流程图导出为 PNG / JPEG / SVG 图片
LogicFlow 插件深度指南:使用 Snapshot 将流程图导出为 PNG / JPEG / SVG 图片 LogicFlow 作为专注于业务自定义的流程
前端低代码流程编排AntV X6 Export 导出插件实战:SVG/PNG/JPEG 画布导出 API 与源码原理详解
AntV X6 Export 导出插件实战:SVG/PNG/JPEG 画布导出 API 与源码原理详解 X6 的 Export 插件为画布提供了一整套「导出为图
前端图形学在 G6 中构建 3D 图可视化:@antv/g6-extension-3d 扩展包从安装到实战
在 G6 中构建 3D 图可视化:@antv/g6 extension 3d 扩展包从安装到实战 G6 的核心渲染能力是 2D Canvas/WebGL,但当需
数据可视化前端图表库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考