G6 画布操作完全指南:getCanvas / getSize / setSize 的用法与底层实现
2026/9/24 20:23:46 网站建设 项目流程
  • 数据可视化
  • 前端
  • 图表库

【免费下载链接】G6

♾ A Graph Visualization Framework in JavaScript.

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

本文围绕 G6(A Graph Visualization Framework in JavaScript)官方 API 文档 packages/site/docs/api/canvas.en.md 展开,系统讲解画布操作的三大核心 API——Graph.getCanvas()Graph.getSize()Graph.setSize(),并结合仓库源码剖析其背后的分层渲染架构与尺寸变更机制,帮助读者在实战中完成画布实例获取、尺寸读取与动态调整等常见需求。

一、画布操作 API 总览

G6 提供了一系列画布操作 API,用于控制与获取画布的基本信息。通过它们,你可以:

  • 获取画布实例:拿到底层 Canvas 对象,进行低层级画布操作(图层、相机、光标等);
  • 获取与设置画布尺寸:读取当前画布容器的宽高,或按需动态调整画布大小;
  • 操作画布渲染器与图层:访问分层渲染体系下的各图层与渲染器。

这三个 API 均归属于graph(Graph 实例)的canvas能力分类(源码中以@apiCategory canvas标注),是绝大多数 G6 应用都会用到的基础能力。

二、Graph.getCanvas():获取画布实例

2.1 方法签名与返回值

getCanvas(): Canvas;

调用graph.getCanvas()返回的是 G6 内部封装后的Canvas实例(定义于 packages/g6/src/runtime/canvas.ts)。从源码看,其实现非常直接——直接返回运行时上下文中的画布对象:

// packages/g6/src/runtime/graph.ts public getCanvas(): Canvas { return this.context.canvas; }

2.2 Canvas 实例提供的主要能力

按官方文档说明,返回的 Canvas 实例包含以下主要方法:

  • getLayer(name?: string):获取指定图层;
  • getLayers():获取所有图层;
  • getCamera():获取相机实例;
  • getRoot():获取根节点;
  • setCursor(cursor: string):设置鼠标光标样式。

结合 packages/g6/src/runtime/canvas.ts 的源码,Canvas类还提供getConfig()getRenderer(layer)getContextService(layer)getBounds(group?)getContainer()getSize()resize(width, height)toDataURL()destroy()以及多组坐标转换方法(如getCanvasByViewportgetViewportByClient等)。其中:

  • getLayer(layer: CanvasLayer = 'main'):按名称取图层,若未找到则回退到main图层(getMainLayerOf);
  • getCamera(layer = 'main')getRoot(layer = 'main'):均以图层为粒度委托给对应@antv/g画布实现;
  • setCursor(cursor):同时更新内部配置this.config.cursor并应用到主图层。

2.3 分层渲染架构(关键背景知识)

理解getLayer/getLayers之前,需要先了解 G6 的分层渲染设计。在 packages/g6/src/types/canvas.ts 中定义了图层类型:

export type CanvasLayer = 'background' | 'main' | 'label' | 'transient';

而在 packages/g6/src/runtime/canvas.ts 中:

  • 默认开启多图层(enableMultiLayer默认为true)时使用四个图层:background(背景层)、main(主元素层)、label(标签层)、transient(临时层,如拖拽过程中的临时绘制);
  • 关闭多图层时则仅保留main单层。

四个图层被放在同一容器内,通过 CSSgrid布局叠加(见configCanvasDom,非main图层会设置pointerEvents = 'none'),main图层还单独注册了DragNDropPlugin用于拖拽交互。

分层的好处在于:例如toDataURL()导出图片时,可以分别克隆各图层根节点并精确重组(见 packages/g6/src/runtime/canvas.ts),而标签层与主元素层互不干扰。

2.4 实战示例

// 获取画布实例 const canvas = graph.getCanvas(); // 获取主图层 const mainLayer = canvas.getLayer('main'); // 获取所有图层 const allLayers = canvas.getLayers(); // 设置鼠标光标样式 canvas.setCursor('pointer'); // 获取画布根节点 const root = canvas.getRoot(); // 获取画布相机(用于视口变换) const camera = canvas.getCamera();

2.5 测试用例佐证

仓库测试代码大量使用该 API,可印证其真实用法:

  • packages/g6/tests/unit/behaviors/drag-element.spec.ts:通过graph.getCanvas().getConfig().cursor断言拖拽过程中光标在grab/grabbing之间切换;
  • packages/g6/tests/unit/behaviors/drag-canvas.spec.ts 与 scroll-canvas.spec.ts:通过graph.getCanvas().getSize()读取画布尺寸参与断言;
  • packages/g6/tests/main.ts:通过graph.getCanvas().getLayers()把各图层暴露到window.__g_instances__供调试。

三、Graph.getSize():获取画布尺寸

3.1 方法签名与返回值

getSize(): [number, number];

返回当前画布容器的尺寸,为一个包含宽、高的二元数组。

从源码看,packages/g6/src/runtime/graph.ts 的实现优先委托给底层 Canvas:

public getSize(): [number, number] { if (this.context.canvas) return this.context.canvas.getSize(); return [this.options.width || 0, this.options.height || 0]; }

而 Canvas.getSize() 则是直接读取内部配置:

public getSize(): [number, number] { return [this.extends.config.width || 0, this.extends.config.height || 0]; }

也就是说,返回的尺寸来自初始化时写入的width/height配置。若创建 Graph 时未显式指定宽高(CanvasOptions 中注明“如果未设置,则会自动获取容器宽度/高度”),则会在初始化阶段自动测量容器得到实际值。

