什么是G6
G6 是一个图可视化引擎。它提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。旨在让关系变得透明,简单。让用户获得关系数据的 Insight。
类似于D3,D3能实现的G6也能实现,但d3的官方文档是非汉语文档。
第一个示例
搭建环境
最近在看react文档,所以我是在react基础上来学习G6。
js
npm install --save @antv/g6
导入G6
js
import G6 from '@antv/g6';
创建容器
在G6进行绘制的时候,会根据id获取对应的节点,将canvas图绘制在这个div中。
js
<div id="mountNode"></div>
绘制图
参考官网入门 快速上手 | G6 (antgroup.com)
Graph
Graph是G6最主要的一个类,通过graph实例就可以直接绘制图片。里面有两个主要API,data和render。
data 渲染数据
-
nodes:定义点集
- x : 横坐标
- y : 纵坐标
-
edges:定义边集
- source : 开始节点
- target : 结束节点
- 一个对象表示一条线
graph.render()
根据提供的数据渲染视图。
一些操作记录
graph.setMode(mode)
将事件交互封装在mode中,可以选择默认default和编辑状态。
js
const graph = new G6.Graph({
container: div,
width: 500,
height: 500,
modes: {
default: [...],
custom: [...]
}
})
graph.setMode('custom')
内置Behavior ------ 与mode搭配使用
参考官网:内置的 Behavior | G6 (antgroup.com)
- 拖动节点:drag-node
- 缩放:zoom-canvas
- 收起和展开:collapse-expand-combo
- 拖拽画布:drag-canvas
js
const graph = new G6.Graph({
container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
width: 800, // Number,必须,图的宽度
height: 500, // Number,必须,图的高度
modes: {
default: [
'drag-canvas',
'zoom - canvas'
],
},
});
自定义交互 registerBehavior
参考官网:自定义交互 Behavior | G6 (antgroup.com)
js
G6.registerBehavior('activate-node',{
...
//返回布局的默认参数
getDefaultCfg() {
return {
multiple: true//是否允许多选,默认为 true?
};
},
//事件绑定
getEvents() {
return {
'node:click': 'onNodeClick',
'canvas:click': 'onCanvasClick'
};
}
//回调 方法实现
onNodeClick(e){}
onCanvasClick(e){}
}
自定义behavior后,使用与内置的相同,都是放在default中。
自定义节点 registerNode
type
在G6中,已经给我们提供了很多内置的节点样式。我们可以在data中对其进行修改。
js
nodes: [
{
id: 'node1', // String,该节点存在则必须,节点的唯一标识
type: 'rect'
},
{
id: 'node2', // String,该节点存在则必须,节点的唯一标识
type: 'star'
},
],
创建
js
G6.registerNode('nodename',{
option:{
style:{}
...
}
})
自定义边 registerEdge
参考官网:自定义边 | G6 (antgroup.com) 注册一个边类型
js
G6.registerEdge('hvh', {})
继承-line为例
line是已经存在的内置边,如果觉得满足不了需求,又不想重新写一个。就可以选择在line的生命周期上穿插一些事件来满足你的需求。
js
import G6 from '@antv/g6';
G6.registerEdge( 'edgeName',
{
draw(cfg, group) {
// 定义的其他方法,都可以在draw里面调用,
// 如 drawShape、drawLabel 等。
},
drawShape(cfg, group) { // },
getLabelStyle(cfg) {
// 根据业务返回 label 的样式
return {};
},
update(cfg, item) {
// 更新绘制的元素
},
}, 'line',);
Item 是一个基类
参考官网:元素实例方法 | G6 (antgroup.com) Node和Edge都会继承与Item上的属性和方法。需了解item的生命周期。
- 更新元素:item.update(model)
- 刷新元素:item.refresh()
- 更新元素位置,避免整体重绘:item.updatePosition(cfg)
- 销毁:item.destroy()
Shape
参考官网:图形样式属性 Shape Attr | G6 (antgroup.com)
如何给节点和边绑定事件
其实就是根据事件绑定回调。
参考文档:基础事件 Event | G6 (antgroup.com)
js
graph.on(eventName, evt => { // 一些操作 })
还可以进行事件的监听
js
graph.on(timingEventName, evt => { // 一些操作 })
如何设置节点和边的状态
graph.setItemState(item, stateName, stateValue)
参考文档:状态 State | G6 (antgroup.com)
参数名 | 类型 | 描述 |
---|---|---|
item | Number | 需要被设置状态的节点/边实例 |
stateName | String | 状态名称,可以是任意字符串 |
stateValue | Booelean | true 代表该状态是被激活,false 代表该状态被灭活 |
js
//定义身体健康状态
//健康
'bodyState:health': {
// keyShape 该状态值下的样式
fill: 'green',
// ... 其他样式
// name 为 shape-name1 的子图形在该状态值下的样式
'shape-name1': {
stroke: '#ccc'
// ... 其他样式
},
// name 为 shape-name2 的子图形在该状态值下的样式
'shape-name2': {
fill: 'red'
// ... 其他样式
}
},
//
// 多值状态 bodyState 为 suspect 时的样式
'bodyState:suspect': {
// ...
},
//生病
// 多值状态 bodyState 为 ill 时的样式
'bodyState:ill': {
// ...
}
// ... 其他状态
根据状态查找元素
graph.findAllByState(type, state)
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
type | string | true | 元素类型,可选值为 node、edge |
state | string | true | 状态名称 |
简单来说就是将item节点的状态(stateName)设置为stateValue,3.4版本之前是只有二值状态的,在这之后就有多值状态了。
js
// 查询所有选中的元素
const nodes = graph.findAllByState('node', 'selected');
实战
data.js
- id: 非必选,内部会自动赋值
- x:500, y:100 该节点在画布中的位置,
- style: 节点样式
- label: 节点文本
- labelCfg: 节点文本样式
- nodeStateStyles: 节点多状态的样式
- anchorPoints: 自定义锚点数量和位置
自定义行为注册工厂
自定义行为、事件、模式通过一个方法(工厂)去注册。(后续陆续完善)
js
// register-factory.js 注册工厂函数
import shape from './shape/exports';
import behavior from './behavior/exports';
import registerEdges from './shape/edges/base-edge';
//注册不分先后
export default G6 => {
// 注册图形
shape(G6);
// 注册行为
behavior(G6);
// 注册边
registerEdges(G6);
};
实例化的时候可以选择哪些事件是否开启。(更灵活)
js
//exports.js 行为暴露 -- 防止全部写在工厂里 显得赘余
import canvasEvent from './canvas-event'; // 画布行为
import selectNode from './select-node'; // 选中节点行为
import deleteItem from './delete-item'; // 删除节点
import activeEdge from './active-edge'; // 激活边
import hoverNode from './hover-node'; // hover节点
import dragNode from './drag-node'; // 拖拽节点
export default G6 => {
canvasEvent(G6);
selectNode(G6);
deleteItem(G6);
activeEdge(G6);
hoverNode(G6);
dragNode(G6);
};
注册行为 behavior:所有的事件
事件一:画布拖拽事件
参考文档: 复合交互及其自定义 Behavior
自定义 Behavior 时,定义事件及处理事件的方法。
触发方式:回调方法 | 'node:click'
: 'onNodeClick',
js
//BehaviorOption.getEvents()
G6.registerBehavior('behaviorName', {
getEvents() {
return {
'node:click': 'onNodeClick',
'edge:click': 'onEdgeClick',
'mousemove': 'onMouseMove'
}
}
}
案例:鼠标按下画布时修改cursor
设置触发事件和回调函数名的定义
js
getEvents () {
return {
'canvas:mousemove': 'onCanvasMouseMove',//鼠标在画布内部移动时不断触发,不能通过键盘触发
'canvas:mousedown': 'onCanvasMouseDown',//鼠标按钮在画布上按下(左键或者右键)时触发,不能通过键盘触发
'canvas:mouseup': 'onCanvasMouseUp',//画布上按下的鼠标按钮被释放弹起时触发,不能通过键盘触发
'canvas:dragend': 'onCanvasDragEnd',//当拖拽完成后触发的事件,此事件作用在被拖曳画布上
};
},
回调函数的实现
js
//设置点击鼠标 拖拽时的鼠标样式
onCanvasMouseMove (e) {
e.target.get('el').style.cursor = 'grab';
},
onCanvasMouseDown (e) {
console.log(e);
e.target.get('el').style.cursor = 'grabbing';
},
onCanvasMouseUp (e) {
e.target.get('el').style.cursor = 'grab';
},
onCanvasDragEnd (e) {
e.target.get('el').style.cursor = 'grab';
this.graph.emit('on-canvas-dragend', e);
},
this.graph.emit('on-canvas-dragend', e);
事件获取画布相对于渲染时的偏移量 避免新增了元素 拖拽进入画布时的位置还是原来的初始值 即更新画布位置 以保证元素相对画布位置准确 参考: