项目中jsplumb使用

337 阅读2分钟

页面模板

<div id="start" class="start" @mouseover="mouseover('start')"
@mouseleave="mouseleave('start')">
   <div class="opacity" id="opacity-start">
 </div>
开始</div>

初始化模板

{
	isSource: true,
	isTarget: true,
	connector:["Bezier",{curviness: 63}],
	overlays: [ 
		['Arrow', { width: 8, length: 8, location: 1}]
	],
	endpoint: ['Dot', {radius: 4}],
	paintStyle: {
		fill: '#FDFDFD',
		stroke:'#ccc',
		strokeWidth: 0.5
	},
	maxConnections: 50,
	hoverPaintStyle: {
	  outlineStroke: '#758CFE'
	},
	connectorStyle: {
		outlineStroke: '#ccc',
		strokeWidth: 0.2,
		joinstyle: 'arrow',
		stroke: '#ccc'
	},
	connectorHoverStyle: {
		strokeWidth: 0.2
	}
}

代码初始化

loadProcessFlow() {
			this.selectNodes = []
			this.nodeTree = {}
			this.jsPlumb = jsPlumb.getInstance()
			this.jsPlumb.ready(() => {
				this.jsPlumb.draggable('start', {
					containment: "flowWrap"
				})
				this.jsPlumb.draggable('end', {
					containment: "flowWrap"
				})
				this.addpoint('start', 'Right')
				this.addpoint('end', 'Left')
				this.makePoint('start', 'makeSource')
				this.makePoint('end', 'makeTarget')
				this.jsPlumb.bind('dblclick', conn => {
					const {sourceId, targetId} = conn
					this.jsPlumb.deleteConnection(conn)
					this.selectNodes = this.selectNodes
						.filter(item => !(item.sourceId === sourceId && item.targetId === targetId))
					if (this.nodeTree[sourceId].length === 1) {
						delete this.nodeTree[sourceId]
					} else {
						this.nodeTree[sourceId] = this.nodeTree[sourceId]
							.filter(item => item !== targetId)
					}
				})
				// 监听连线操作
				this.jsPlumb.bind('beforeDrop', info => {
					/**
					 *以下几种情况不能连线
					 *1、开始节点不能是目标源
					 *2、结束节点不能是来源
					 *3、目标源和来源不能相同
					 *4、开始节点和结束节点不能相连
					 *5、目标源和来源不能出现多条
					 *6、相同位置的端点不能相连
					 *7、左边不能连右边, 右边不能连右边
					 *8、源节点已经结束了就不能再连目标节点
					 *9、目标节点的源节点是开始节点不能被源节点相连
					 *10、两个不同的源节点不能是相同的目标节点(结束节点除外)
					 *11、开始节点出去只能有一条线
					 *12、开始节点不能连已经有目标节点的源节点
					 **/
					const {sourceId, targetId, connection: {endpoints}} = info
					if (targetId === 'start' ||
						sourceId === 'end' ||
						sourceId === targetId ||
						(sourceId === 'start' && targetId === 'end')) {
						return false
					}
					const startNode = this.selectNodes.find(node => node.sourceId === 'start' && sourceId === 'start')
					if (startNode) {
						return false
					}
					// 目标源和来源不能出现多条
					const findIndex = this.selectNodes.findIndex(item =>
						item.sourceId === sourceId && item.targetId === targetId
					)
					if (findIndex > -1) return false
					// 相同位置的端点不能相连
					if (endpoints) {
						const anchorslength = endpoints[0].anchor.anchors.length
						const firstEndPoint = endpoints[0].anchor.anchors[anchorslength-1].type
						const secondEndPoint = info.dropEndpoint.anchor.anchors[0].type
						// 左边不能连右边
						if (firstEndPoint === 'Left' && secondEndPoint === 'Right') {
							return false
						}
						// 右边不能连接右边
						if (firstEndPoint === 'Right' && secondEndPoint === 'Right') {
							return false
						}
						// 左边不能连接左边
						if (firstEndPoint === 'Left' && secondEndPoint === 'Left') {
							return false
						}
						// const endPointTypes = []
						// endPointTypes.push(firstEndPoint)
						// endPointTypes.push(secondEndPoint)
						// if ([...new Set(endPointTypes)].length !== endPointTypes.length) {
						// 	return false
						// }
					}
					// 有下一级端点的不能连结束节点
					const currentSourceId = this.nodeTree[sourceId];
					if (currentSourceId && currentSourceId.length > 0) {
						for (let sr = 0; sr < currentSourceId.length; sr++) {
							if (!this.nodeTree[currentSourceId[sr]]) {
								continue
							}
							if (this.nodeTree[currentSourceId[sr]].includes('end') &&
								targetId === this.nodeTree[currentSourceId[sr]]) {
								return false
							}
						}
					}
					// 源节点的目标节点结束了就不能相连
					// const selectSourceNode = this.selectNodes.find(node => node.sourceId === sourceId || node.sourceId === targetId)
					// if (selectSourceNode && selectSourceNode.targetId === 'end') {
					// 	return false
					// }
					let targetNodeCompare = this.selectNodes.find(node => node.targetId === targetId)
					if (targetNodeCompare && (targetNodeCompare.sourceId === 'start' || sourceId === 'start')) {
						return false
					}
					targetNodeCompare = this.selectNodes.find(node => node.sourceId === sourceId)
					if (targetNodeCompare && targetId === 'end') {
						return false
					}
					targetNodeCompare = this.selectNodes.find(node => node.sourceId === sourceId && node.targetId === 'end')
					if (targetNodeCompare) {
						return false
					}
					// 两个不同的源节点不能是相同的目标节点(结束节点除外)
					const sourceNodeCompare = this.selectNodes.find(node => node.targetId === targetId && node.sourceId !== sourceId)
					if (sourceNodeCompare && sourceNodeCompare.targetId !== 'end') {
						// return false
					}
					this.setSelectNodes(sourceId, targetId)
					return true
				})
				// 获取路由信息
				this.getProcessInfo()
				// 监听窗口变化
				this.listenWindowResize()
			})
		},

