一、是什么
官网介绍:G6 是一个图可视化引擎。它提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。旨在让关系变得透明,简单。让用户获得关系数据的 Insight。
二、核心概念
图、 图元素:节点\边\Combo、图布局、交互与事件、动画、插件与工具
1. 图元素:节点\边\Combo
图的元素(Item)包含图上的节点 Node 、边 Edge 和 Combo 三大类。每个图元素由一个或多个 图形(Shape) 组成,且都会有自己的唯一关键图形(keyShape)
图元素属性:一般分为两种,样式属性、其它属性
配置属性的方式:7种
- 实例化图时,配置元素全局属性(全局的, 不能个性化配置) eg: defaultNode, defaultEdge
const graph = new G6.Graph({
// ... // 图的其他配置
// 节点在默认状态下的样式配置(style)和其他配置
defaultNode: {
size: 30, // 节点大小
// ... // 节点的其他配置
// 节点样式配置
style: {
fill: 'steelblue', // 节点填充色
stroke: '#666', // 节点描边色
lineWidth: 1, // 节点描边粗细
},
// 节点上的标签文本配置
labelCfg: {
// 节点上的标签文本样式配置
style: {
fill: '#fff', // 节点标签文字颜色
},
},
},
// 边在默认状态下的样式配置(style)和其他配置
defaultEdge: {
// ... // 边的其他配置
// 边样式配置
style: {
opacity: 0.6, // 边透明度
stroke: 'grey', // 边描边颜色
},
// 边上的标签文本配置
labelCfg: {
autoRotate: true, // 边上的标签文本根据边的方向旋转
},
},
});
- 在数据中配置(不同点、边可以有不同个性化配置,可以覆盖全局静态属性值)
const nodes = remoteData.nodes;
nodes.forEach((node) => {
if (!node.style) {
node.style = {};
}
switch (
node.class // 根据节点数据中的 class 属性配置图形
) {
case 'c0': {
node.type = 'circle'; // class = 'c0' 时节点图形为 circle
break;
}
case 'c1': {
...
}
case 'c2': {
...
}
}
});
graph.data(remoteData);
- 使用update、updateItem
graph.updateItem(node, {
// 节点的样式
style: {
stroke: 'blue',
},
// 节点上文本的样式
labelCfg: {
style: {
fill: '#fff',
fontSize: 12,
},
},
});
- graph.node()
- 必须在render之前调用,优先级最高,如果数据量大,每个节点上需要更新的内容多时,可能会有性能问题
// const data = ...
// const graph = ...
graph.node((node) => {
return {
id: node.id,
type: 'rect',
style: {
fill: 'blue',
},
};
});
graph.data(data);
graph.render();
2. 图布局 Layout
当数据中没有节点位置信息,或者数据中的位置信息不满足需求时,需要借助一些布局算法对图进行布局
3. 图交互Behavior与事件
- 交互行为 Behavior
eg:drag-canvas 、 zoom-canvas
- 交互管理 Mode
一个 mode 是多种行为 Behavior 的组合,允许用户通过切换不同的模式进行交互行为的管理
- 交互状态 State
用户可以为图中的元素(节点/边)设置不同的状态及不同状态下的样式。要达到交互更改元素样式,需要两步
- 实例化图时,通过
nodeStateStyles
和edgeStateStyles
两个配置项可以配置元素在不同状态下的样式。
const graph = new G6.Graph({
// ... // 其他配置项
// 节点不同状态下的样式集合
nodeStateStyles: {
// 鼠标 hover 上节点,即 hover 状态为 true 时的样式
hover: {
fill: 'lightsteelblue',
},
// 鼠标点击节点,即 click 状态为 true 时的样式
click: {
stroke: '#000',
lineWidth: 3,
},
},
// 边不同状态下的样式集合
edgeStateStyles: {
// 鼠标点击边,即 click 状态为 true 时的样式
click: {
stroke: 'steelblue',
},
},
});
- 监听事件并切换元素状态
// 点击节点
graph.on('node:click', (e) => {
// 先将所有当前是 click 状态的节点置为非 click 状态
const clickNodes = graph.findAllByState('node', 'click');
clickNodes.forEach((cn) => {
graph.setItemState(cn, 'click', false);
});
const nodeItem = e.item; // 获取被点击的节点元素对象
graph.setItemState(nodeItem, 'click', true); // 设置当前节点的 click 状态为 true
});
4. 插件与工具
为辅助用户在图上探索,G6 提供了一些辅助工具,其中一部分是插件工具,另一部分是交互工具。 插件工具:Minimap、Grid 交互工具: tooltip // 节点提示框
5. 动画
- 全局动画:G6 的全局动画指通过图实例进行操作时,产生的动画效果
const graph = new G6.Graph({
// ... // 图的其他配置项
animate: true, // Boolean,切换布局时是否使用动画过度,默认为 false
animateCfg: {
duration: 500, // Number,一次动画的时长
easing: 'linearEasing', // String,动画函数
},
});
// 放大、变小动画
G6.registerNode(
'circle-animate',
{
afterDraw(cfg, group) {
// 获取该节点上的第一个图形
const shape = group.get('children')[0];
// 该图形的动画
shape.animate(
(ratio) => {
// 每一帧的操作,入参 ratio:这一帧的比例值(Number)。返回值:这一帧需要变化的参数集(Object)。
// 先变大、再变小
const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
let radius = cfg.size;
if (isNaN(radius)) radius = radius[0];
// 返回这一帧需要变化的参数集,这里只包含了半径
return {
r: radius / 2 + diff,
};
},
{
// 动画重复
repeat: true,
duration: 3000,
easing: 'easeCubic',
},
); // 一次动画持续的时长为 3000,动画效果为 'easeCubic'
},
},
'circle',
); // 该自定义节点继承了内置节点 'circle',除了被复写的 afterDraw 方法外,其他按照 'circle' 里的函数执行。