antv/G6使用记录,实现简单vue组件的demo

 antv/G6是蚂蚁金服数据可视化团队出品的一个功能完备的图可视化引擎。

 介于业务需要,最近在学习G6,特此记录下~~

简单展示:
简单的demo

功能点:

  • 连接关系图表
    • 鼠标控制缩放
    • 节点拖动事件
    • 画布拖动事件
    • 边的状态切换
    • 边动画

特性:

状态:G6中提供了状态管理,指的是节点或边的状态,包括交互状态和业务状态。
动画:动画是可视化中非常重要的内容,本例中涉及到边的动画效果
字体图标:本例中使用iconfont,具体实现参照G6官方文档,比较的详细
布局:G6提供了一些布局的方法,只需要在实例化G6时进行配置就好,但是本例没有使用布局,而是指定了节点额度坐标

 话不多说,上代码,使用vue写的组件,代码写的比较low~~~
完整代码

<template>
  <div class="main-content-box">
    <div id="container"></div>
  </div>
</template>

<script>
import G6 from '@antv/g6';
export default {
  name: 'g6demo',
  data () {
    return {
      data: {
        randomColor: ''
      }
    }
  },
  mounted () {
    setTimeout(() => {
      this.getInit()
    }, 100)
  },
  methods: {

    getInit () {

      const nodes = [];
      const edges = [];

      // 中心节点
      const centerNode = {
        id: 'center',
        x: 500,
        y: 300,
        // type: 'center-node',
        size: 86,
        label: '网络运营商',
        text: '\ue827',  //对应iconfont.css 里面的content,注意加u
        style: {
          fill: 'red'
        },
        labelCfg: {
          style: {
            fill: "blue"
          }
        },
        backgroundConfig: null  // 自定义项,用于判读是否需要圆背景
      };
      nodes.push(centerNode);

      // 左侧一级节点
      const leftMoudelNode = {
        id: 'node1',
        x: 350,
        y: 300,
        label: '光纤',
        text: '\ue78a',
        style: {
          fill: 'Coral'
        },
        backgroundConfig: null,
        size: 45,
      }
      nodes.push(leftMoudelNode);
      edges.push({ source: 'node1', target: 'center', type: 'can-running' });
      let leftGzzNode = {

      }
      // 左侧添加 4 个节点
      for (let i = 0; i < 4; i++) {
        const id = 'left' + i;
        nodes.push({
          id,
          x: 150,
          y: (i + 1) * 100 + 50,
          type: 'leaf-node',
          text: '\ue60e',
          label: (i + 1) + '号楼',
          style: {
            fill: '#5B8FF9'
          },
          backgroundConfig: null,
          size: 45,
        });
        edges.push({ source: id, target: 'node1', type: 'can-running' });
      }
      for (let i = 0; i < 4; i++) {
        const id = 'leftNodeGzz' + i;
        nodes.push({
          id,
          x: 50,
          y: (i + 1) * 100 + 50,
          type: 'leaf-node',
          text: '\ue627',
          label: '黑网吧',
          style: {
            fill: '#c6E5F5'
          },
          backgroundConfig: null,
          size: 45,
        });
        edges.push({ source: id, target: 'left' + i, type: 'can-running' });
      }
      // 右侧添加 5 个节点
      for (let i = 0; i < 5; i++) {
        const id = 'right' + i;
        const edgesId = 'edgeRight' + i
        nodes.push({
          id,
          x: 750,
          y: i * 100 + 50,
          type: 'leaf-node',
          text: '\ue60e',
          label: (i + 5) + '号楼',
          relation: '以太网',
          style: {
            fill: '#5B8FF9'
          },
          backgroundConfig: null,
          size: 45,
          linebackgroundConfig: {
            fill: 'Coral',
          },
        });
        edges.push({
          id: edgesId,
          source: 'center',
          target: id,
          type: 'can-running',
          label: id === 'right0' ? '高速宽带' : '以太网',
          style: {
            stroke: 'red'
          },
          labelCfg: {
            style: {
              fill: id === 'right0' ? 'Coral' : 'cyan'
            }
          }
        });
      }


      for (let i = 0; i < 5; i++) {
        const id = 'rightNodeGzz' + i;
        nodes.push({
          id,
          x: 950,
          y: (i + 1) * 100,
          type: 'leaf-node',
          text: '\ue64c',
          label: '家庭用户',
          style: {
            fill: '#c6E5F5'
          },
          backgroundConfig: null,
          size: 45,
        });
        edges.push({ source: 'right' + i, target: id, type: 'can-running' });
      }


      //
      G6.registerNode(
        'leaf-node',
        {
          draw (cfg, group) {
            const { backgroundConfig: backgroundStyle, style, labelCfg: labelStyle } = cfg;

            if (backgroundStyle) {
              group.addShape('circle', {
                attrs: {
                  x: 0,
                  y: 0,
                  r: cfg.size,
                  ...backgroundStyle,
                },
                name: 'circle-shape',
              });
            }
            group.addShape('circle', {
              attrs: {
                x: -120,
                y: 0,
                r: 30,
                ...backgroundStyle,
              },
              name: 'circle-shape',
            });
            const keyShape = group.addShape('text', {
              attrs: {
                x: 0,
                y: 0,
                fontFamily: 'iconfont', // 对应css里面的font-family: "iconfont";
                textAlign: 'center',
                textBaseline: 'middle',
                text: cfg.text,
                fontSize: cfg.size,
                ...style,
              },
              name: 'text-shape1',
            });
            const labelY = backgroundStyle ? cfg.size * 2 : cfg.size;

            group.addShape('text', {
              attrs: {
                x: 0,
                y: labelY,
                textAlign: 'center',
                text: cfg.label,
                ...labelStyle.style,
              },
              // must be assigned in G6 3.3 and later versions. it can be any value you want
              name: 'text-shape1',
            });
            return keyShape;
          },
          getAnchorPoints () {
            return [
              [0, 0.5],
              [1, 0.5],
            ];
          },
        },
        'circle',
      );


      //使用iconfont
      G6.registerNode('iconfont', {
        draw (cfg, group) {
          const { backgroundConfig: backgroundStyle, style, labelCfg: labelStyle } = cfg;

          if (backgroundStyle) {
            group.addShape('circle', {
              attrs: {
                x: 0,
                y: 0,
                r: cfg.size,
                ...backgroundStyle,
              },
              // must be assigned in G6 3.3 and later versions. it can be any value you want
              name: 'circle-shape',
            });
          }
          group.addShape('circle', {
            attrs: {
              x: -12,
              y: 0,
              r: 30,
              ...backgroundStyle,
            },
            name: 'circle-shape',
          });
          const keyShape = group.addShape('text', {
            attrs: {
              x: 0,
              y: 0,
              fontFamily: 'iconfont', // 对应css里面的font-family: "iconfont";
              textAlign: 'center',
              textBaseline: 'middle',
              text: cfg.text,
              fontSize: cfg.size,
              ...style,
            },
            // must be assigned in G6 3.3 and later versions. it can be any value you want
            name: 'text-shape1',
          });
          const labelY = backgroundStyle ? cfg.size * 2 : cfg.size;

          group.addShape('text', {
            attrs: {
              x: 0,
              y: labelY,
              textAlign: 'center',
              text: cfg.label,
              ...labelStyle.style,
            },
            // must be assigned in G6 3.3 and later versions. it can be any value you want
            name: 'text-shape1',
          });
          return keyShape;
        },
      });
      // lineDash 的差值,可以在后面提供 util 方法自动计算
      const dashArray = [
        [0, 1],
        [0, 2],
        [1, 2],
        [0, 1, 1, 2],
        [0, 2, 1, 2],
        [1, 2, 1, 2],
        [2, 2, 1, 2],
        [3, 2, 1, 2],
        [4, 2, 1, 2],
      ];
      const lineDash = [4, 2, 1, 2];
      const interval = 9;

      G6.registerEdge(
        'can-running',
        {
          setState (name, value, item) {
            const shape = item.get('keyShape');
            if (name === 'running') {
              if (value) {
                const length = shape.getTotalLength(); // 后续 G 增加 totalLength 的接口
                let totalArray = [];
                for (let i = 0; i < length; i += interval) {
                  totalArray = totalArray.concat(lineDash);
                }
                let index = 0;
                shape.animate(
                  () => {
                    const cfg = {
                      lineDash: dashArray[index].concat(totalArray),
                    };
                    index = (index + 1) % interval;
                    return cfg;
                  },
                  {
                    repeat: true,
                    duration: 3000,
                  },
                );
              } else {
                shape.stopAnimate();
                shape.attr('lineDash', null);
              }
            }
          },
        },
        'cubic-horizontal',
      );




      let COLOR = '#40a9ff'
      const width = document.getElementById('container').scrollWidth * 0.7;
      const height = document.getElementById('container').scrollHeight || 600;
      const graph = new G6.Graph({
        container: 'container',
        width,
        height,
        renderer: 'svg',
        modes: {
          default: [
            'drag-canvas',
            'drag-node',
            'zoom-canvas'
          ]
        },
        defaultNode: {
          backgroundConfig: {
            backgroundType: 'circle',
            fill: COLOR,
            stroke: 'LightSkyBlue',
          },
          type: 'iconfont',
          size: 12,
          style: {
            fill: '#DEE9FF',
            stroke: '#5B8FF9',
          },
          labelCfg: {
            style: {
              fill: COLOR,
              fontSize: 12,
            },
          },

        },
        defaultEdge: {

          style: {
            stroke: '#b5b5b5',
          },
        },
      });

      graph.data({ nodes, edges });
      graph.render();
      graph.fitView();
      // 响应 hover 状态
      graph.on('node:mouseenter', ev => {
        const node = ev.item;
        const edges = node.getEdges();
        edges.forEach(edge => graph.setItemState(edge, 'running', true));
      });
      graph.on('node:mouseleave', ev => {
        const node = ev.item;
        const edges = node.getEdges();
        edges.forEach(edge => graph.setItemState(edge, 'running', false));
      });


      let model = {
        type: 'can-running',
        text: '\ue60e',
        style: {
          stroke: 'yellow'
        },
        labelCfg: {
          style: {
            fill: 'cyan'
          }
        }
      };

      //增加edge的标识id字段后
      const item = graph.findById('edgeRight0');
      const item2 = graph.findById('edgeRight1');
      const item3 = graph.findById('edgeRight2');
      const item4 = graph.findById('edgeRight3');
      const item5 = graph.findById('edgeRight4');
      setInterval(() => {
        model.labelCfg.style.fill = this.getRandomColor()
        model.style.stroke = this.getRandomColor()
        graph.updateItem(item, model);
        graph.updateItem(item2, model);
        graph.updateItem(item3, model);
        graph.updateItem(item4, model);
        graph.updateItem(item5, model);
      }, 1000);
    },
    getRandomColor () {
      var rand = Math.floor(Math.random() * 0xFFFFFF).toString(16);
      if (rand.length == 6) {
        return '#' + rand;
      } else {
        return this.getRandomColor();
      }
    }
  }
}

</script>

<style scoped>
</style>

  以上就是示例的完整代码,G6的版本为3.5.0,话说G6的团队真的是很勤奋,版本更新的也蛮快的,官方文档也是越来越完善。希望越做越好吧。

Tips:
   如果本文章对您有帮助,欢迎评论告知!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值