G6 元素体系总览:节点、边、组合的构成原理与配置实战
【免费下载链接】G6♾ A Graph Visualization Framework in JavaScript.项目地址: https://gitcode.com/gh_mirrors/g6/G6
本文基于 G6 官方文档 元素总览 展开,系统梳理 G6 图表中节点(Node)、边(Edge)、组合(Combo) 三大基本元素的类型体系、构成原理、状态机制与三种配置方式,并结合
packages/g6源码剖析其底层实现。读完本文,你将能够:掌握 G6 5.x 扁平化元素配置结构,理解 Shape 组合原理,熟练运用静态配置、实例配置与数据内配置三种途径,并借助状态系统与扩展能力构建复杂业务图表。
元素体系:三类基本元素
G6 图表的核心由三种基本元素构成:节点(Node)、边(Edge)和组合(Combo)。它们是构建复杂图形网络的基础单元。从源码看,三者均为元素类体系(Element)的实现,统一继承自BaseElement(见 base-element.ts),而BaseElement又继承自图形基类BaseShape(见 base-shape.ts),因此节点、边、组合本质上都是"由多个基础图形组合而成的复合元素"。
节点 (Node)
节点表示图中的实体或概念,如人物、地点、对象等。G6 提供了丰富的内置节点类型,源码中位于 nodes 目录:
| 节点类型 | 说明 | 源码文件 |
|---|---|---|
circle圆形 | 基础圆形节点,默认size: 32 | circle.ts |
rect矩形 | 矩形节点 | rect.ts |
ellipse椭圆 | 椭圆节点 | ellipse.ts |
diamond菱形 | 菱形节点 | diamond.ts |
triangle三角形 | 三角形节点 | triangle.ts |
star星形 | 星形节点 | star.ts |
hexagon六边形 | 六边形节点 | hexagon.ts |
donut环形 | 环形占比图节点 | donut.ts |
image图片 | 图片节点 | image.ts |
htmlHTML | HTML/DOM 节点 | html.ts |
所有内置节点均在 nodes/index.ts 中统一导出。除内置类型外,G6 还支持 使用 React 定义节点 或 自定义节点 以满足特定需求。
以圆形节点为例,其关键实现是在drawKeyShape中通过upsert('key', GCircle, ...)创建圆形图形,并将r取为size各维度最小值的一半(见 circle.ts)。upsert是BaseShape提供的"创建、更新或删除图形"的统一入口,当传入的 style 为false时删除图形,否则按需创建或更新(见 base-shape.ts)。
边 (Edge)
边表示节点间的连接关系,如朋友关系、交易往来等。G6 内置多种边类型,源码位于 edges 目录:
| 边类型 | 说明 | 源码文件 |
|---|---|---|
line直线 | 直线边 | line.ts |
polyline折线 | 折线边(可配置拐点) | polyline.ts |
quadratic二次贝塞尔 | 二次贝塞尔曲线边 | quadratic.ts |
cubic三次贝塞尔 | 三次贝塞尔曲线边 | cubic.ts |
cubic-horizontal | 水平方向三次贝塞尔 | cubic-horizontal.ts |
cubic-vertical | 垂直方向三次贝塞尔 | cubic-vertical.ts |
cubic-radial | 径向三次贝塞尔 | cubic-radial.ts |
边是"路径(Path) + 箭头(marker) + 文本标签(label) + 光晕(halo) + 徽标(badge)"的复合体。从 base-edge.ts 的render方法可见其渲染顺序:先绘制 key 路径,再绘制起始/结束箭头,然后绘制标签、光晕和徽标。边还支持自环(loop)配置——当sourceNode与targetNode相同时,会自动切换为自环路径(getLoopPath,支持arc与 cubic 两种形态,见 base-edge.ts)。
当内置边不满足需求时,可以通过 自定义边 实现复杂的连接表现。
组合 (Combo)
组合是一种特殊元素,可以包含节点和其他组合,用于表示集合、分组或层级关系。G6 内置两种组合类型(源码位于 combos 目录):
- 圆形组合(
circle):适合紧凑型分组(circle.ts) - 矩形组合(
rect):适合规则布局的分组(rect.ts)
组合支持嵌套、拖拽、展开/收起等交互。从 base-combo.ts 可以看到,BaseCombo直接继承自BaseNode,因此组合天然具备节点的全部能力(标签、图标、徽标、连接桩等),并额外扩展了组合特有能力:
size/collapsedSize:展开/收起时的尺寸padding:内边距(仅展开状态生效)collapsedMarker:收起时的标记,collapsedMarkerType支持child-count(子元素数)、descendant-count(后代总数)、node-count(后代节点数)或自定义函数(见 base-combo.ts)- 展开时组合尺寸由子元素包围盒自动计算,收起时按
collapsedSize渲染,位置取后代节点的平均中心(见 base-combo.ts)
可以通过 自定义组合 实现更复杂的容器行为。
元素构成原理:Shape 最小图形单元
每个元素由一个或多个基础图形(Shape)组成。图形是 G6 中的最小图形单元,包括矩形、圆形、文本、路径等。这些基础图形组件集中在 shapes 目录,包括:
- BaseShape:所有图形与元素的基类,提供
upsert、animate、getShape等核心能力(base-shape.ts) - Label:文本标签图形(label.ts)
- Icon:图标图形(icon.ts)
- Badge:徽标图形(badge.ts)
- Contour:轮廓图形(contour.ts)
- Image:图片图形(image.ts)
各 Shape 样式属性参考 Shape 样式属性。
典型组合示例:
- 一个节点可能由背景图形(如圆形)+ 文本标签 + 图标 + 徽标 + 连接桩组成。从 base-node.ts 的
render方法可见完整渲染顺序:keyShape → halo(光晕) → icon(图标) → badges(徽标) → label(标签) → ports(连接桩) - 一条边可能由路径、箭头(start/end 两个方向)和文本标签组成
- 一个组合可能由容器图形、标题文本和展开/收起按钮(collapsed marker)组成
值得一提的是,BaseShape.upsert实现了图形实例的增量复用:同名图形存在则更新属性,不存在则创建,传入false则销毁,这套机制让元素在数据更新时无需重建整个 DOM 树,是 G6 高性能渲染的基石之一(见 base-shape.ts)。
元素状态:交互与业务的视觉开关
元素状态是一种强大的机制,用于展示元素在不同交互或业务场景下的视觉变化。G6 提供了一套完整的状态管理系统:
- 预设状态:
selected(选中)、highlight(高亮)、active(激活)、inactive(未激活)、disabled(禁用) 等 - 状态叠加:元素可同时拥有多个状态,样式按优先级叠加合并
- 自定义状态:可根据业务需求定义任意状态(
State类型即string,见 state.ts)
状态的底层计算机制
状态样式的核心计算逻辑位于 runtime/element.ts:
computeElementStatesStyle将元素当前的多个状态样式按Object.assign顺序合并(后声明的状态覆盖先声明的同名属性,见 element.ts)getElementComputedStyle定义了最终样式的优先级(从低到高):主题样式 → 色板样式 → 数据样式 → 元素默认样式 → 主题状态样式 → 元素状态样式(见 element.ts)- 状态声明支持回调函数写法,可根据数据动态返回样式(
computeElementCallbackStyle)
操作状态的 API
graph.setElementState(id, state, animation?):为单个元素设置状态graph.setElementState({ id: state }, animation?):批量设置(见 graph.ts)graph.getElementState(id):获取元素当前状态数组
内置行为(如 click-select.ts、brush-select.ts、hover-activate.ts)正是通过setElementState驱动状态切换的。
主题中预设的状态样式
G6 内置主题(base.ts)为三类元素分别定义了state配置。以节点为例,selected状态默认开启 halo(光晕,haloStrokeOpacity: 0.25)并加粗描边;active状态开启淡光晕;highlight状态加粗描边;inactive/disabled状态则降低透明度与填充(见 base.ts)。边与组合也各有对应的状态定义(见 base.ts)。
配置元素:扁平化配置结构与三种方式
G6 5.x 采用扁平化的配置结构,所有元素的配置都在同一层级,便于查找和管理。以文档中的完整示例为例:
{ node: { // 节点默认样式 style: { fill: 'orange', labelText: 'node', }, // 节点在不同状态下的样式 state: { selected: { stroke: '#1890FF', lineWidth: 2, } } }, edge: { // 边默认样式 style: { stroke: '#aaa', }, // 边在不同状态下的样式 state: { highlight: { stroke: 'red', } } }, combo: { // 组合默认样式 style: { fill: 'lightblue', stroke: 'blue', } } };这份配置既可以作为new Graph({ node, edge, combo })的全局配置传入,也可以与数据结合使用。从 spec/element/node.ts 的类型定义可见,style与state均支持静态对象、函数以及逐属性函数三种形态,例如:
new Graph({ node: { type: 'circle', style: { fill: (d) => d.color, // 逐属性回调,根据数据动态着色 size: 32, }, state: { selected: { lineWidth: 2, stroke: '#1890FF' }, }, }, });三种配置方式(按优先级从高到低)
配置方式有三种,优先级从高到低:
- 使用实例方法动态配置:如
graph.setNode()、graph.setEdge()、graph.setCombo()(见 graph.ts)。这些方法将配置写入graph.options并触发model.refreshData()刷新数据映射,适用于运行时切换样式方案 - 实例化图时全局配置:在
new Graph()时指定配置项,作为所有元素的默认映射 - 在数据中配置:在节点、边、组合的数据对象中设置,如
{ id: 'node-1', style: { fill: 'red' } },用于对单个元素做个性化覆盖
在 VSCode 等编辑器中,由于全部类型定义完备,你可以看到元素的全部可配置属性,并基于关键字进行搜索,大幅降低记忆负担。
扩展能力
G6 提供了强大的扩展能力,满足各种自定义需求:
- 自定义节点:自定义节点指南
- 自定义边:自定义边指南
- 自定义组合:自定义组合指南
- React 节点:使用 React 定义节点
- Vue 节点:使用 Vue 定义节点
- 3D 扩展:通过
@antv/g6-extension-3d使用 3D 节点(源码见 g6-extension-3d,内置cube、sphere、capsule、cylinder、cone、torus、plane等 3D 图元)
自定义扩展的实现要点
自定义元素的核心是继承对应基类(BaseNode/BaseEdge/BaseCombo)并实现drawKeyShape抽象方法。例如自定义圆形节点时,只需关注主图形(key shape)的绘制,其余标签、图标、光晕、徽标、连接桩等均由基类统一处理(见 base-node.ts 的注释说明)。BaseCombo同理:"自定义组合时,推荐使用这个类作为基类,只需要专注于实现 keyShape 的绘制逻辑"(见 base-combo.ts)。
完成自定义类后,通过graph.registerNode()/registerEdge()/registerCombo()注册到 G6 的扩展注册表(registry/register.ts)即可在配置中按名称使用。
内置元素参考
节点类型
- 内置节点库(BaseNode 通用配置见 BaseNode)
边类型
- 内置边库(BaseEdge 通用配置见 BaseEdge)
组合类型
- 内置组合库(BaseCombo 通用配置见 BaseCombo)
小结
G6 的元素体系可以概括为一条主线:节点、边、组合三类复合元素 → 由若干基础 Shape 图形组成 → 通过扁平化的 style/state 配置驱动视觉 → 通过三种配置方式与状态系统响应业务与交互 → 通过自定义扩展覆盖任意场景。理解这一体系后,无论是开箱即用的内置元素,还是深度定制的复杂业务图表,都能从"配置"与"扩展"两个维度从容应对。
【免费下载链接】G6♾ A Graph Visualization Framework in JavaScript.项目地址: https://gitcode.com/gh_mirrors/g6/G6
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考