ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

@antv/g6-ssr 服务端渲染实践:在 Node.js 中将 G6 5.0 图导出为 PNG / JPEG / SVG / PDF

@antv/g6-ssr 服务端渲染实践:在 Node.js 中将 G6 5.0 图导出为 PNG / JPEG / SVG / PDF 数据可视化前端图表库【免费下载链接】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-ssrG6 5.0 本身是面向浏览器的图可视化框架画布渲染依赖 DOM 与浏览器能力。而antv/g6-ssr是 G6 官方提供的SSRServer-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-canvascanvas包在 Node 中创建离屏画布再通过antv/g-canvas的 Renderer 驱动 G6 完成渲染从而完全绕开浏览器环境。二、安装与环境准备npm install antv/g6-ssr安装时需要注意以下两点前提依据 packages/g6-ssr/package.json 的依赖声明该包依赖原生模块canvasnode-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.cjsmain字段并对外提供bin/g6-ssr.js命令行入口构建配置见 rollup.config.mjs其中fs、path、canvas被标记为 external。三、JavaScript APIcreateGraph 渲染与导出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/heightnumber必填画布宽高单位 pxoutputTypeimage \| pdf \| svgimage输出文件类型决定导出的是图片、PDF 还是 SVGimageTypepng \| jpegpng当outputType为image时的图片编码格式waitForRendernumber32ms渲染完成后额外等待的毫秒数用于等待动画帧、异步图片等完成代码实现见 src/graph.ts#L34renderPluginsRendererPlugin[][]透传给antv/g-canvasRenderer 的渲染插件数组backgroundstringwhite画布背景色在 canvas.ts 中解构设置见 src/canvas.ts#L15devicePixelRationumber2输出像素比控制导出图清晰度默认 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的 srcgetGraph() G6Graph取回底层 G6 原生 Graph 实例getCanvas() Canvas取回底层 node-canvas 实例destroy() void销毁图实例释放资源其中MetaData类型为PdfConfig | PngConfig | JpegConfignode-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实现核心子命令是exportnpx 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#L25node ./bin/g6-ssr.js export -i ./__tests__/graph-options.json -o __tests__/assets/bin五、导出 SVG / PDF两种方式5.1 JavaScript APIoutputType 选项在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.pdfapplication/pdfoutputType: svg.svg无undefinedimageType: 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 导出了getExtension与getExtensions。七、接入渲染插件renderPluginsG6-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-L44createCanvas会读取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-canvascanvas^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.项目地址https://gitcode.com/gh_mirrors/g6/G6点击查看免费下载相关推荐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),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进