g6 -TreeGraph案例:任务和任务流关系树图

一、技术背景

React Hook +Antv g6

二、需求

分别以主题--层次--任务--任务流的维度进行树形管理。并且可以已任务的维度进行检索,均展示名称:

image.png

三、选择工具

  • 选择很重要,花了两天时间对比了echarts、antv里的G2、G6。这个过程有点烦,先是尝试echarts里的关系图,毕竟是大厂出来的,API文档还是挺全乎的,也易懂。深入研究后发现graph并不支持重复节点,无法实现需求,弃用。再看看echarts里的tree,echarts里的树图示例真的是好丑。
  • 转入Antv里的G6看看,样例中G6对流程图、树图、文件系统图支持的很好,但有不如意的地方:G6的文档没有echarts完善、专业。但G6的优点也很明显,对此类图支持的很好、灵活,提供丰富的接口。

四、实现

1、安装

// 在项目目录下执行命令安装
npm install --save @antv/g6
// 引入依赖使用
import G6 from '@antv/g6';

2、在componentDidMount生命周期函数中调用接口获取数据

  componentDidMount() {
    this.handleSearch();
  }

3、给子组件传递属性

  render() {
    const { g6Data } = this.state;
    return (
      <>
        
); }

4、在子组件useEffect方法中创建实例,监听g6Data属性是否发生变化,第一次变化创建实例,之后每一次更新数据,并重新渲染树图。

  useEffect(() => {
    if (!isEmpty(g6Data)) {
      if (!graph.current) {
        // 初始化画布
        const container = document.getElementById('job-tree-graph');
        const width = container.scrollWidth;
        const height = container.scrollHeight || 600;
        graph.current = new G6.TreeGraph({
          container: 'job-tree-graph',
          width,
          height,
          modes: {
            default: ['zoom-canvas', 'drag-canvas'],
          },
          defaultNode: {
            type: 'circle',
            size: [20, 20],
            style: {
              stroke: '#73ADD9',
              radius: 5,
              fill: '#73ADD9',
            },
          },
          defaultEdge: {
            type: 'cubic-horizontal',
            style: {
              endArrow: true,
            },
          },
          plugins: [tooltip],
          layout: {
            type: 'indented',
            direction: 'LR',
            dropCap: false,
            indent: 200,
            getHeight: () => {
              return 40;
            },
          },
        });
        graph.current.data(g6Data);
        graph.current.render();
        graph.current.fitView();
        graph.current.moveTo(10, 50);
        if (typeof window !== 'undefined') {
          window.onresize = () => {
            if (!graph.current || graph.current.get('destroyed')) return;
            if (!container || !container.scrollWidth || !container.scrollHeight) return;
            graph.current.changeSize(container.scrollWidth, container.scrollHeight);
          };
        }
      } else {
        // 更新
        graph.current.changeData(g6Data);
        graph.current.paint();
        graph.current.fitView();
        graph.current.moveTo(10, 50);
      }
    }
  }, [g6Data]);

注意,当前组件中需要有一个容器来挂载Graph

5、自定义节点,以任务类型节点为示例

1625411287644.png

6、自定义节点的点击事件,根据节点的类型和状态来判断,是否展开和收缩子节点。

        graph.current.on('node:click', (e) => {
          const {
            objectType,
            layerId,
            themeId,
            jobId,
            collapsed,
            id,
            children = [],
          } = e.item.getModel();
          if (e.target.get('name') === 'collapse-icon') {
            e.item.getModel().collapsed = !collapsed;
            graph.current.setItemState(e.item, 'collapsed', !collapsed);
            if (collapsed && isEmpty(children)) {
              if (objectType === OBJECT_TYPE.LAYER) {
                loadJobNodes({ themeId, layerId }, id, e);
              } else if (objectType === OBJECT_TYPE.JOB) {
                loadFlowNodes({ jobId }, id, e);
              }
            }
            graph.current.layout();
          }
        });

你可能感兴趣的:(g6 -TreeGraph案例:任务和任务流关系树图)