antv/g6在vue中的使用

<template>
  <div id="mountNode"></div>
</template>

<script>
import G6 from '@antv/g6';
import { getAction } from '@/api/manage';
let graph;
let showNodes = [];
let showEdges = [];
let curShowNodes = [];
let curShowEdges = [];
let nodes = [];
let edges = [];
let nodeMap = new Map();
let edgesMap = new Map();
let curShowNodesMap = new Map();
let highlighting = false;
let currentFocus;
let width = 800;
let height = 800;
const Colors = { noun: '#009793', adj: '#f2e394', v: '#d96459', adv: '#f2ae72' };
const layoutCfg = {
  type: 'force',
  nodeSize: (d) => {
    return d.size / 2 + 5;
  },
  nodeStrength: 2500,
  collideStrength: 0.8,
  alphaDecay: 0.01,
  preventOverlap: true,
  onTick: () => {
    // console.log(11111);
    const nodeItems = graph.getNodes();
    const height = graph.get('height');
    const width = graph.get('width');
    const padding = 10;
    nodeItems.forEach((item) => {
      const model = item.getModel();
      if (model.x > width - padding) model.x = width - padding;
      else if (model.x < padding) model.x = padding;

      if (model.y > height - padding) model.y = height - padding;
      else if (model.y < padding) model.y = padding;
    });
  },
};






