自定义交互 Behavior

G6 除了提供丰富的 内置交互行为 Behavior 外,还提供了自定义交互行为的机制,方便用户开发更加定制化的交互行为。

在交互行为上, G6 主要考虑了三个场景:

  • 展示关系数据;
  • 可视化建模;
  • 图分析。

在这些场景中只要用户可能无法一眼看清楚所有需要的信息,都需要进行交互,例如:

  • 图太大,需要缩放;
  • 单个节点上展示的信息太少,需要通过 tooltip 显示详情;
  • 对节点进行增删改查。

我们无法将所有常用的交互全部内置到 G6 中。由于场景不一样,业务不一样,同样的目的需要的交互都不一样:

  • 有些系统需要从工具栏上点击后添加节点,有些系统需要从面板栏上拖出出新的节点;
  • 有的业务添加边需要从锚点上拖拽出来,而有些直接点击节点后就可以拖拽出边;
  • 有些边可以连接到所有节点上,而有些边不能连接到具体某个节点的某个锚点上;
  • 所有的交互的触发、持续、结束都要允许能够进行个性化的判定。

我们可以看到在图上的交互是繁杂多变的。各种冲突、各种配置项会让用户和开发者疲于应对。出于这些考虑, G6 提供了一套非常简单而灵活的机制来实现交互。

Behavior 的生命周期

为实现交互,首先需要了解交互的生命周期。交互起源于用户在系统上的所有事件,是否允许交互发生同事件密切相关。所以我们看到交互的生命周期,即操作事件的过程如下:

  • 绑定事件;
  • 触发事件;
  • 持续事件;
  • 结束事件;
  • 移除事件。

自定义交互 registerBehavior

通过 G6.registerBehavior 自定义 Behavior。下面代码实现了名为 'activate-node'的交互行为,在终端用户点击节点时,置该节点的 active 状态为 true;再次点击或点击画布时,置该节点的 active 状态为 false

注意:

  • 下面代码仅设置了不同交互后节点的状态,没有指定这些状态下节点的样式。若需要根据节点状态变化它的样式,参见 配置不同 State 样式
  • 自定义 Behavior 时,可选的方法请参数 Behavior API
  • getEvent 返回该 Behavior 所需监听事件的对象,G6 中支持的所有事件,请参考 Event API
  1. G6.registerBehavior('activate-node', {
  2. getDefaultCfg() {
  3. return {
  4. multiple: true
  5. };
  6. },
  7. getEvents() {
  8. return {
  9. 'node:click': 'onNodeClick',
  10. 'canvas:click': 'onCanvasClick'
  11. };
  12. }
  13. onNodeClick(e) {
  14. const graph = this.graph;
  15. const item = e.item;
  16. if (item.hasState('active')) {
  17. graph.setItemState(item, 'active', false);
  18. return;
  19. }
  20. // this 上即可取到配置,如果不允许多个active,先取消其他节点的active状态
  21. if (!this.multiple) {
  22. this.removeNodesState();
  23. }
  24. // 置点击的节点状态为active
  25. graph.setItemState(item, 'active', true);
  26. },
  27. onCanvasClick(e) {
  28. // shouldUpdate可以由用户复写,返回 true 时取消所有节点的active状态
  29. if (this.shouldUpdate(e)) {
  30. removeNodesState();
  31. }
  32. },
  33. removeNodesState() {
  34. graph.findAllByState('active').forEach(node => {
  35. graph.setItemState(node, 'active', false);
  36. });
  37. }
  38. });

使用自定义的 Behavior

有了上面代码定义的名为 'activate-node' 的 Behavior 以后,在实例化 Graph 时,在 modes 中将其配置到默认或其他行为模式中。下面代码将其配置到了默认行为模式中,在默认模式下,该行为将会生效。

  1. const graph = new G6.Graph({
  2. container: 'mountNode',
  3. width: 500,
  4. height: 500,
  5. modes: {
  6. // 定义的 behavior 指定到这里,就可以支持Behavior中定义的交互
  7. default: ['activate-node'],
  8. },
  9. });