效果图
代码
<template><div class="app"><div ref="myholder" id="paper"></div></div>
</template><script>
import * as joint from '@joint/core'
import $ from 'jquery'
export default {data() {return {graph: null,}},mounted() {const namespace = joint.shapesvar graph = new joint.dia.Graph({}, { cellNamespace: namespace })this.graph = graphvar paper = new joint.dia.Paper({el: this.$refs.myholder,model: this.graph,width: 800,height: 300,cellViewNamespace: namespace,drawGrid: true,gridSize: 10,background: {color: 'rgba(0, 255, 0, 0.3)',},// 禁止交互interactive: false, // disable default interaction (e.g. dragging)// 当mousemove事件的数量超过clickThreshold时,在mouseup之后不会触发pointerclick事件clickThreshold: 10,})this.paper = paperconst node1 = this.drawRect({ x: 50, y: 30 }, '节点1')const node2 = this.drawRect({ x: 200, y: 30 }, '节点2')const node3 = this.drawRect({ x: 350, y: 30 }, '节点3')const node4 = this.drawRect({ x: 500, y: 30 }, '节点4')// const node5 = this.drawRect({ x: 50, y: 100 }, '流程-1.1')const node6 = this.drawRect({ x: 350, y: 100 }, '节点6')const node7 = this.drawRect({ x: 350, y: 150 }, '流程-2.2')// 自定义路径点const path_points = new joint.g.Path('M 300 50 L 325 50 L 325 120 L 350 120').segmentsconst points = path_points.map((item) => item.end)const path_points_2 = new joint.g.Path('M 300 50 L 325 50 L 325 120 L 325 170 L 350 170').segmentsconst points_2 = path_points_2.map((item) => item.end)const node2_to_node6_vetices = [...points]const node2_to_node7_vetices = [...points_2]this.drawLine(node1, node2)this.drawLine(node2, node3)this.drawLine(node3, node4)// this.drawLine(node1, node5)this.drawLine(node2, node6, node2_to_node6_vetices)this.drawLine(node2, node7, node2_to_node7_vetices)},methods: {drawRect({ x, y }, text) {var rect = new joint.shapes.standard.Rectangle()rect.position(x, y)rect.resize(100, 40)rect.attr({// body选择器修改的是 svg元素 [selector for the <rect> SVGElement]body: {fill: '#2c3e50',// strokeWidth: 0,// strokeDasharray: '10,2',// fill: 'transparent',// stroke: 'transparent',},// label选择器修改的是 text元素 [selector for the <text> SVGElement]label: {text,fill: '#3498DB',fontSize: 18,fontWeight: 'bold',fontVariant: 'Microsoft YaHei',},})rect.addTo(this.graph)// this.transformHtml(rect, text)return rect},// vertices 数组,从起始点到终点是否需要绕行 [https://resources.jointjs.com/tutorial/links]drawLine(node1, node2, vertices) {var link = new joint.shapes.standard.Link()link.source(node1)link.target(node2)link.addTo(this.graph)if (vertices && vertices.length) {link.vertices(vertices)// 注意:下面不能使用,使用下面后路径会自动去计算// link.router('orthogonal')// link.connector('rounded')}link.attr({line: {stroke: 'gray',},})},transformHtml(element, text) {var bbox = element.getBBox()// NOTE:重点方法 绘制一个html元素在element元素之上// Draw an HTML rectangle above the element.var clientRect1 = this.paper.localToClientRect(bbox)var div = document.createElement('div')div.style.position = 'fixed'div.style.background = 'red'div.style.left = clientRect1.x + 'px'div.style.top = clientRect1.y + 'px'div.style.width = clientRect1.width + 'px'div.style.height = clientRect1.height + 'px'div.innerHTML = `<span class='yellow'>${text}</span>`$(div).click(function () {console.log(this)})this.paper.el.appendChild(div)},},
}
</script><style lang="less" scoped>
#paper {border: 1px solid;
}/deep/.yellow {color: yellow;
}
</style>