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,箭头居中