G6版本: 4.8.21
此部分主要包括以下4点:监听和事件绑定、交互行为Behavior、交互模式Mode、状态State
一、监听和事件绑定
除了 内置交互行为 Behavior 和 交互模式 Mode 搭配的事件管理方式外,G6 提供了直接的单个事件、时机的监听方法,可以监听画布、节点、边、以及各函数被调用的时机等
// 全局事件: 只要在画布上范围内发生均会被触发,如 `mousedown`,`mouseup`,`click`,`mouseenter`,`mouseleave` 等。
graph.on('click', (ev) => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
// canvas事件: 只在 canvas 空白处被触发,如 `canvas:mousedown`,`canvas:click` 等,以`canvas:eventName` 为事件名称
graph.on('canvas:click', (ev) => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
// 节点/边/combo 上的事件: 例如 `node:mousedown`,`edge:click`, `combo:click` 等
graph.on('node:click', (ev) => {
const node = ev.item; // 被点击的节点元素
const shape = ev.target; // 被点击的图形,可根据该信息作出不同响应,以达到局部响应效果
// ... do sth
});
graph.on('edge:click', (ev) => {
const edge = ev.item; // 被点击的边元素
const shape = ev.target; // 被点击的图形,可根据该信息作出不同响应,以达到局部响应效果
// ... do sth
});
graph.on('combo:click', (ev) => {
const combo = ev.item; // 被点击 combo 元素
const shape = ev.target; // 被点击的图形,可根据该信息作出不同响应,以达到局部响应效果
// ... do sth
});
// 图形上的事件: 指定图形上的事件
graph.on('circle-shape:click', (ev) => {
const shape = ev.target; // 被点击的图形
// ... do sth
});
// 时机事件: 时机事件指渲染、视口变换、元素增删改、数据变换等时机
graph.on('afterrender', (ev) => {
// ... do sth
});
// 自定义事件: on 监听,emit触发
graph.on('some-custom-event-name', (ev) => {
// ... do sth
});
graph.emit('some-custom-event-name', {
// some params
})
二、Behavior
- 14个内置Behavior
drag-combo // 拖动 Combo
collapse-expand-combo // 收起和展开 Combo
drag-canvas // 拖拽画布
scroll-canvas // 滚轮滚动画布
zoom-canvas // 缩放画布
drag-node // 拖拽节点,或拖动 Combo 中的节点
click-select // 点击选中节点,再次点击节点或点击 Canvas 取消选中状态
tooltip // 节点文本提示
edge-tooltip // 边文本提示
activate-relations // 当鼠标移到某节点时,突出显示该节点以及与其直接关联的节点和连线
brush-select // 拖动框选节点
lasso-select // 自由圈选
collapse-expand // 只适用于树图,展开或收起子树
create-edge // 通过交互创建边
shortcuts-call // 允许终端用户使用键盘组合键调用 Graph 的函数,例如按下键盘上的 control 与 1,对图进行适应画布。
- 交互的声明周期
- 绑定事件;
- 触发事件;
- 持续事件;
- 结束事件;
- 移除事件。
- 自定义Behavior
G6.registerBehavior('activate-node', {
getDefaultCfg() {
return {
multiple: true
};
},
getEvents() {
return {
'node:click': 'onNodeClick',
'canvas:click': 'onCanvasClick'
};
}
onNodeClick(e) {
const graph = this.graph;
const item = e.item;
if (item.hasState('active')) {
graph.setItemState(item, 'active', false);
return;
}
// this 上即可取到配置,如果不允许多个 'active',先取消其他节点的 'active' 状态
if (!this.multiple) {
this.removeNodesState();
}
// 置点击的节点状态 'active' 为 true
graph.setItemState(item, 'active', true);
},
onCanvasClick(e) {
// shouldUpdate 可以由用户复写,返回 true 时取消所有节点的 'active' 状态,即将 'active' 状态置为 false
if (this.shouldUpdate(e, self)) {
removeNodesState();
}
},
removeNodesState() {
graph.findAllByState('node', 'active').forEach(node => {
graph.setItemState(node, 'active', false);
});
}
});
三、Mode
交互模式 Mode,它是图上交互行为 Behavior 的管理机制。一个图上可以有存在多种交互模式,每个交互模式包含多种交互行为 Behavior
- 配置mode
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500,
modes: {
// 支持的 behavior
default: ['drag-canvas', 'zoom-canvas'],
edit: ['click-select'],
},
});
- 切换mode
graph.setMode('edit'); // 默认graph会使用default模式
- 编辑已有的mode addBehaviors, removeBehaviors, updateBehavior
// 向 default 模式中添加名为 drag-canvas 的行为,并使用行为的默认配置
graph.addBehaviors('drag-canvas', 'default');
// 从 default 模式中移除名为 drag-canvas 的行为
graph.removeBehaviors('drag-canvas', 'default');
// 向 edit 模式中添加名为 drag-canvas 的行为,并定义个性化配置
graph.addBehaviors(
{
type: 'drag-canvas',
direction: 'x',
},
'edit',
);
// 一次向 default 模式中添加多个行为
graph.addBehaviors(['drag-canvas', 'zoom-canvas'], 'default');
// 一次从 default 模式中移除多个行为
graph.removeBehaviors(['drag-canvas', 'zoom-canvas'], 'default');
// 更新 'default' 模式下的 behavior 'zoom-canvas'
graph.updateBehavior('zoom-canvas', { sensitivity: 1.5, enableOptimize: true}, 'default');
// 更新 'select' 模式下的 behavior 'click-select'
graph.updateBehavior('click-select', { trigger: 'ctrl' }, 'select');
四、状态 State
G6 中的 state,指的是节点或边的状态,包括交互状态和业务状态两种。
何时使用 state
判断是否该使用 state 的原则很简单,从交互和业务两个层面来看:
- 某个交互动作要改变节点或边的样式及属性;
- 呈现给用户的内容会根据数据改变(如 1 代表成功,0 代表失败)。
满足上述条件其一,则应该使用 state。
状态的类型
状态可以是二值的,也可以是多值的
graph.setItemState(item, stateName, stateValue)
graph.setItemState(item, 'stateName', true);
调用的时机
可以在监听函数graph.on中被调用,也可以在自定义 Behavior 中调用,或在其他任意地方用于响应交互/业务的变化
// graph.on 在回调函数中使定义的交互状态 hover 生效
graph.on('node:mouseenter', (evt) => {
const { item } = evt;
graph.setItemState(item, 'hover', true);
});
graph.on('node:mouseleave', (evt) => {
const { item } = evt;
graph.setItemState(item, 'hover', false);
});
// 在自定义 Behavior 中使定义的交互状态 selected 生效。
G6.registerBehavior('nodeClick', {
getEvents() {
return {
'node:click': 'onClick',
};
},
onClick(e) {
e.preventDefault();
if (!this.shouldUpdate.call(this, e)) {
return;
}
const { item } = e;
const graph = this.graph;
graph.setItemState(item, 'selected', true);
},
});
配置state样式
graph.setItemState使某些状态在图元素(节点/边)上被激活/灭活,仅仅是为该元素做了某些状态的标识。我们还需要对不同状态设置不同样式。
有三种方式配置不同状态的样式
- 在实例化 Graph 时,通过
nodeStateStyles
和edgeStateStyles
对象定义; - 在节点/边数据中,在
stateStyles
对象中定义状态; - 在自定义节点/边时,在 options 配置项的
stateStyles
对象中定义状态。
// 实例化 Graph 时定义 state 样式
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
type: 'diamond',
style: {
// 默认状态样式
fill: 'blue',
// ... 其他样式
},
},
nodeStateStyles: {
// 二值状态 hover 为 true 时的样式
hover: {
// keyShape 的状态样式
fill: '#d3adf7',
// name 为 node-label 的子图形在该状态值下的样式
'node-label': {
fontSize: 15
},
},
// 多值状态 bodyState 为 health 时的样式
'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': {
// ...
}
},
defaultEdge: {
// ...
},
edgeStateStyles: {
// ...
},
});
// 在节点/边数据中定义 state 样式
const data = {
nodes: [
{
id: 'node1',
stateStyles: {
},
},
{
id: 'node2',
stateStyles: {
//...
},
},
],
edges: [
{
source: 'node1',
target: 'node2',
styles: {
// 默认样式
},
stateStyles: {
//... 见上方例子
},
},
],
};
// 自定义节点和边时定义 state 样式
G6.registerNode('customShape', {
// 自定义节点时的配置
options: {
size: 60,
style: {
lineWidth: 1
},
stateStyles: {
// ... 见上方例子
}
}
}
更新状态配置
updateItem
更新状态样式配置是指更改在配置 state 样式中设置的某状态下的样式配置
graph.updateItem(item, {
// 修改默认样式
style: {
stroke: 'green',
// 修改 name 为 'node-label' 的子图形的默认样式
'node-label': {
stroke: 'yellow',
},
},
stateStyles: {
// 修改 hover 状态下的样式
hover: {
opacity: 0.1,
// 修改 name 为 'node-label' 的子图形 hover 状态下的样式
'node-text': {
stroke: 'blue',
},
},
},
});
取消状态
graph.setItemState(item, 'bodyState', 'health');
// 取消单个状态
graph.clearItemStates(item, 'selected');
graph.clearItemStates(item, ['selected']);
// 取消多个状态
graph.clearItemStates(item, ['bodyState:health', 'selected', 'active']);