antv g6 4.7版本

antv 4.8文档

设置可缩放 拖动画布

 let graph = new G6.Graph({
     modes: {
      // 拖拽画布   缩放画布
      default: ['drag-canvas', 'zoom-canvas']
    }
  })

内容缩放居中

 graph.zoom(0.5) // 缩放到0.5
 graph.fitCenter() //将图中心将对齐到画布中心

连接点的设置

tupain 连接点
 // 全局默认配置 
 let graph = new G6.Graph({
     defaultNode: {
      anchorPoints: [[0.5, 0],[1, 0.5],[0.5, 1],[0, 0.5],[0.85, 0.15],[0.85, 0.85],[0.15, 0.85],[0.15, 0.15]],
    },
  })
// 自定义节点配置
  G6.registerNode('labelBox', {
    draw(){...},
    getAnchorPoints() {
      return [[0.5, 0],[1, 0.5],[0.5, 1],[0, 0.5],[1, 0],[1, 1],[0, 1],[0, 0]];
    }
  })

// 使用 边data中
  {
    id: 'g8',
    source: 'g8',
    target: 'g8Label',
    sourceAnchor: 7,  // anchorPoints数组中下标为7的[0, 0]  左上
    targetAnchor: 5,  // anchorPoints数组中下标为5的[1, 1]  右下
    type: 'labelBox'
  },

图片旋转

旋转会导致anchorPoints跟着转。 思路: 1.添加一个框 2.框里添加图片 3.旋转图片,框不变

tupain 旋转
  // 引入转换方法
  import { ext } from '@antv/matrix-util';
  const transform = ext.transform;

  G6.registerNode(type, {
    draw(cfg, group) { // 添加框
       const keyShape = group.addShape('rect', {...})
       return keyShape
    },
    afterDraw(cfg, group) { //添加img
       let direction = cfg.direction
       let image  = group.addShape('image', {})
       if(direction && direction === 'v') {
        const newMatrix = transform([1, 0, 0, 0, 1, 0, 0, 0, 1], [
          ['t', 0,-34], // 位移  包含框不同 自行设置
          ['r', Math.PI / 2], // 旋转90度
        ]);
        image.setMatrix(newMatrix); // 图片变化
      }
    }
  })

自定义添加文字

自定义节点或边添加文本时 需要addShape('text')

  // 节点文本 
  G6.registerNode(type, {
    draw(cfg, group) {
      const keyShape = group.addShape('rect', {...})
      if (cfg.label) {
        const label = group.addShape('text', {
          attrs: {
            x: positionX, // 相对于节点的偏移
            y: positionY, // 
          },
          name: 'text-za',
        });
      }
      return keyShape
    }
  })

边文的 xy坐标 是相对于整个容器的,不是所在线的xy坐标

  // 边文本 
  G6.registerEdge(type, {
    draw(cfg, group) {
      const keyShape = group.addShape('path', {...})
      if (cfg.label) {
        let {startPoint,endPoint} = cfg
        const label = group.addShape('text', {
          attrs: {
            x: startPoint.x - endPoint.x, // 居中  线段起点终点的 
            y: startPoint.y - endPoint.y, // 坐标系跟节点的坐标一样
          },
          name: 'text-za',
        });
      }
      return keyShape
    }
  })

自定义边文本的旋转

tupain 旋转

    if (cfg.label) {

      let direction = cfg.textDirection && cfg.textDirection === 'v'
      let label = group.addShape('text', {
          attrs: {
            x: direction ? 0 : x, //需要旋转是 先设置位置为0
            y: direction ? 0 : y,
            text: cfg.label,
            fontSize:8,
            fill: '#aaa',
            lineHeight: 18, // 行高  renderer方式是svg是无效   默认canvas 
            zIndex:1000
          },
          name: 'left-text-shape',
        });
        // 文本垂直
        if(direction) {
          //transform 看图片旋转
          const newMatrix = transform([1, 0, 0, 0, 1, 0, 0, 0, 1], [
            ['t', yPosition,12 - xPosition], // // 这个时候才移动文字的位置
            ['r', Math.PI / 2],
          ]);
          label.setMatrix(newMatrix);
        }
    }

定义边 虚线

  // 添加虚线 
  afterDraw(cfg, group) {
    // 获得该边的第一个图形,这里是边的 path
    const shape = group.get('children')[0];
    shape.attr('lineDash', [7, 3, 2, 3]);  // 虚线、实线 的长度
  }


