关于react.js:React中使用AntV-G6

38次阅读

共计 4340 个字符,预计需要花费 11 分钟才能阅读完成。

AntV G6:G6 是一个简略、易用、齐备的图可视化引擎,它在高定制能力的根底上,提供了一系列设计优雅、便于应用的图可视化解决方案。能帮忙开发者搭建属于本人的图可视化、图剖析、或图编辑器利用。官网

⚡️ AntV G6 的引入

  1. 我的项目中应用 npm 对包引入

    npm install –save @antv/g6

  2. 从新载入依赖

    yarn install

  3. 须要应用到 G6 的 js 文件 中引入 G6

    import G6 from ‘@antv/g6’;

自此,筹备工作完结,上面开始应用 G6 绘制须要的关系图,以力导向图为例形容一对多、一对一的关系。

🔨 AntV G6 的应用

  1. 创立容器:在 HTML 中创立一个用于包容 G6 绘制的图的容器,通常为 div 标签。G6 在绘制时会在该容器下追加 canvas 标签,而后将图绘制在其中。
    ref:在 React 中,能够通过 ref.current 获取到实在的 DOM 元素。Forwarding Refs(官网文档)

    <div ref={ref} id=”test”/>

  2. 创立关系图:创立关系图(实例化)时,至多须要为图设置容器、宽和高。其余请参考图例对应的 API 以及官网 API 文档,按需配置。

       graph = new G6.Graph({
         container: ref.current,
         width: width < 1000 ? 387 : width,
         height: width < 1000 ? 220 : 550,
         layout: {
           type: 'force',
           preventOverlap: true,
           linkDistance: (d) => {if (d.source.id === 'node0') {return 10;}
             return 80;
           },
           nodeStrength: (d) => {if (d.isLeaf) {return 200;}
             return -500;
           },
           edgeStrength: (d) => {if (d.source.edgeStrength) {return 0.1;}
             return 0.8;
           },
         },
         defaultNode: {color: '#5B8FF9',},
         edgeStateStyles: {
           highlight: {stroke: '#5B8FF9' // 这个色彩能够依据集体爱好进行批改}
         },
         modes: {default: ['drag-canvas', 'zoom-canvas'],
         },
       });
  3. 数据处理及筹备:依据所需图表的数据格式,对数据进行解决。
  4. 配置数据源并渲染:

    graph.data(data); // 读取 Step 2 中的数据源到图上
    graph.render(); // 渲染图

🚀AntV G6 的根本应用论述完后,须要留神在 React 中,G6 与 AntV L7 及 AntV G2,BizCharts 有所不同,AntV G6 在应用过程中须要拜访节点,将其图形作为组件应用时,如果疏忽这一点,则会呈现问题。React 中应用 G6(官网文档)

📃AntV G6 在 React 中留神

  1. 将渲染 G6 图形的 Demo 作为匿名函数返回,同时函数 return 的应为上文创立的容器,在其余 js 文件中调用 Demo 时作为组件,同时传入的参数为匿名函数的形参。
  2. 上文中第二步:“创立关系图”中生成的实例应在副作用 useEffect 中定义。
  3. 因为在 CompotentDidMount 中获取数据,当渲染 Demo 时可能会存在数据并未失去响应便渲染 Demo 导致报错,解决办法如下:
    {deviceData.length ? <G6Picture g6Data={deviceData}/> : <></>}

🏆 实现成果

📦残缺代码及局部解释如下:

Demo.js

import G6 from '@antv/g6';
import React, {useEffect} from "react";
import groupBy from 'lodash/groupBy'
import router from "umi/router";

function dealData(data) {// 数据处理函数
  const dataGroup = groupBy(data, (item) => [item.chipGroupName])
  const nodes = [];
  const edges = [];
  let index = 0;
  nodes.push({id: `node${index}`, size: 90, label: "芯片组治理", edgeStrength: true})
  for (const key in dataGroup) {
    index += 1;
    nodes.push({id: `node${index}`, size: 60, label: key, edgeStrength: false, isLeaf: true})
    edges.push({source: `node0`, target: `node${index}`, label: '芯片', routerFlag: 0})
    if (dataGroup[key]) {
      const indexTemp = index;
      dataGroup[key].map((item) => {
        index += 1;
        nodes.push({id: `node${index}`, size: 40, label: item.name, edgeStrength: false})
        edges.push({source: `node${indexTemp}`, target: `node${index}`, label: "产品", routerFlag: 1})
      })
    }
  }
  const returnData = {nodes: [...nodes],
    edges: [...edges],
  }
  return returnData;
}

export default function (props) {//props 为传入的参数
  const ref = React.useRef(null)
  let graph = null;
  useEffect(() => {const {g6Data} = props;
    const data = dealData(g6Data);
    const width = document.getElementById('test').clientWidth;// 获取以后宽度
    if (!graph) {
      graph = new G6.Graph({// 生成关系图实例
        container: ref.current,// 获取实在的 DOM 节点
        width: width < 1000 ? 387 : width,// 依据所需大小定义高度、宽度
        height: width < 1000 ? 220 : 550,
        layout: {// 依据要求所需及官网 API 文档配置
          type: 'force',
          preventOverlap: true,
          linkDistance: (d) => {if (d.source.id === 'node0') {return 10;}
            return 80;
          },
          nodeStrength: (d) => {// 依据要求所需及官网 API 文档配置
            if (d.isLeaf) {return 200;}
            return -500;
          },
          edgeStrength: (d) => {// 依据要求所需及官网 API 文档配置
            if (d.source.edgeStrength) {return 0.1;}
            return 0.8;
          },
        },
        defaultNode: {// 依据要求所需及官网 API 文档配置
          color: '#5B8FF9',
        },
        edgeStateStyles: {// 依据要求所需及官网 API 文档配置
          highlight: {stroke: '#5B8FF9' // 这个色彩能够依据集体爱好进行批改}
        },
        modes: {// 依据要求所需及官网 API 文档配置
          default: ['drag-canvas', 'zoom-canvas'],
        },
      });
    }
    const {nodes} = data;
    graph.data({// 绑定数据
      nodes,
      edges: data.edges.map((edge, i) => {edge.id = `edge${i}`;
        return Object.assign({}, edge);
      }),
    });
    graph.render();// 渲染图形
// 上面为交互事件配置及操作函数
    graph.on('node:dragstart', (e) => {graph.layout();
      refreshDragedNodePosition(e);
    });
    graph.on('node:drag', (e) => {refreshDragedNodePosition(e);
    });
    graph.on('node:dragend', (e) => {e.item.get('model').fx = null;
      e.item.get('model').fy = null;
    });
    graph.zoom(width < 1000 ? 0.7 : 1, {x: 300, y: 300});
    graph.on('node:mouseenter', (ev) => {
      const node = ev.item;
      const edges = node.getEdges();
      const model = node.getModel();
      const size = model.size * 1.2;
      graph.updateItem(node, {size,});
      edges.forEach((edge) => {graph.setItemState(edge, 'highlight', true)
      });
    });
    graph.on('node:click', (e) => {router.push({pathname: `/DeviceSetting/ChipsetManagement`})
    });
    graph.on('node:mouseleave', (ev) => {
      const node = ev.item;
      const edges = node.getEdges();
      const model = node.getModel();
      const size = model.size / 1.2;
      graph.updateItem(node, {size,});
      edges.forEach((edge) => graph.setItemState(edge, 'highlight', false));
    });

    function refreshDragedNodePosition(e) {const model = e.item.get('model');
      model.fx = e.x;
      model.fy = e.y;
    }
  }, []);
  return <>
    <div ref={ref} id="test"/>
  </>;
};

具体应用 Demo 的 js 文件:

import G6Picture from './Demo'
render(return(<>
            {deviceData.length ? <G6Picture g6Data={deviceData}/> : <></>}
        </>))

正文完
 0