3.2 实战示例

// 获取画布尺寸 const [width, height] = graph.getSize(); console.log('Canvas width:', width); console.log('Canvas height:', height); // 用尺寸信息做计算(例如求中心点) const centerX = width / 2; const centerY = height / 2;

3.3 相关联动:视口中心的计算

getSize()的结果与视口中心计算直接相关。在 packages/g6/src/runtime/viewport.ts 中,getCanvasCenter()即基于宽高计算中心坐标:

public getCanvasCenter(): Point { const { canvas } = this.context; const { width = 0, height = 0 } = canvas.getConfig(); return [width / 2, height / 2, 0]; }

该中心点在fitViewfocusElement、坐标换算等视口操作中被广泛引用(viewport.ts 等),因此准确读取尺寸是做好视口控制的前提。在自定义节点/边中,也可以像 packages/g6/tests/demos/element-html-sub-graph.ts 那样通过this.getSize()拿到画布宽高做布局计算。

四、Graph.setSize(width, height):动态调整画布尺寸

4.1 方法签名与参数说明

setSize(width: number, height: number): void;

该方法会同时更新画布与容器尺寸。参数说明如下:

参数说明类型默认值是否必填
width画布宽度(像素)number-
height画布高度(像素)number-

4.2 底层实现:与 resize 的关系

packages/g6/src/runtime/graph.ts 中,setSize的实现为:

public setSize(width: number, height: number): void { if (width) this.options.width = width; if (height) this.options.height = height; this.resize(width, height); }

它先同步更新 Graph 的options.width / options.height(保证后续getSize()读到一致的值),再调用resize。而resize(graph.ts)做了三件事:

  1. 若未传宽高,则回退为容器实测尺寸sizeOf(container)
  2. 若目标尺寸与当前画布尺寸一致,则直接返回(避免无效变更);
  3. 依次派发BEFORE_SIZE_CHANGEAFTER_SIZE_CHANGE生命周期事件,然后调用底层canvas.resize(...)

底层 Canvas.resize() 会遍历所有图层调用@antv/gcanvas.resize(width, height),并在缩放后恢复相机位置与焦点,从而保证 resize 后视口内容不发生漂移。

4.3 实战示例

// 设置为固定尺寸 graph.setSize(800, 600); // 也可以先读取再调整 const [w, h] = graph.getSize(); graph.setSize(w + 200, h + 200);

4.4 联动:autoResize 自动尺寸调整

除手动调用setSize外,G6 还支持通过配置autoResize让画布随窗口变化自动调整。该配置项定义于 packages/g6/src/spec/canvas.ts:

/** * <zh/> 是否自动调整画布大小 * * <en/> whether to auto resize canvas * @defaultValue false * @remarks * <zh/> 基于 window.onresize 事件自动调整画布大小 * * <en/> Automatically adjust the canvas size based on the window.onresize event */ autoResize?: boolean;

对应实现在 graph.ts:当autoResizetrue时,Graph 会监听全局resize事件,并在销毁时移除监听(graph.ts)。这意味着响应式布局有两种典型做法:

// 方式一:显式调用 window.addEventListener('resize', () => { graph.setSize(window.innerWidth, window.innerHeight); }); // 方式二:开启自动调整 const graph = new Graph({ container: '#container', autoResize: true, // ... 其他配置 });

五、综合实战:一个响应式、居中的画布

将上述 API 组合使用,即可实现常见的“窗口变化后画布自适应并重新居中”场景:

import { Graph } from '@antv/g6'; const graph = new Graph({ container: document.getElementById('container')!, data: { nodes: [...], edges: [...] }, autoResize: true, }); graph.render(); // 用 getSize 计算中心并聚焦 const [width, height] = graph.getSize(); console.log(`画布中心位于 (${width / 2}, ${height / 2})`); // 手动调整尺寸后重新适配视口 graph.setSize(1200, 800); graph.fitView();

再配合getCanvas()做低层级控制,例如在需要临时屏蔽交互时修改光标:

const canvas = graph.getCanvas(); canvas.setCursor('crosshair'); // 或 'grab' / 'pointer' 等任意 CSS cursor 值

六、小结

API作用底层要点
graph.getCanvas()获取底层 Canvas 实例返回context.canvas,可操作图层、相机、根节点、光标
graph.getSize()读取画布尺寸委托Canvas.getSize()读取内部配置宽高,返回[width, height]
graph.setSize(w, h)动态调整画布尺寸更新 options 后调用resize,派发尺寸变更事件并保持相机不漂移

这三个 API 覆盖了“拿到画布、读尺寸、改尺寸”的完整闭环,配合 G6 的四层分层渲染(background/main/label/transient)与autoResize自动调整能力,可以支撑从静态展示到复杂响应式交互的绝大多数业务场景。更多画布细节可继续阅读:

  • Canvas 运行时实现:packages/g6/src/runtime/canvas.ts
  • Graph 运行时实现:packages/g6/src/runtime/graph.ts
  • 画布配置项定义:packages/g6/src/spec/canvas.ts
  • 视口与坐标换算:packages/g6/src/runtime/viewport.ts
  • 数据可视化
  • 前端
  • 图表库

【免费下载链接】G6

♾ A Graph Visualization Framework in JavaScript.

项目地址:https://gitcode.com/gh_mirrors/g6/G6
点击查看免费下载
上一篇:DevDocs Desktop:把几十份 API 文档收进一个窗口的终极桌面阅读神器
下一篇:LSD (LSDeluxe) 终极指南:现代化ls命令的完美替代方案

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

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

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

立即咨询