export default {
  name: "lawyerDemo",
  components: {},
  data() {
    return{
    }
  },
  methods:{
    mapNodeSizeAndFontSize(nodes, propertyName, visualRange){
      // console.log(nodes,'---------------------------');
      let minp = 9999999999;
      let maxp = -9999999999;
      nodes.forEach((node) => {
        // console.log(node[propertyName],'propertyNamepropertyNamepropertyName')
        const propertyValue = node[propertyName] > 5000 ? 5000 : node[propertyName];
        minp = propertyValue < minp ? propertyValue : minp;
        maxp = propertyValue > maxp ? propertyValue : maxp;
      });
      const rangepLength = maxp - minp;
      const rangevLength = visualRange[1] - visualRange[0];
      nodes.forEach((node) => {
        const propertyValue = node[propertyName] > 5000 ? 5000 : node[propertyName];
        node.size = ((propertyValue - minp) / rangepLength) * rangevLength + visualRange[0];
        if (node.labelCfg && node.labelCfg.style) {
          const textLength = node.label.length;
          let fontSize = (1.3 * node.size) / textLength;
          if (fontSize < 11) fontSize = 11;
          node.labelCfg.style.fontSize = fontSize;
        }
      });
    },
    refreshDragedNodePosition(e) {
      // console.log(e,'model')
      const model = e.item.get('model');
      model.fx = e.x;
      model.fy = e.y;
    },
    G6Fun(){
      graph.on('node:dragstart', (e) => {
        graph.layout();
        this.refreshDragedNodePosition(e);
      });
      graph.on('node:drag', (e) => {
        this.refreshDragedNodePosition(e);
      });
      graph.on('node:dragend', (e) => {
        e.item.get('model').fx = null;
        e.item.get('model').fy = null;
      });

      graph.on('node:click', (e) => {
        // console.log(e);
        curShowNodes = [];
        curShowEdges = [];
        const item = e.item;
        const model = item.getModel();
        // console.log(model);
        if (model.neighbor) {
          return;
        }
        // if clicked a root, hide unrelated items and show the related items
        if (!model.neighbor) {
          const layoutController = graph.get('layoutController');
          const forceLayout = layoutController.layoutMethods[0];
          forceLayout.forceSimulation.stop();
          // light the level 0 nodes
          // console.log(showNodes);
          // console.log(0.5 * width);
          showNodes.forEach((snode) => {
            if (snode.x < 0.5 * width) {
              snode.x = 300;
            } else {
              snode.x = width - 300;
            }
          });
          model.x = width / 2;
          model.y = height / 2;
          // animatively hide the items which are going to disappear
          if (curShowEdges.length) {
            curShowEdges.forEach((csedge) => {
              const item = graph.findById(csedge.id);
              item && graph.setItemState(item, 'disappearing', true);
            });
          }
          curShowNodes.forEach((csnode) => {
            const item = graph.findById(csnode.id);
            item && graph.setItemState(item, 'disappearing', true);
          });
          graph.positionsAnimate();

          // reset curShowNodes nad curShowEdges
          curShowNodes = [];
          curShowEdges = [];

          // click on the same node which is the current focus node, hide the small nodes, change the layout parameters to roots view
          if (currentFocus && currentFocus.id === model.id) {
            currentFocus = undefined;
            layoutController.layoutCfg.nodeStrength = 100;
            layoutController.layoutCfg.collideStrength = 0.8;
            layoutController.layoutCfg.alphaDecay = 0.01;
          } else {
            // click other focus node, hide the current small nodes and show the related nodes
            currentFocus = model;
            // change data after the original items disappearing
            const layoutController = graph.get('layoutController');
            layoutController.layoutCfg.nodeStrength = () => {
              return -80;
            };
            layoutController.layoutCfg.collideStrength = 0.2;
            layoutController.layoutCfg.linkDistance = (d) => {
              if (!d.source.neighbor && !d.target.neighbor) return 150;
              return 80;
            };
            layoutController.layoutCfg.edgeStrength = () => {
              return 2;
            };

            curShowNodesMap = new Map();
            // find the nodes which are the descendants of clicked model
            edges.forEach((edge) => {
              let nodeId = '';
              let node;
              if (edge.source === model.id) {
                nodeId = edge.target;
              } else if (edge.target === model.id) {
                nodeId = edge.source;
              } else {
                return;
              }
              nodes.forEach((tnode) => {
                if (tnode.id === nodeId) {
                  node = tnode;
                }
              });
              if (!node) return;
              const randomAngle = Math.random() * 2 * Math.PI;
              node.x = model.x + (Math.cos(randomAngle) * model.size) / 2 + 10;
              node.y = model.y + (Math.sin(randomAngle) * model.size) / 2 + 10;
              // const dist = (model.x - node.x) * (model.x - node.x) + (model.y - node.y) * (model.y - node.y);

              if (!node.style) node.style = {};
              node.style.lineWidth = 0;
              node.style.opacity = 1;
              if (node.neighbor) {
                node.type = 'animate-circle';
                node.label = node.text;
                const color = model.style.fill;
                node.color = color;
                node.style.fill = '#fff';
                node.style.lineWidth = 1;
                node.size = 30;
                node.labelCfg = {
                  style: {
                    fontSize: 13,
                    lineHeight: 19,
                    fill: '#697B8C',
                  },
                  position: 'center',
                };
              }
              curShowNodes.push(node);
              curShowNodesMap.set(node.id, node);

              // add the edge connect from model to node which exists in edges
              const edgeId = `${model.id}-${node.id}`;
              const medge = edgesMap.get(edgeId);
              if (medge) {
                medge.color = model.color;
                curShowEdges.push(medge);
              }
            });

            edges.forEach((edge) => {
              if (edge.source === model.id || edge.target === model.id) {
                curShowEdges.push(edge);
              }
            });
          }
          setTimeout(() => {
            graph.changeData({
              nodes: showNodes.concat(curShowNodes),
              edges: showEdges.concat(curShowEdges),
            });
            const nodeItems = graph.getNodes();
            const edgeItems = graph.getEdges();
            edgeItems.forEach((item) => {
              graph.clearItemStates(item);
            });
            nodeItems.forEach((item) => {
              graph.clearItemStates(item);
              graph.setItemState(item, 'appearing', true);
            });
          }, 400);
        }
      });


      graph.on('canvas:click', () => {
        currentFocus = undefined;
        const forceLayout = graph.get('layoutController').layoutMethods[0];
        forceLayout.forceSimulation.stop();
        const nodeItems = graph.getNodes();
        const edgeItems = graph.getEdges();
        if (highlighting) {
          highlighting = false;
        } else {
          nodeItems.forEach((item) => {
            const model = item.getModel();
            if (model.neighbor) {
              graph.setItemState(item, 'disappearing', true);
            }
          });
          edgeItems.forEach((item) => {
            graph.setItemState(item, 'disappearing', true);
          });
          curShowNodes = [];
          curShowEdges = [];
          setTimeout(() => {
            const layoutController = graph.get('layoutController');
            layoutController.layoutCfg.nodeStrength = 100;
            layoutController.layoutCfg.collideStrength = 0.8;
            layoutController.layoutCfg.alphaDecay = 0.01;

            graph.changeData({
              nodes: showNodes,
              edges: showEdges,
            });
          }, 400);
        }
      });

      // 读取数据
      // graph.data(data);
      // 渲染图
      // graph.render();
    },
    async getData(){
      const response = await fetch(
        'https://gw.alipayobjects.com/os/basement_prod/0a749386-8593-44a2-a132-81dfa1fc3158.json',
      );
      const remoteData = await response.json();
      const layoutController = graph.get('layoutController');
      layoutController.layoutCfg.nodeStrength = 30;
      layoutController.layoutCfg.collideStrength = 0.8;
      layoutController.layoutCfg.alphaDecay = 0.01;
      // console.log(remoteData);
       nodes = remoteData.nodes;
       edges = remoteData.edges;
      showNodes = [];
      showEdges = [];
      nodeMap = new Map();
      edgesMap = new Map();
      nodes.forEach((node) => {
        if (!node.neighbor) {
          node.label = node.text;
          node.color = Colors[node.type];
          node.style = {
            fill: Colors[node.type],
            lineWidth: 0,
          };
          let labelColor = '#fff';
          if (node.type === 'adj') {
            labelColor = Colors.noun;
          }
          node.labelCfg = {
            style: {
              fontSize: 15,
              fill: labelColor,
              fontWeight: 300,
            },
          };
          node.x = Math.random() * 800;
          node.y = Math.random() * 800;
          showNodes.push(node);
        }
        nodeMap.set(node.id, node);
      });
      // console.log('======================')
      this.mapNodeSizeAndFontSize(showNodes, 'count', [40, 120]);
      showNodes.forEach((snode) => {
        if (snode.size < 80) {
          snode.type = 'circle';
        }
      });
      edges.forEach((edge) => {
        // map the id
        edge.id = `${edge.source}-${edge.target}`;
        edge.style = {
          lineWidth: 0.5,
          opacity: 1,
          strokeOpacity: 1,
        };
        edgesMap.set(edge.id, edge);
      });
      graph.data({
        nodes: showNodes,
        edges: showEdges,
      });
      graph.render();
      this.G6Fun();
    },
  },
  mounted() {

    // G6.registerNode(
    //   'bubble',
    //   {
    //     drawShape(cfg, group) {
    //       const self = this;
    //       const r = cfg.size / 2;
    //       // a circle by path
    //       const path = [
    //         ['M', -r, 0],
    //         ['C', -r, r / 2, -r / 2, r, 0, r],
    //         ['C', r / 2, r, r, r / 2, r, 0],
    //         ['C', r, -r / 2, r / 2, -r, 0, -r],
    //         ['C', -r / 2, -r, -r, -r / 2, -r, 0],
    //         ['Z'],
    //       ];
    //       const keyShape = group.addShape('path', {
    //         attrs: {
    //           x: 0,
    //           y: 0,
    //           path,
    //           fill: cfg.color || 'steelblue',
    //         },
    //         // must be assigned in G6 3.3 and later versions. it can be any value you want
    //         name: 'path-shape',
    //       });
    //
    //       const mask = group.addShape('path', {
    //         attrs: {
    //           x: 0,
    //           y: 0,
    //           path,
    //           opacity: 0.25,
    //           fill: cfg.color || 'steelblue',
    //           shadowColor: cfg.color, // cfg.color.split(' ')[2].substr(2),
    //           shadowBlur: 40,
    //           shadowOffsetX: 0,
    //           shadowOffsetY: 30,
    //         },
    //         // must be assigned in G6 3.3 and later versions. it can be any value you want
    //         name: 'mask-shape',
    //       });
    //
    //       const spNum = 10; // split points number
    //       const directions = [],
    //         rs = [];
    //       self.changeDirections(spNum, directions);
    //       for (let i = 0; i < spNum; i++) {
    //         const rr = r + directions[i] * ((Math.random() * r) / 1000); // +-r/6, the sign according to the directions
    //         if (rs[i] < 0.97 * r) rs[i] = 0.97 * r;
    //         else if (rs[i] > 1.03 * r) rs[i] = 1.03 * r;
    //         rs.push(rr);
    //       }
    //       keyShape.animate(
    //         () => {
    //           const path = self.getBubblePath(r, spNum, directions, rs);
    //           return { path };
    //         },
    //         {
    //           repeat: true,
    //           duration: 1000,
    //         },
    //       );
    //
    //       const directions2 = [],
    //         rs2 = [];
    //       self.changeDirections(spNum, directions2);
    //       for (let i = 0; i < spNum; i++) {
    //         const rr = r + directions2[i] * ((Math.random() * r) / 1000); // +-r/6, the sign according to the directions
    //         if (rs2[i] < 0.97 * r) rs2[i] = 0.97 * r;
    //         else if (rs2[i] > 1.03 * r) rs2[i] = 1.03 * r;
    //         rs2.push(rr);
    //       }
    //       mask.animate(
    //         () => {
    //           const path = self.getBubblePath(r, spNum, directions2, rs2);
    //           return { path };
    //         },
    //         {
    //           repeat: true,
    //           duration: 1000,
    //         },
    //       );
    //       return keyShape;
    //     },
    //     changeDirections(num, directions) {
    //       for (let i = 0; i < num; i++) {
    //         if (!directions[i]) {
    //           const rand = Math.random();
    //           const dire = rand > 0.5 ? 1 : -1;
    //           directions.push(dire);
    //         } else {
    //           directions[i] = -1 * directions[i];
    //         }
    //       }
    //       return directions;
    //     },
    //     getBubblePath(r, spNum, directions, rs) {
    //       const path = [];
    //       const cpNum = spNum * 2; // control points number
    //       const unitAngle = (Math.PI * 2) / spNum; // base angle for split points
    //       let angleSum = 0;
    //       const sps = [];
    //       const cps = [];
    //       for (let i = 0; i < spNum; i++) {
    //         const speed = 0.001 * Math.random();
    //         rs[i] = rs[i] + directions[i] * speed * r; // +-r/6, the sign according to the directions
    //         if (rs[i] < 0.97 * r) {
    //           rs[i] = 0.97 * r;
    //           directions[i] = -1 * directions[i];
    //         } else if (rs[i] > 1.03 * r) {
    //           rs[i] = 1.03 * r;
    //           directions[i] = -1 * directions[i];
    //         }
    //         const spX = rs[i] * Math.cos(angleSum);
    //         const spY = rs[i] * Math.sin(angleSum);
    //         sps.push({ x: spX, y: spY });
    //         for (let j = 0; j < 2; j++) {
    //           const cpAngleRand = unitAngle / 3;
    //           const cpR = rs[i] / Math.cos(cpAngleRand);
    //           const sign = j === 0 ? -1 : 1;
    //           const x = cpR * Math.cos(angleSum + sign * cpAngleRand);
    //           const y = cpR * Math.sin(angleSum + sign * cpAngleRand);
    //           cps.push({ x, y });
    //         }
    //         angleSum += unitAngle;
    //       }
    //       path.push(['M', sps[0].x, sps[0].y]);
    //       for (let i = 1; i < spNum; i++) {
    //         path.push([
    //           'C',
    //           cps[2 * i - 1].x,
    //           cps[2 * i - 1].y,
    //           cps[2 * i].x,
    //           cps[2 * i].y,
    //           sps[i].x,
    //           sps[i].y,
    //         ]);
    //       }
    //       path.push(['C', cps[cpNum - 1].x, cps[cpNum - 1].y, cps[0].x, cps[0].y, sps[0].x, sps[0].y]);
    //       path.push(['Z']);
    //       return path;
    //     },
    //   },
    //   'single-node',
    // );
    //
    //
    //
    // G6.registerNode(
    //   'animate-circle',
    //   {
    //     setState(name, value, item) {
    //       const shape = item.get('keyShape');
    //       const label = shape.get('parent').get('children')[1];
    //       if (name === 'disappearing' && value) {
    //         shape.animate(
    //           (ratio) => {
    //             return {
    //               opacity: 1 - ratio,
    //               r: shape.attr('r') * (1 - ratio),
    //             };
    //           },
    //           {
    //             duration: 200,
    //           },
    //         );
    //         label.animate(
    //           (ratio) => {
    //             return {
    //               opacity: 1 - ratio,
    //             };
    //           },
    //           {
    //             duration: 500,
    //           },
    //         );
    //       } else if (name === 'appearing' && value) {
    //         const r = item.getModel().size / 2;
    //         shape.animate(
    //           (ratio) => {
    //             return {
    //               opacity: ratio,
    //               r: r * ratio,
    //               fill: shape.attr('fill'),
    //             };
    //           },
    //           {
    //             duration: 300,
    //           },
    //         );
    //         label.animate(
    //           (ratio) => {
    //             return {
    //               opacity: ratio,
    //             };
    //           },
    //           {
    //             duration: 500,
    //           },
    //         );
    //       }
    //     },
    //   },
    //   'circle',
    // );
    //
    // G6.registerEdge(
    //   'animate-line',
    //   {
    //     drawShape(cfg, group) {
    //       const self = this;
    //       let shapeStyle = self.getShapeStyle(cfg);
    //       shapeStyle = mix(shapeStyle, {
    //         opacity: 0,
    //         strokeOpacity: 0,
    //       });
    //       const keyShape = group.addShape('path', {
    //         attrs: shapeStyle,
    //         // must be assigned in G6 3.3 and later versions. it can be any value you want
    //         name: 'path-shape',
    //       });
    //       return keyShape;
    //     },
    //     afterDraw(cfg, group) {
    //       const shape = group.get('children')[0];
    //       shape.animate(
    //         (ratio) => {
    //           const opacity = ratio * cfg.style.opacity;
    //           const strokeOpacity = ratio * cfg.style.strokeOpacity;
    //           return {
    //             opacity: ratio || opacity,
    //             strokeOpacity: ratio || strokeOpacity,
    //           };
    //         },
    //         {
    //           duration: 300,
    //         },
    //       );
    //     },
    //     setState(name, value, item) {
    //       const shape = item.get('keyShape');
    //       if (name === 'disappearing' && value) {
    //         shape.animate(
    //           (ratio) => {
    //             return {
    //               opacity: 1 - ratio,
    //               strokeOpacity: 1 - ratio,
    //             };
    //           },
    //           {
    //             duration: 200,
    //           },
    //         );
    //       }
    //     },
    //   },
    //   'line',
    // );



    graph = new G6.Graph({
      container: 'mountNode', // 指定图画布的容器 id,与第 9 行的容器对应
       width:1000,
       height:1000,
       linkCenter: true,//指定边是否连入节点的中心
       layout: layoutCfg,
      fitView:true,//是否开启画布自适应
      fitCenter:true,//图的中心将对齐到画布中心
      modes: {
        default: ['drag-canvas'],
      },
       defaultNode: {
         type: 'bubble',
         size: 30,
         labelCfg: {
           position: 'center',
           style: {
             fill: 'white',
             fontStyle: 'bold',
           },
         },
       },
       defaultEdge: {
         color: '#888',
         type: 'animate-line',
       },
    });
    this.getData();
  }
}
</script>

<style lang="scss" scoped>

</style>

未点击的样子

在这里插入图片描述

点击后的样子

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BowenHero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值