概述

G6 是一个纯 JS 库,不与任何框架耦合,也就是可以在任何前端框架中使用,如 React、Vue、Angular 等。由于我们目前使用的大多数都是 React 技术栈,所以在这里我们就介绍一下如何在 React 中使用 G6。

在 React 中使用 G6,和在 HTML 中使用基本相同,唯一比较关键的区分就是在实例化 Graph 时,要保证 DOM 容器渲染完成,并能获取到 DOM 元素

在该示例中,我们以一个简单的流程图为例,实现如下的效果。
如何在 React 中使用 G6 - 图1

功能及实现

案例包括以下功能点:

  • 自定义节点;
  • 自定义边;
  • 节点的 tooltip;
  • 边的 tooltip;
  • 节点上面弹出右键菜单;
  • tooltip 及 ContextMenu 如何渲染自定义的 React 组件。

在 React 中,通过 ref.current获取到真实的 DOM 元素。

  1. import React, { useEffect, useState } from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { data } from './data';
  4. import G6 from '@antv/g6';
  5. export default function () {
  6. const ref = React.useRef(null);
  7. let graph = null;
  8. useEffect(() => {
  9. if (!graph) {
  10. graph = new G6.Graph({
  11. container: ref.current,
  12. width: 1200,
  13. height: 800,
  14. modes: {
  15. default: ['drag-canvas'],
  16. },
  17. layout: {
  18. type: 'dagre',
  19. direction: 'LR',
  20. },
  21. defaultNode: {
  22. type: 'node',
  23. labelCfg: {
  24. style: {
  25. fill: '#0000A6',
  26. fontSize: 10,
  27. },
  28. },
  29. style: {
  30. stroke: '#72CC4A',
  31. width: 150,
  32. },
  33. },
  34. });
  35. }
  36. graph.data(data);
  37. graph.render();
  38. }, []);
  39. return <div ref={ref}></div>;
  40. }

G6 中渲染 React 组件

节点和边的 tooltip、节点上的右键菜单,G6 中内置的很难满足样式上的需求,这个时候我们就可以通过渲染自定义的 React 组件来实现。

Tooltip 和 ContextMenu 都是普通的 React 组件,样式完全由用户控制。交互过程中,在 G6 中需要做的事情就是确定何时渲染组件,以及渲染到何处。在 G6 中获取到是否渲染组件的标识值和渲染位置后,这些值就可以使用 React state 进行管理,后续的所有工作就全部由 React 负责了。

  1. // 边 tooltip 坐标
  2. const [showNodeTooltip, setShowNodeTooltip] = useState(false);
  3. const [nodeTooltipX, setNodeToolTipX] = useState(0);
  4. const [nodeTooltipY, setNodeToolTipY] = useState(0);
  5. // 监听 node 上面 mouse 事件
  6. graph.on('node:mouseenter', (evt) => {
  7. const { item } = evt;
  8. const model = item.getModel();
  9. const { x, y } = model;
  10. const point = graph.getCanvasByPoint(x, y);
  11. setNodeToolTipX(point.x - 75);
  12. setNodeToolTipY(point.y + 15);
  13. setShowNodeTooltip(true);
  14. });
  15. // 节点上面触发 mouseleave 事件后隐藏 tooltip 和 ContextMenu
  16. graph.on('node:mouseleave', () => {
  17. setShowNodeTooltip(false);
  18. });
  19. return <div ref={ref}>{showNodeTooltip && <NodeTooltips x={nodeTooltipX} y={nodeTooltipY} />}</div>;

完整的案例源码请戳 「这里」。