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

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:''}]
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354