![在这里插入图片描述](https://img-blog.csdnimg.cn/f8b1c50e5f9247799f358808eddf7bde.png#pic_center)
```javascript
// html import G6 from '@antv/g6'
<el-card class="leftCard">
<div id="mountNode" style="margin-top: 20px;"></div>
</el-card>
methods: {
// 将流程信息转换成树状结构
getTree(data, v) {
let arr = []
for (let index = data.length - 1; index >= 0; index--) {
if (index === data.length - 1) {
data[index].id = data[index].nodeName + data[index].dispatchId + index
data[index].data = v
arr[0] = data[index]
} else {
data[index].id = data[index].nodeName + data[index].dispatchId + index
data[index].data = v
data[index].children = []
data[index].children[0] = arr[0]
arr[0] = data[index]
}
}
return arr
},
// G6换行符处理超长文本
superLongTextHandle(str, maxWidth, fontSize) {
let currentWidth = 0
let res = str
// 区分汉字和字母
const pattern = new RegExp('[\u4E00-\u9FA5]+')
str.split('').forEach((letter, i) => {
if (currentWidth > maxWidth) return
if (pattern.test(letter)) {
// 中文字符
currentWidth += fontSize
} else {
// 根据字体大小获取单个字母的宽度
currentWidth += G6.Util.getLetterWidth(letter, fontSize)
}
if (currentWidth > maxWidth) {
res = `${str.substr(0, i)}\n${this.superLongTextHandle(
str.substr(i),
maxWidth,
fontSize
)}`
}
})
return res
},
// 流程图画布
initG6(value) {
console.log(this.formData1)
// 数据
const data = {
id: '数据接入',
nodeName: '数据接入',
processTime: this.formData1.happenTime,
data: {
departmentName: this.formData1.departmentName
},
children: []
}
if (value.length !== 0) {
value.map((e, i) => {
let v = e
if (e.processList.length !== 0) {
e = this.getTree(e.processList, v)[0]
}
data.children[i] = e
})
}
const container = document.getElementById('mountNode')
const width = container.scrollWidth
const height = container.scrollHeight || 600
let that = this
// 文本
G6.registerNode(
'icon-node',
{
options: {
size: [60, 20],
stroke: '#91d5ff',
fill: '#91d5ff'
},
draw(cfg, group) {
const styles = this.getShapeStyle(cfg)
console.log(styles)
const { labelCfg = {} } = cfg
const h = styles.height
const w = styles.width
const keyShape = group.addShape('rect', {
attrs: {
...styles,
y: -h / 2,
radius: [2, 4]
}
})
if (cfg.label) { // 展示的文本
group.addShape('text', {
attrs: {
...labelCfg.style,
fill: '#fff',
text: cfg.nodeName,
textAlign: 'center',
y: 25 - h / 2
}
})
if (cfg.data.isMain && cfg.nodeName === '派遣') {
if (cfg.data.isMain === '1') {
group.addShape('text', {
attrs: {
...labelCfg.style,
fill: 'red',
text: cfg.data.isMain === '1' ? '主办' : '协办',
y: 25 - h / 2,
x: 110 - w / 2
}
})
} else {
group.addShape('text', {
attrs: {
...labelCfg.style,
fill: '#A279C1',
text: '协办',
y: 25 - h / 2,
x: 110 - w / 2
}
})
}
}
if (cfg.data.departmentName && cfg.nodeName === '派遣') {
group.addShape('text', {
attrs: {
...labelCfg.style,
fill: '#fff',
text: that.superLongTextHandle(cfg.data.departmentName, 120, 12),
textAlign: 'center',
textBaseline: 'top',
y: h - 10
}
})
}
group.addShape('text', {
attrs: {
...labelCfg.style,
y: h / 2,
text: cfg.processTime,
fill: '#fff',
fontSize: 14,
textAlign: 'center',
opacity: 0.75
}
})
}
return keyShape
},
update: undefined
},
'rect'
)
// 线
G6.registerEdge('flow-line', {
draw(cfg, group) {
const startPoint = cfg.startPoint
const endPoint = cfg.endPoint
const { style } = cfg
const shape = group.addShape('path', {
attrs: {
stroke: '#2281C0',
endArrow: style.endArrow,
path: [
['M', startPoint.x, startPoint.y],
['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, endPoint.y]
]
}
})
return shape
}
})
const graph = new G6.TreeGraph({
container: 'mountNode',
width,
height,
linkCenter: true,
modes: {
default: [
'drag-canvas',
'zoom-canvas'
] // 允许拖拽画布、放缩画布
},
// 节点默认配置
defaultNode: {
type: 'icon-node',
size: [150, 40],
style: {
fill: '#10324C',
stroke: '#1C4E94',
lineWidth: 4
},
labelCfg: {
style: {
fill: '#3C4353',
fontSize: 16
}
}
},
// 边默认配置
defaultEdge: {
type: 'flow-line',
style: {
stroke: '#DDE2EE',
endArrow: {
path: 'M 0,0 L 12, 6 L 9,0 L 12, -6 Z',
fill: '#1C4E94',
d: -20
}
}
},
layout: {
type: 'compactBox',
direction: 'TB',
getId: function getId(d) {
return d.id
},
getHeight: function getHeight() {
return 16
},
getWidth: function getWidth() {
return 16
},
getVGap: function getVGap() {
return 80
},
getHGap: function getHGap() {
return 100
}
},
// 节点不同状态下的样式集合
nodeStateStyles: {
// 鼠标点击节点,即 click 状态为 true 时的样式
click: {
fill: 'lightsteelblue',
stroke: '#000'
}
}
})
graph.node(function (node) {
let position = 'right'
let rotate = 0
if (!node.children) {
position = 'bottom'
rotate = Math.PI / 2
}
return {
label: node.id,
labelCfg: {
position,
offset: 5,
style: {
rotate,
textAlign: 'start'
}
}
}
})
graph.data(data)
graph.render()
graph.fitView()
// 监听鼠标点击节点
// graph.on('node:click', (e) => {
// // 先将所有当前有 click 状态的节点的 click 状态置为 false
// const clickNodes = graph.findAllByState('node', 'click')
// clickNodes.forEach((cn) => {
// graph.setItemState(cn, 'click', false)
// })
// const nodeItem = e.item
// // 设置目标节点的 click 状态 为 true
// graph.setItemState(nodeItem, 'click', true)
// // this.nodeClick(e)
// })
if (typeof window !== 'undefined') {
window.onresize = () => {
if (!graph || graph.get('destroyed')) return
if (!container || !container.scrollWidth || !container.scrollHeight) return
graph.changeSize(container.scrollWidth, container.scrollHeight)
}
}
},
}