一、G6 图可视化引擎
基于Canvas,提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。旨在让关系变得透明,简单。让用户获得关系数据的 Insight (洞察力)。具备以下 6 种特性:
1)优秀的性能:支持大规模图数据的交互与探索;
2)丰富的元素:内置丰富的节点与边元素,自由配置,支持自定义;
3)可控的交互:内置 10+ 交互行为,支持自定义交互;
4)强大的布局:内置了 10+ 常用的图布局,支持自定义布局;
5)便捷的组件:优化内置组件功能及性能;
6)友好的体验:根据用户需求分层梳理文档,支持 TypeScript 类型推断。
1.1 G6 的架构
参考文献:图可视化之G6 mobile 的前世今生
约束布局:解决的问题是布局过程中图形之间互相有依赖关系互相影响,约束布局把这些依赖关系在约束计算中内聚,外部布局并不感知,比如可以让多图形在同一方向的时候,均分区域大小,这是衍生自 g2 的方法。
状态管理:@antv/g6 中实现,这是处理关系图可视化交互的解法之一,图中的节点或边是有状态的,g6 中默认处理交互状态,也支持自定义的业务状态。
事件模型:@antv/g 中实现,配合状态管理处理交互,g6 内置了事件、也支持自定义事件,g6 上的所有基础图形、Item(节点/边)都能通过事件进行操作。
定位:canvas 中定位获取图形元素,已经在 @antv/g 里实现。由于 canvas 绘制的是一张图,所以“定位”是建立事件模型的基础。
拓展 shape、分组管理、插件 plugin、动画 animation 和布局 layout 的概念已在脑图中呈现。
数据处理部分涉及:
数据转换(@antv/data-set 包中专门实现)
并行计算(我们前面提到为了提供布局渲染效率可以利用 gpu 并行计算,@antv/webgpu 包中独立封装了 webgpu 的接口,涉及到许多依赖,后面会讲)
图算法(@antv/algorithim 包中单独实现,调用 dfs 之类的算法处理 node 和 edge)
1.2 安装与引用
// 安装
npm install --save @antv/g6
// 引用
import G6 from '@antv/g6'
1.3 功能导图
地址
密码:6666
1.4 适用场景
1)高定制能力,搭建图可视化、图分析(图算法)、或图编辑器等应用;
2)大数据量,节点复杂;
3)支持移动端/小程序;
4)支持原生 HTML DOM、React(@antv/g6-react-node 包) 和类 JSX 语法定义节点,不支 vue 组件;
5)智能布局预测(@antv/vis-predict-engine,预测提供的数据应该使用什么布局);
6)状态管理机制(全局、节点、边、子图及状态优先级)。
1.5 案例
代码:
// 容器
<div :id="id" class="igy-canvas"></div>
// 初始化
initDraw() {
this.initData()
this.initGraph()
this.moveToCenter()
this.draw()
}
// 初始化g6画布
initGraph() {
this.graph = initG6(this.id)
this.draw()
}
// initG6()的实现
export default function (container) {
container = document.getElementById(container)
const {
width, height } = container.getBoundingClientRect()
const minimap = new G6.Minimap({
size: [150, 110]
})
const graph = new G6.Graph({
container,
width,
height,
plugins: [minimap],
modes: {
default: ['zoom-canvas', 'drag-canvas', 'drag-node']
},
fill: '#DEE2EA',
defaultNode: {
// 默认节点
type: 'flow-rect', // flow-rect我们自定义的样式名称,告诉画板要引用哪个模块
···
},
defaultEdge: {
// 默认边
type: 'line',
···
},
layout: {
// 布局
type: 'dagre',
···
})
// 注册节点
registerNode()
// 注册边
registerEdge()
return graph
}
// 画图
draw() {
this.clear()
this.graph.data(this.data)
this.graph.render()
// 调用自定义事件
this.initEvent()
}
// 清空画布
clear() {
let menu = document.getElementById('igy-contextMenu')
if (menu) {
menu.style.display = 'none'
}
if (this.graph) {
this.graph.clear()
}
}
注册节点:
function registerNode() {
// 节点背景色
const colors = {
source: '#F1E7FF',
sink: '#E3ECFF'
}
// 节点边框色
const borderColors = {
source: '#D086E2',
sink: '#5F95FF'
}
// 节点图标
const imgs = {
···
}
G6.registerNode(
'flow-rect', // 自定义的节点名称,在上面进行引用
{
shapeType: 'flow-rect',
// 这里涉及到模板的生命周期函数,官网上面有详细的讲解
draw(cfg, group) {
<