import panzoom from 'panzoom' import {tbType} from './tbType.js' const coreMethods = { init() { this.jsPlumb.ready(() => { // 导入默认配置 this.jsPlumb.importDefaults(this.jsPlumbSetting) this.loadFlow() this.initPanZoom() // 会使整个jsPlumb立即重绘。 this.jsPlumb.setSuspendDrawing(false, true) }) }, // 加载 loadFlow() { if (!this.json || !this.json.nodes || this.json.nodes.length === 0) { this.$message.error('json中nodes数组不能为空') return } if (!this.json || !this.json.nodes) { this.$message.error('json中edges数组不能是未定义') return } // 初始化节点 this.json.nodes.forEach(node => { this.jsPlumb.draggable(node.id, { grid: this.commonGrid }) const nodeType = node.type node.columns.forEach(col => { const colID = `${nodeType}${this.minus}${node.name}${this.minus}${col.name}` const props = {tbName: node.name, column: col.name} // 节点类型不同,添加端点的方向也不同.对于Origin/RS表来说 它们都只有一侧有端点.其他表都视为中间表两侧都有端点 if (nodeType === tbType['Origin'].type) { this.addEndpoint( colID, ['Right'], { isSource: true }, props ) } else if (nodeType === tbType['RS'].type) { this.addEndpoint( colID, ['Left'], { isTarget: true }, props ) } else { this.addEndpoint( colID, ['Right', 'Left'], { isSource: true, isTarget: true }, props ) } }) }) // 初始化连线 this.json.edges.forEach(edge => { let fromFull = tbType['Origin'].type + this.minus + edge.from.tbName + this.minus + edge.from.column + this.minus + 'Right', toFull = tbType['RS'].type + this.minus + edge.to.tbName + this.minus + edge.to.column + this.minus + 'Left' this.connect(fromFull, toFull) }) // 绑定click点击连线的事件,记录当前选中的连线 this.jsPlumb.bind('click', conn => { if (!conn) { return } if (this.currentConnect && this.currentConnect.id == conn.id) { this.currentConnect = null } else { this.currentConnect = conn } }) }, // 获取连线对应的数据 getEdgeData() { const edges = [] const connections = this.jsPlumb.getAllConnections() if (connections && connections.length > 0) { connections.forEach(conn => { const [source, target] = conn.endpoints const from = source.props const to = target.props edges.push({from, to}) }) } return edges }, addEndpoint(elID, AnchorArr, setting, props) { //AnchorArr 可能有多个锚点需要添加 AnchorArr.forEach(anchor => { const endpoint = this.jsPlumb.addEndpoint( elID, { anchors: anchor, uuid: elID + this.minus + anchor }, Object.assign({}, this.jsPlumbSetting, setting) ) endpoint.props = {...props} }) }, connect(from, to) { this.jsPlumb.connect( { uuids: [from, to] }, this.jsPlumbSetting ) }, initPanZoom() { const mainContainer = this.jsPlumb.getContainer() const mainContainerWrap = mainContainer.parentNode const pan = panzoom(mainContainer, { smoothScroll: false, bounds: true, // autocenter: true, zoomDoubleClickSpeed: 1, minZoom: 0.5, maxZoom: 2, //设置滚动缩放的组合键,默认不需要组合键 beforeWheel: e => { // console.log(e) // let shouldIgnore = !e.ctrlKey // return shouldIgnore }, beforeMouseDown: function(e) { // allow mouse-down panning only if altKey is down. Otherwise - ignore const isSVG = e.target.className.constructor != String const shouldIgnore = e.ctrlKey return shouldIgnore || isSVG } }) this.jsPlumb.mainContainerWrap = mainContainerWrap this.jsPlumb.pan = pan // 缩放时设置jsPlumb的缩放比率 pan.on('zoom', e => { const {x, y, scale} = e.getTransform() this.jsPlumb.setZoom(scale) }) pan.on('panend', e => { const {x, y, scale} = e.getTransform() }) // 平移时设置鼠标样式 mainContainerWrap.style.cursor = 'grab' mainContainerWrap.addEventListener('mousedown', function wrapMousedown() { this.style.cursor = 'grabbing' mainContainerWrap.addEventListener('mouseout', function wrapMouseout() { this.style.cursor = 'grab' }) }) mainContainerWrap.addEventListener('mouseup', function wrapMouseup() { this.style.cursor = 'grab' }) }, //初始化节点位置 (以便对齐,居中) fixNodesPosition() { if (this.json.nodes && this.$refs.flowWrap) { const nodeWidth = 120 const nodeHeight = 40 let wrapInfo = this.$refs.flowWrap.getBoundingClientRect() let maxLeft = 0, minLeft = wrapInfo.width, maxTop = 0, minTop = wrapInfo.height let nodePoint = { left: 0, right: 0, top: 0, bottom: 0 } let fixTop = 0, fixLeft = 0 this.json.nodes.forEach(el => { let top = el.top let left = el.left maxLeft = left > maxLeft ? left : maxLeft minLeft = left < minLeft ? left : minLeft maxTop = top > maxTop ? top : maxTop minTop = top < minTop ? top : minTop }) nodePoint.left = minLeft nodePoint.right = wrapInfo.width - maxLeft - nodeWidth nodePoint.top = minTop nodePoint.bottom = wrapInfo.height - maxTop - nodeHeight fixTop = nodePoint.top !== nodePoint.bottom ? (nodePoint.bottom - nodePoint.top) / 4 : 0 fixLeft = nodePoint.left !== nodePoint.right ? (nodePoint.right - nodePoint.left) / 2 : 0 this.json.nodes.map(el => { let top = Number(el.top) + fixTop let left = Number(el.left) + fixLeft el.top = Math.round(top / 20) * 20 el.left = Math.round(left / 20) * 20 }) } } } export default coreMethods