美文网首页功能点前端知识点
基于antv/g6开发流程图编辑器(一)——节点的设计

基于antv/g6开发流程图编辑器(一)——节点的设计

作者: Gason_d796 | 来源:发表于2019-04-15 11:25 被阅读0次

    gason-editor 设计文档(基于antv/g6-2.0)

    基于antv/g6,参考g6-editor编写的一个编辑器,虽然是基于2.0版本,但是2.0和3.0的设计思路基本上一致,只是3.0有扩展一些更好有的功能,2.0会了,3.0很快上手。

    节点的设计

    节点的参数

    节点的基本参数如id,类型等,根据你的业务情况,可以加入各种参数,如图片Image,状态state等,获取时,使用item.getModel()中去获取(具体参考g6的api文档)

    节点的展示

    很多人在使用g6时,对锚点的使用会很疑惑。

    因为g6的锚点是看不见的,所以我们在设计节点时,要画出一个节点,覆盖在锚点上。所以在设计节点时,显示的节点位置要和锚点的位置重合,估需要计算。
    如你的节点是个正方形状,某个锚点的位置为[0,0.5],代表的是在上边的中点,所以你在显示节点y坐标为0,x坐标为你节点宽度的一半。


    node.png

    如上图的节点,代码如下:

    `  const G6 = require('@antv/g6')
       const nodeCache = new Map() // 组件类型缓存
       export function registNewNode(node) {
         let inPorts = node.inPorts //输入锚点
         let outPorts = node.outPorts //输出锚点
        let nodeDefId = node.nodeDefId
        if (!nodeCache.has(nodeDefId)) {
        nodeCache.set(node.nodeDefId, node.nodeDefId)
    // 根据传入的参数确定真实的锚点
        let anchors = []
        if (inPorts && inPorts.length > 0) { // 
        for (let index = 0; index < inPorts.length; index++) {
        anchors.push([
          (1 / (inPorts.length + 1)) * (index + 1),
          0,
          {
            id: inPorts[index].id,
            sequence: inPorts[index].position,
            type: 'in'
          }
        ])
      }
    }
    if (outPorts && outPorts.length > 0) {
      for (let index = 0; index < outPorts.length; index++) {
        anchors.push([
          (1 / (outPorts.length + 1)) * (index + 1),
          1,
          {
            id: outPorts[index].id,
            sequence: outPorts[index].position,
            type: 'out'
          }
        ])
      }
    }
     // 注册新图形节点
    G6.registerNode(nodeDefId, { // nodeDefId 动态的节点类型,后面拖拽生成相对应节点有效
      shapeType: 'rect',
      anchor: anchors,// 真实的锚点
      draw(item) {
        const group = item.getGraphicGroup()
        const model = item.getModel()
        const textStyle = {
          textAlign: 'center',
          fontSize: 13,
          fill: 'rgba(0, 0, 0, 0.9)'
        }
        const keyshap = group.addShape('rect', {
          attrs: {
            x: 0,
            y: 0,
            width: 150,
            height: 40,
            fill: '#fff',
            radius: 4,
            stroke: '#59B9FF',
            type: 'rect'
          }
        })
        group.addShape('image', {
          attrs: {
            x: 7,
            y: 8,
            type: 'image1',
            width: 24,
            height: 24,
            img: model.flagA
          }
        })
        group.addShape('image', {
          attrs: {
            x: 120,
            y: 3,
            type: 'image2',
            width: 30,
            height: 35,
            img: model.flagB
          }
        })
    
        group.addShape('text', {
          attrs: {
            ...textStyle,
            x: 70,
            y: 27,
            text: model.name,
            type: 'text'
          }
        })
        // 确定出展示的锚点
        if (inPorts && inPorts.length > 0) {
          let index = 0
          for (let inPort of inPorts) {
            index++
            group.addShape('circle', {
              attrs: {
                id: inPort.id,
                x: (150 / (inPorts.length + 1)) * index,// 根据锚点个数来确定展示的位置
                y: 0,
                r: model.inR || 5,
                fill: '#fff',
                stroke: '#757ffc',
                type: 'anchor',
                description: inPort.name,
                anchorType: 'in',
                anchorIndex: index - 1
              }
            })
          }
        }
        if (outPorts && outPorts.length > 0) {
          let index = 0
          for (let outPort of outPorts) {
            let anchorIndex = index + inPorts.length
            index++
            group.addShape('circle', {
              attrs: {
                id: outPort.id,
                x: (150 / (outPorts.length + 1)) * index,
                y: 40,
                r: model.outR || 5,
                fill: '#fff',
                stroke: '#69D7E6',
                type: 'anchor', //锚点类型,之后动态连接节点时有用
                description: outPort.name,
                anchorType: 'out',
                anchorIndex: anchorIndex
              }
            })
          }
        }
        return keyshap
      },
      afterDraw(cfg) {
        // console.log('cfg', cfg)
      }
    })}}
    

    绘制时代码:


    test.png

    其中,node中的数据结构为:

    `

      {
       id:'',
       defId:'',
       name:'',
       inPorts:[{id:'',name:''}],//输入锚点
       outPorts:[{id:'',name:''}]
    }
    

    `
    下一篇文章我会介绍如何根据事件去节点动态连接,根据不同锚点去连接

    相关文章

      网友评论

        本文标题:基于antv/g6开发流程图编辑器(一)——节点的设计

        本文链接:https://www.haomeiwen.com/subject/aytuwqtx.html