交互 设置状态 改变图片

  G6.registerNode(type, {
    options: {
      stateStyles: {
        'status:default': {
          img: vedio0Img
        },
        'status:pass': {
          img: vedio1Img  
        },
        'status:stop': {
          img: vedio2Img
        }
      }
    },
    draw(cfg, group) {
      const keyShape = group.addShape('image', {
        attrs: {
          x: typeObj.x,
          y: typeObj.y,
          img: (this.options.stateStyles[cfg.img] || {}).img  ||  this.options.stateStyles['status:default'].img,
          width: cfg.width || typeObj.width,
          height: cfg.height || typeObj.height,
          cursor: 'pointer', // 鼠标样式
        },
        name: 'img_node',
      });
      
    },
    setState(name, value, item) {
      const shape = item.get('keyShape')
      let stateStyles = item._cfg.styles || {}
      if (!!value) {
        if(name === 'status') {
          let newKey = `${name}:${value}`
          if(stateStyles[newKey]) {
            shape.attr('img', stateStyles[newKey].img);
          }
        }
      } else {
        // 恢复默认图片
        if(Object.keys(stateStyles).includes(name)) {
          shape.attr('img', stateStyles['status:default'].img);
        }
      }
    }
  })

    //执行
    let g = this.graph.findById('g1')
    this.graph.setItemState(g, 'status', 'pass') // 设置状态

    this.graph.clearItemStates(g, ['status:pass']); // 清除状态  方式1
    this.graph.clearItemStates(g); // 清除状态  方式2
  }

虚线动画

  // 添加虚线 
  afterDraw(cfg, group) {
    const shape = group.get('children')[0];
    shape.attr('lineDash', [7, 3, 2, 3]);  // 虚线、实线 的长度
  },
  setState(name, value, item) {
    const shape = item.get('keyShape')
    let currStatusArr = item.getStates() // 当前选中的状态

    if (!!value) {
      // 添加动画
      if(currStatusArr.includes('animation') && value) {
        let index = 0;
        shape.animate(() => {
          index++;
          if (index > 60) {
            index = 0;
          }
          // 虚线的所有边长 * 4 = 60 
          let a = -(index / 4)
          const res = {
            lineDash:[7, 3, 2, 3], // 加起来有15
            lineDashOffset: a,
          };
          return res;
        },
        {
          repeat: true, // 动画重复
          duration: 3000, // 一次动画的时长为 3000
        });
      }

    } else {
      // 取消动画
      if(name === 'animation'){
        shape.stopAnimate();
        item.toBack() // 元素实例方法   将元素设置到最底层
      }
    }
  }


修改自定义文本

  let arr = this.graph.getNodes()
  for(let i=0;i<arr.length;i++) {
    let obj = arr[i].getModel()
    arr[i].update({ label: 13 })
  }
  

  // 自定义节点
  draw(cfg, group) {
    const label = group.addShape('text', {})
  },
  update (cfg, node) { // 修改时触发update
    const group = node.getContainer(); // 获取容器
    const shape = group.get('children')[1]; // 按照添加的顺序
    shape.attr('text',cfg.label)
  }

点击事件

  graph.data(data);
  graph.render(); // 渲染图
  graph.on('click', (ev) => {
      let type = ev.item._cfg.currentShape // 自定义节点的type
        switch(type){
          case 'vedioImg':
            this.clickVedio(ev)
            break;
          default:
            console.log(type)
        }
  });

菜单 弹窗

tupain 菜单
   const menu = this.getMenu()
   let graph = new G6.Graph({
      plugins: [menu], // 配置插件   menu属于插件
   })

  //菜单   样式需要页面的css中
    getMenu () {
      let _this = this
      return new G6.Menu({
        offsetX: 0,
        offsetY: 0,
        className: 'vedioListItemBox',
        trigger: 'click',  // 触发类型 
        getContent (e) {
          // 添加dom
          const outDiv = document.createElement('div')
          outDiv.classList.add("vedioListItem");
          let arr = e.item.getModel().vList
          let strDiv = arr.map((ele) => {
            let data = JSON.stringify(ele)
            return `<div data-info='${data}'> ${ele.channelName} </div>`
          })
          outDiv.innerHTML = `${strDiv.join(' ')}`
          return outDiv
        },
        // 设置是否显示
        shouldBegin(G6Event){
          // 返回boolean 值  true显示
          let obj = G6Event.item.get('model') || {}
          return obj.type === 'vedioImg' && obj.label
        },
        // 设置是否显示 处理点击
         handleMenuClick(target) {
          if(target.nodeType === 1) {
            let data = target.getAttribute("data-info")
            data = JSON.parse(data)
            console.log(data )
          }
        }
      })
    }

path

  • M 移动到某个点
  • L 从上一个点 到当前点 画一条线
  • Z 封口 可以不需要
tupain path
posted @ 2022-12-30 17:21  雨天。我  阅读(868)  评论(0)    收藏  举报