- 数据可视化
- 前端
- 图表库
【免费下载链接】G6
♾ A Graph Visualization Framework in JavaScript.
节点是图可视化中最核心的构成单元。本文以 G6 官方文档《节点总览》为主线,结合 G6 仓库源码(packages/g6/src/elements/nodes、packages/g6/src/registry/build-in.ts等)逐层拆解 G6 的节点体系:从内置节点、3D 节点、React 节点到自定义节点的整体分类,从节点数据字段到三种配置方式的优先级关系,再到状态样式与动态更新。读完本文,你将掌握 G6 中"选型 → 建数据 → 配样式 → 做交互"的完整节点开发链路,并理解这些能力在源码层面的实现原理。
什么是节点
节点(Node)是图中的基本元素之一,表示图中的实体或抽象概念,例如一个人、一个地点、一个组织等。节点可以包含一些属性,例如节点的 ID、名称、类型等。在 G6 中,节点可以具有多种形状和样式,并支持丰富的交互和自定义功能。
节点与节点之间通过**边(Edge)**连接以表示关系,因此你可以在图中创建任意数量的节点,并通过边将它们组织成完整的图结构。
节点体系总览
G6 的节点体系包括三大类:内置节点、扩展节点(3D 节点、React 节点等)和自定义节点。其中,大多数场景下使用内置节点即可满足需求,无需注册、直接配置type字段即可使用。
内置节点
G6 内置了 10 种开箱即用的节点类型,无需注册,直接配置即可使用:
| 节点类型 | 注册名称 | 描述 |
|---|---|---|
| 圆形节点 | circle | 常用于表示普通实体 |
| 矩形节点 | rect | 适合展示更多文本和细节 |
| 椭圆节点 | ellipse | 类似圆形的变体 |
| 菱形节点 | diamond | 常用于决策点或特殊节点 |
| 三角形节点 | triangle | 可用于指示方向或特殊标记 |
| 六边形节点 | hexagon | 适合网格布局和蜂窝图 |
| 星形节点 | star | 突出显示重要节点 |
| 甜甜圈节点 | donut | 可展示比例或进度信息 |
| 图片节点 | image | 使用图片作为节点主体 |
| HTML 节点 | html | 支持自定义 HTML 内容 |
这一注册表在源码中有明确对应:packages/g6/src/registry/build-in.ts(第 174-185 行)将circle、diamond、ellipse、hexagon、html、image、rect、star、donut、triangle这 10 个名称逐一映射到对应的节点类实现,因此你在node.type或节点数据type字段中直接写入这些名称即可生效。
从源码结构看,每个内置节点都是一个独立的类文件,位于 packages/g6/src/elements/nodes 目录下,包括circle.ts、rect.ts、ellipse.ts、diamond.ts、donut.ts、hexagon.ts、triangle.ts、star.ts、image.ts、html.ts,它们全部继承自抽象的BaseNode基类(base-node.ts)。
以圆形节点为例,circle.ts 中核心绘制逻辑为:
protected drawKeyShape(attributes: Required<CircleStyleProps>, container: Group) { return this.upsert('key', GCircle, this.getKeyStyle(attributes), container); } protected getKeyStyle(attributes: Required<CircleStyleProps>): GCircleStyleProps { const keyStyle = super.getKeyStyle(attributes); // 圆形半径 = size 最小值的一半 return { ...keyStyle, r: Math.min(...this.getSize(attributes)) / 2 }; }可以看到,circle的半径由size推导(r = min(size) / 2),并且其连线交点计算使用椭圆求交算法(getEllipseIntersectPoint),这保证边始终从节点轮廓边界出发而非圆心。矩形节点 rect.ts 则会将 keyShape 的x/y偏移至-width/2、-height/2,实现以节点中心为原点居中绘制。各内置节点类型的详细样式配置,可进一步查阅 Circle.zh.md、Rect.zh.md 等对应文档。
3D 节点
当使用 WebGL 渲染器时,@antv/g6-extension-3d提供了 3D 节点:
Capsule— 胶囊型节点Cone— 圆锥型节点Cube— 立方体节点Cylinder— 圆柱型节点Plane— 平面节点Sphere— 球体节点Torus— 圆环节点
这些 3D 节点的实现位于 packages/g6-extension-3d/src/elements 目录,每个几何体(capsule.ts、cone.ts、cube.ts、cylinder.ts、plane.ts、sphere.ts、torus.ts)对应一个节点类,并统一继承BaseNode3D(base-node-3d.ts)。3D 节点与内置 2D 节点一样,属于扩展包提供的类型,需要在渲染前注册后使用。
React 节点
@antv/g6-extension-react提供了 React 节点,支持使用 React 组件作为节点的主体,使节点内容具备组件化的渲染与交互能力。其实现位于 packages/g6-extension-react/src/react-node,包含针对 React 16/18 的不同渲染适配(render16.ts、render18.ts)。详细教程请查看 使用 React 定义节点 文档。
自定义节点
当内置节点和扩展节点无法满足需求时,G6 提供了强大的自定义能力:
- 继承内置节点进行扩展:以
BaseNode或任一内置节点为基类,只需关注 keyShape(主图形)的绘制逻辑即可; - 创建全新的节点类型:完全自定义节点的渲染与行为。
与内置节点不同,自定义节点需要先注册后使用。详细教程请参考 自定义节点 文档。
节点的数据结构
定义节点时,需要在图的数据对象中添加nodes字段。每个节点是一个对象,其字段结构如下:
| 属性 | 描述 | 类型 | 默认值 | 必选 |
|---|---|---|---|---|
| id | 节点的唯一标识符,用于区分不同的节点 | string | - | ✓ |
| type | 节点类型,内置节点类型名称或自定义节点的名称 | string | - | |
| data | 节点数据,用于存储节点的自定义数据,例如节点的名称、描述等。可以在样式映射中通过回调函数获取 | object | - | |
| style | 节点样式,包括位置、大小、颜色等视觉属性 | object | - | |
| states | 节点初始状态,如选中、激活、悬停等 | string[] | - | |
| combo | 所属组合的 ID,用于组织节点的层级关系,如果没有则为 null | string | null | - | |
| children | 子节点 ID 集合,仅在树图场景下使用 | string[] | - |
nodes数组中一个数据项的示例:
{ "id": "node-1", "type": "circle", "data": { "name": "alice", "role": "Admin" }, "style": { "x": 100, "y": 200, "size": 32, "fill": "violet" }, "states": ["selected"], "combo": null }从源码设计看,data与style的分离非常关键:data存放业务自定义数据(名称、描述等),而style存放视觉属性;样式映射阶段可以通过回调函数读取data中的值做条件化渲染(见下文"调整优先级"示例)。style中常用的视觉字段在BaseNode的defaultStyleProps(base-node.ts 第 197-225 行)中有默认值,例如x: 0、y: 0、size: 32,以及label: true(默认显示标签)、halo: false(默认关闭光晕)、icon: true(默认启用图标)等。
节点配置的三种方式
配置节点的方式有三种,按优先级从高到低排列:
- 使用
graph.setNode()动态配置(最高优先级) - 实例化图时全局配置
- 在数据中动态配置(最低优先级)
这三种配置方式可以同时使用;当存在相同配置项时,优先级高的方式会覆盖优先级低的。
使用graph.setNode()
可在图实例创建后,使用graph.setNode()动态设置节点的样式映射逻辑。该方法需要在graph.render()之前调用才会生效,并拥有最高优先级:
graph.setNode({ style: { type: 'circle', style: { size: 60, fill: '#7FFFD4', stroke: '#5CACEE', lineWidth: 2 }, }, }); graph.render();实例化图时全局配置
在实例化图时,通过node字段配置节点样式映射。这里的配置是全局配置,会在所有节点上生效:
import { Graph } from '@antv/g6'; const graph = new Graph({ node: { type: 'circle', style: { size: 60, fill: '#7FFFD4', stroke: '#5CACEE', lineWidth: 2 }, }, });注意这里配置的type与style与节点数据中的字段同名同义,全局配置充当了"默认模板",为所有未显式指定这些字段的节点提供兜底值。
在数据中动态配置
如果需要为不同节点进行不同的配置,可以将配置直接写入节点数据中:
const data = { nodes: [ { id: 'node-1', type: 'circle', style: { size: 60, fill: '#7FFFD4', stroke: '#5CACEE', lineWidth: 2 }, }, ], };调整优先级
默认情况下,graph.setNode()> 全局node配置 > 数据内配置。如果你希望数据中配置的优先级高于全局配置(例如不同节点的描边颜色各不相同),可以在全局配置中使用回调函数动态读取数据中的值,这样数据内配置的值就会被最终采用:
const data = { nodes: [ { id: 'node-1', type: 'circle', style: { size: 60, fill: '#7FFFD4', stroke: '#5CACEE', lineWidth: 2 }, }, ], }; const graph = new Graph({ node: { type: 'circle', style: { // 回调函数接收节点数据,从中读取样式值 stroke: (d) => d.style.stroke || '#5CACEE', lineWidth: 2, }, }, });回调函数(如(d) => d.style.stroke || '#5CACEE')的参数即节点的数据对象,这正体现了上文提到的data与style分离设计:通过回调,全局配置可以针对每个节点的数据动态计算样式,实现"数据驱动样式"的灵活映射。
动态更新节点
G6 支持在运行时动态更新节点的样式和状态:
// 更新单个节点样式 graph.updateNodeData([ { id: 'node-1', style: { fill: 'red', size: 80, }, }, ]); graph.draw(); // 设置节点状态 graph.setElementState('node-1', ['selected']);:::warning{title=注意} 更新节点时,只有指定的属性会被更新,未指定的属性保持不变。 :::
更多与节点相关的 API 请参考 API - 元素操作。
节点状态
节点可以拥有不同的状态,例如选中、高亮、禁用等。通过配置状态样式(state),可以定义节点在不同状态下的显示效果:
const graph = new Graph({ node: { style: { // 默认样式 fill: '#C6E5FF', }, // 状态样式 state: { selected: { fill: '#ffa940', stroke: '#ff7a00', haloStroke: '#ff7a00', }, highlight: { stroke: '#1890ff', lineWidth: 3, }, }, }, });状态系统是实现节点交互效果的基础。例如配合graph.setElementState('node-1', ['selected'])即可让节点切换为选中态的橙色样式;也可以与 click-select、hover-activate 等内置交互行为联动,实现点击选中、悬停高亮等开箱即用的体验。更多状态相关内容可参考 BaseNode.zh.md 及各内置节点文档中的状态配置说明。
从源码理解节点的渲染顺序与默认样式
为了更高效地定制节点,了解BaseNode的渲染机制很有帮助。在 base-node.ts(第 407-426 行)的render()方法中,节点的绘制遵循固定顺序:
- keyShape:主图形(决定节点的整体轮廓,如圆、矩形、多边形);
- halo:光晕,默认关闭(
halo: false),常与状态高亮配合使用,默认haloStrokeOpacity: 0.25、haloLineWidth: 12; - icon:图标,默认启用(
icon: true),图标尺寸默认按主图形尺寸的比例(ICON_SIZE_RATIO)自动推导; - badges:徽标,默认启用(
badge: true),支持多个徽标及背景色板badgePalette; - label:文本标签,默认启用(
label: true),默认放置在节点底部(labelPlacement: 'bottom'),支持labelMaxWidth: '200%'自动换行(labelWordWrap默认关闭); - ports:连接桩,默认启用(
port: true),支持通过ports数组配置多个连接桩及各自位置。
各子形状的 zIndex 层级为:halo(-1)< label(0)< icon(1)< port(2)< badge(3)。理解这一渲染管线后,你在配置style中的labelText、iconSrc、badges、ports等字段时,就能清楚它们各自作用于哪一层图形。
此外,自定义节点时建议直接继承BaseNode(源码注释亦明确推荐),这样只需要实现drawKeyShape()一个抽象方法,halo、icon、badges、label、ports 等通用能力都会被基类自动复用,这也是 自定义节点 文档背后的源码支撑。
小结
G6 的节点能力可以概括为一条清晰的选型路径:大多数场景直接使用 10 种内置节点 → 3D 场景使用 g6-extension-3d 的几何节点 → 组件化场景使用 React 节点 → 特殊需求继承 BaseNode 自定义。配合"graph.setNode()> 全局node配置 > 数据内配置"的优先级体系、回调函数式的样式映射,以及状态样式系统,你可以灵活地构建从静态展示到复杂交互的各类图应用。本文涉及的源码与文档均在仓库中可查证,可进一步阅读:
- 节点实现源码:packages/g6/src/elements/nodes
- 内置节点注册表:packages/g6/src/registry/build-in.ts
- 3D 节点:packages/g6-extension-3d/src/elements
- React 节点:packages/g6-extension-react/src/react-node
- 各节点类型详细文档:packages/site/docs/manual/element/node
- 元素操作 API:packages/site/docs/api/element.zh.md
- 数据可视化
- 前端
- 图表库
【免费下载链接】G6
♾ A Graph Visualization Framework in JavaScript.
相关推荐
G6 边(Edge)完全指南:内置类型、数据结构与配置优先级解析
G6 边(Edge)完全指南:内置类型、数据结构与配置优先级解析 本文围绕图可视化框架 G6 中"边(Edge)"这一基础元素展开,系统讲解边的概念与方向性、六
数据可视化前端图表库G6 矩形节点(Rect Node)实战指南:配置、样式扩展与源码实现解析
G6 矩形节点(Rect Node)实战指南:配置、样式扩展与源码实现解析 矩形节点是 G6 中最基础、应用最广泛的节点形态之一。它以明确的边界和规整的几何形状
数据可视化前端图表库G6 Hexagon Node 六边形节点:样式配置、顶点计算与底层实现解析
G6 Hexagon Node 六边形节点:样式配置、顶点计算与底层实现解析 六边形(Hexagon)是 G6 图可视化框架内置的一种多边形节点,凭借六条等边的
数据可视化前端图表库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考