@antv/g6-ssr 服务端渲染实践:在 Node.js 中将 G6 5.0 图导出为 PNG / JPEG / SVG / PDF
2026/9/23 22:37:11 网站建设 项目流程
  • 数据可视化
  • 前端
  • 图表库

【免费下载链接】G6

♾ A Graph Visualization Framework in JavaScript.

项目地址:https://gitcode.com/gh_mirrors/g6/G6
点击查看免费下载

本指南围绕 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(导出createGraphcreateCanvasregister等 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 的依赖声明):

  1. 该包依赖原生模块canvas(node-canvas,版本 ^3),因此运行环境需要能编译或预装 node-canvas 的原生依赖(如 cairo 相关系统库)。如果使用 Docker,建议选择带 canvas 原生依赖的 Node 基础镜像。
  2. 依赖@antv/g(^6.1.24)、@antv/g-canvas(^2.0.43)与@antv/g6(同仓库 workspace 版本),安装时会被一并拉取。

在 G6 仓库中该包位于 packages/g6-ssr,构建产物为 CJS 格式的dist/g6-ssr.cjsmain字段),并对外提供bin/g6-ssr.js命令行入口(构建配置见 rollup.config.mjs,其中fspathcanvas被标记为 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等导出方法的包装对象;
  • 配置项中widthheight为必填,其余绝大多数可透传 G6 的 GraphOptions(如datanodeedgelayoutautoFitbehaviors等)。

3.2 Options 参数速查表

依据 src/types.ts 的类型定义,Options在 G6GraphOptions基础上(排除renderercontainer,这两个由内部接管)新增了以下字段:

参数类型默认值说明
width/heightnumber必填画布宽高,单位 px
outputType'image' \| 'pdf' \| 'svg''image'输出文件类型,决定导出的是图片、PDF 还是 SVG
imageType'png' \| 'jpeg''png'outputType'image'时的图片编码格式
waitForRendernumber32(ms)渲染完成后额外等待的毫秒数,用于等待动画帧、异步图片等完成;代码实现见 src/graph.ts#L34
renderPluginsRendererPlugin[][]透传给@antv/g-canvasRenderer 的渲染插件数组
backgroundstring'white'画布背景色(在 canvas.ts 中解构设置,见 src/canvas.ts#L15)
devicePixelRationumber2输出像素比,控制导出图清晰度(默认 2 倍)

提示:waitForRender在类型注释中标注为 16ms,但运行时默认值以 src/graph.ts#L34 的解构默认值32为准。

其余配置(如datalayoutnodeedgeautoFitbehaviors等)与 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 时可传入titleauthorcreatorsubjectkeywordscreationDatemodDate等元信息(测试用例中的完整示例见 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 的处理流程:

  1. 校验-i是否提供、文件是否存在,否则红色报错并退出;
  2. 读取并JSON.parse配置,非法 JSON 直接报错退出;
  3. 如果配置中没有outputType且命令行传了-t svg/-t pdf,则将outputType注入配置;
  4. 调用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 pdf

5.3 输出格式与 MIME 的映射规则

文件扩展名与 MIME 类型由 src/graph.ts#L13-L20 的getInfoOf函数决定:

配置扩展名MIME 类型
outputType: 'pdf'.pdfapplication/pdf
outputType: 'svg'.svg无(undefined)
imageType: 'jpeg'(默认 image 模式).jpegimage/jpeg
默认(image + png).pngimage/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 导出了getExtensiongetExtensions

七、接入渲染插件(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-canvasRenderer时逐个registerPlugin。同时有两个值得注意的细节:

  1. 服务端没有 DOM,因此源码会主动unregister 掉html-rendererdom-interaction两个插件(src/canvas.ts#L39-L42),这与 G6 在前端默认启用 HTML 渲染能力的行为不同;
  2. 仓库测试覆盖了该插件场景——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 渲染的内部流程大致如下:

  1. 创建双画布createCanvas(options)调用 node-canvas 的createNodeCanvas(width, height, outputType)创建「真实」节点画布,再创建一块 1×1 的offscreenCanvas作为离屏画布;
  2. 构造 G6 Canvas:用G6Canvas(来自@antv/g6)包裹节点画布,设置widthheightbackground(默认'white')、devicePixelRatio(默认 2)、enableMultiLayer: false,并注入createImage: () => new NodeImage()以支持图片加载;
  3. 创建 G6 Graph:在createGraph中实例化new G6Graph({ animation: false, ...restOptions, container: g6Canvas })——注意服务端渲染强制关闭动画(src/graph.ts#L35-L39);
  4. 渲染并等待await graph.render()完成首帧渲染后,再sleep(waitForRender)等待异步资源(如图片、字体)落地;
  5. 导出:通过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-rendererdom-interaction插件被移除,因此HTML 节点等依赖 DOM 的渲染方式在 SSR 中不可用
  • 动画被禁用createGraph内部强制animation: false,服务端渲染只关心最终静态帧;
  • 异步图片需要等待:若节点使用远程图片(如iconSrc),建议调大waitForRender(测试中用了 1000ms),否则图片可能来不及加载;
  • 输出与导入的对应outputType需在渲染前确定,因为它同时决定了 node-canvas 的创建方式与最终文件扩展名/MIME;
  • 导出 PDF 元信息:通过exportToFile(file, metadata)/toBuffer(metadata)的第二个参数传入PdfConfig等元数据配置。

十、快速上手清单

  1. npm install @antv/g6-ssr,确保 Node 环境支持canvas原生模块;
  2. 脚本方式:const graph = await createGraph({ width, height, data, layout, node, ... }),随后graph.exportToFile('out')graph.toBuffer()
  3. CLI 方式:准备一份 graph-options.json 格式的配置,执行npx g6-ssr export -i config.json -o ./out -t svg
  4. 需要自定义节点/边时,用registry(ExtensionCategory.Node, 'xxx', CustomNode)注册后以type: 'xxx'引用;
  5. 需要特殊渲染风格时,将@antv/g生态插件放入renderPlugins数组即可。

该包许可证为 MIT,源码、测试与 CLI 实现均可直接在 packages/g6-ssr 目录下查阅。

  • 数据可视化
  • 前端
  • 图表库

【免费下载链接】G6

♾ A Graph Visualization Framework in JavaScript.

项目地址:https://gitcode.com/gh_mirrors/g6/G6
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询