拖拽节点连线

packageNode(processNodes = []) {
			processNodes.forEach(item => {
				const {sourceId, targetId, uuid, subMilestone, children = []} = item
				this.nodeList.push(item)
				this.$nextTick(() => {
					this.jsPlumb.draggable(uuid, {
						containment: "flowWrap",
					})
					this.addpoint(uuid, 'Left')
					this.addpoint(uuid, 'Right')
					this.makePoint(uuid, 'makeSource')
					this.makePoint(uuid, 'makeTarget')
					if (sourceId.indexOf(',') !== -1) {
						let sourceIdSplit = sourceId.split(',')
						sourceIdSplit.forEach(node => {
							this.setSelectNodes(node, targetId)
							this.jsPlumb.connect({
								source: node,
								target: targetId
							}, {
								anchor: node === 'start' ? ['Right', 'Left'] : ['Left', 'Right']
							})
							if (subMilestone === false) {
								this.setSelectNodes(targetId, 'end')
								this.jsPlumb.connect({
									source: targetId,
									target: "end"
								}, {
									anchor: ['Right', 'Left']
								})
							}
						})
						return
					}
					this.setSelectNodes(sourceId, targetId)
					this.jsPlumb.connect({
						source: sourceId,
						target: targetId
					}, {
						anchor: sourceId === 'start' ? ['Right', 'Left'] : ['Left', 'Right']
					})
					if (subMilestone === false) {
						this.setSelectNodes(targetId, 'end')
						this.jsPlumb.connect({
							source: targetId,
							target: "end"
						}, {
							anchor: ['Right', 'Left']
						})
					}
				})
			})
		},
onDragEnd(event) {
			const {x, y} = event
			if (x < (this.menuIscollapse ? 320 : 200)) return
			if (y < 170) return
			const uuid = `processNode${new Date().getTime()}`
			this.nodeList.push({
				uuid,
				left: this.menuIscollapse ? x - 360 : x- 200,
				top: y - 170
			})
			this.$nextTick(() => {
				this.jsPlumb.draggable(uuid, {
					containment: "flowWrap"
				})
				this.addpoint(uuid, 'Left')
				this.addpoint(uuid, 'Right')
			})
		},

获取节点连线数据

const connectNodeData = this.jsPlumb.getConnections()