vue中使用g6实现流程图

2,184 阅读2分钟

G6实现流程图,并实现自定义DOM

最近在做业务的时候,需要一个需求,大致是实现几个不同样式的流程图,调研的时候,考虑了使用jsmind,echarts, g6,也考虑过自己写,综合考虑后还是决定用g6流程图,开始使用的是canvas实现的,但是不支持DOM扩展,导致的问题有文字过长超出,箭头指向有问题,文字过短没有居中等,但是type为svg的时候,可以通过自定义dom来解决这些问题,上代码

废话不多说,还是粘上所有的代码,然后进行注释讲解

const data = value
// 字数超出换行
data.nodes.forEach(e => {
if (e.label.length > 19) {
  e.label = e.label.replace(/(.{19})/g, '$1\n')
}
})
const width = document.getElementById('container').scrollWidth
const height = document.getElementById('container').scrollHeight || 700
window.G6.registerNode(
'dom-node',{
  draw: (cfg, group) => {
    return group.addShape('dom', {
      attrs: {
                width: cfg.size[0],
                height: cfg.size[1],
                // 传入 DOM 的 html
                html: `
                    <div style="background-color: #fff; border: 1px solid #333; border-radius: 5px; width: ${cfg.size[0] - 5}px; height: ${cfg.size[1] - 5}px; display: flex;">
                    <span style="display:inline-block; padding:2px; color: #606266; height:72px; line-height:18px;overflow-x:auto;text-align:center;width:100%;" class="label">
                        ${cfg.label}
                    </span>
                    </div>
                    `
              },
              draggable: false
            })
          }
        },
        'single-node'
      )
      this.graph = new window.G6.Graph({
        container: 'container',
        renderer: 'svg', // 性能较差  数据多的情况下使用canvas, by zcs
        width,
        height,
        fitView: false,
        modes: {
          default: ['drag-canvas', 'drag-node']
        },
        layout: {
          type: 'dagre',
          rankdir: 'LR',
          align: '',
          nodesepFunc: () => 1,
          ranksepFunc: () => 1
        },
        defaultNode: {
          size: [220, 80],
          type: 'dom-node',
          
          style: {
            lineWidth: 1,
            stroke: '#5B8FF9',
            fill: '#fff'
          }
        },
        groupByTypes: false,
        defaultCombo: {
          style: {
            fill: '#steelblue',
            stroke: '#eaff8f',
            lineWidth: 5
          },
          labelCfg: {
            position: 'left',
            refX: 5,
            style: {
              fill: '#fff',
              fontSize: 40
            }
          }
        },
        defaultEdge: {
          type: 'line',
          size: 1,
          color: '#FA6973',
          style: {
            endArrow: {
              d: 25
            }
          }
        }
      })
      this.graph.data(data)
      this.graph.render()

至此可以实现自定义dom,有几个点需要注意下,以下代码从上边的代码中摘抄出来:

自定义dom中

 window.G6.registerNode(
        'dom-node',
        {
          draw: (cfg, group) => {  // cfg是graph中的配置项
            return group.addShape('dom', {
              attrs: {
                width: cfg.size[0],
                height: cfg.size[1],
                // 传入 DOM 的 html
                html: `
                    <div style="background-color: #fff; border: 1px solid #333; border-radius: 5px; width: ${cfg.size[0] - 5}px; height: ${cfg.size[1] - 5}px; display: flex;">
                    <span style="display:inline-block; padding:2px; color: #606266; height:72px; line-height:18px;overflow-x:auto;text-align:center;width:100%;" class="label">
                        ${cfg.label} 
                    </span>
                    </div>
                    `
              },
              draggable: false  // 是否可以拖拽
            })
          }
        },
        'single-node'
)

在init,render后调用此方法

此外,还有几个比较常用的api方法

1、graph.destroy()  销毁实例
2、dataChange() 重新渲染
layout中:
1、ranksepFunc 线条长度  // 在drage中使用 如果设置了ranksep则ranksep优先级最高,配合rankdir,横向或纵向
 ranksepFunc:(d) => {
     if(d.id == '1') {
         return 100
     }
     return 20
 }
2、ranksep 线条长度  
3、nodesepFunc  节点之间的高度
4、defaultNode中的anchorPoints,箭头居中