概述

本文档主要向大家介绍如何在 G6 中拓展交互行为,如有描述不清楚、有误的地方欢迎大家在 GitHub 上提 Issue 指正,或是直接 PR 修缮。根据您的贡献度,我们会视情况将您加入 AntV 共建者名录 :-)

简单交互

如果你做的是一个仅用于展示,或者简单分析的图可视化场景,那么你只需要监听一些简单的事件,再配合一些简单的信号量,基本能够满足你的需求,例如:
自定义交互 - 图1

  1. const data = {
  2. nodes: [{
  3. id: 'node1',
  4. x: 100,
  5. y: 200
  6. },{
  7. id: 'node2',
  8. x: 300,
  9. y: 200
  10. }],
  11. edges: [{
  12. id: 'edge1',
  13. target: 'node2',
  14. source: 'node1'
  15. }]
  16. };
  17. const graph = new G6.Graph({
  18. container: 'mountNode',
  19. width: 500,
  20. height: 500
  21. });
  22. graph.read(data);
  23. let node;
  24. let dx;
  25. let dy;
  26. graph.on('node:dragstart', ev=>{
  27. const {item} = ev;
  28. const model = item.getModel();
  29. node = item;
  30. dx = model.x - ev.x;
  31. dy = model.y - ev.y;
  32. });
  33. graph.on('node:drag', ev=>{
  34. node && graph.update(node, {
  35. x: ev.x+dx,
  36. y: ev.y+dy
  37. });
  38. });
  39. graph.on('node:dragend', ev=>{
  40. node = undefined;
  41. });

复杂交互

如果你是要做一个类似图编辑器的复杂交互的场景,你可能就要考虑如何隔离不同行为下,同一事件的相互影响。对于复杂交互的场景,G6 给出了一套,事件 -> 行为 -> 模式,的解决方案。具体使用方法如下:
自定义交互 - 图2

  1. // 注册鼠标进入节点变红的行为
  2. G6.registerBehaviour('mouseEnterFillRed', graph=>{
  3. graph.behaviourOn('node:mouseenter', ev=>{
  4. graph.update(ev.item, {
  5. color: 'red'
  6. });
  7. });
  8. });
  9. // 注册鼠标进入节点变绿的行为
  10. G6.registerBehaviour('mouseEnterFillGreen', graph=>{
  11. graph.behaviourOn('node:mouseenter', ev=>{
  12. graph.update(ev.item, {
  13. color: 'green'
  14. });
  15. });
  16. });
  17. // 注册鼠标移出节点变原色的行为
  18. G6.registerBehaviour('mouseLeaveResetFill', graph=>{
  19. graph.behaviourOn('node:mouseleave', ev=>{
  20. graph.update(ev.item, {
  21. color: '#2f54eb'
  22. });
  23. });
  24. });
  25. const data = {
  26. nodes: [{
  27. id: '事件',
  28. x: 80,
  29. y: 150,
  30. },{
  31. id: '行为',
  32. x: 200,
  33. y: 150
  34. },{
  35. id: '模式',
  36. x: 320,
  37. y: 150
  38. }],
  39. edges: [{
  40. source: '事件',
  41. target: '行为',
  42. label: '组成'
  43. },{
  44. source: '行为',
  45. target: '模式',
  46. label: '组成'
  47. }]
  48. };
  49. let mode = 'red';
  50. const graph = new G6.Graph({
  51. container: 'mountNode',
  52. width: 500,
  53. height: 500,
  54. modes: {
  55. red: ['mouseEnterFillRed', 'mouseLeaveResetFill'],
  56. green: ['mouseEnterFillGreen', 'mouseLeaveResetFill']
  57. },
  58. mode,
  59. });
  60. graph.node({
  61. label(model) {
  62. return model.id;
  63. }
  64. });
  65. graph.edge({
  66. style() {
  67. return {
  68. endArrow: true
  69. };
  70. }
  71. });
  72. graph.read(data);
  73. // 点击按钮切换模式
  74. document.getElementById('changeMode').onclick = () => {
  75. if(mode === 'red') {
  76. graph.changeMode('green');
  77. mode = 'green';
  78. } else {
  79. graph.changeMode('red');
  80. mode = 'red';
  81. }
  82. };

从上面的例子可以看出,我们可以通过 行为和模式 实现了在不引入任何信号量的前提下,将两个 mouseenter 事件的交互进行了隔离。

特别注意:行为注册中,我们需要用 behaviourOn() 而不是直接用 on() 来绑定事件。