/** * @author: clay * @data: 2019/07/16 * @description: edit mode: 通过拖拽节点上的锚点添加连线 */ import utils from "../../utils"; import theme from "../theme"; import {ElMessage} from "element-plus"; // 用来获取调用此js的vue组件实例(this) let vm = null; const sendThis = (_this) => { vm = _this; }; export default { sendThis, // 暴露函数 name: "drag-add-edge", options: { getEvents() { return { "node:mousedown": "onNodeMousedown", "node:mouseup": "onNodeMouseup", "edge:mouseup": "onEdgeMouseup", "mousemove": "onMousemove" }; }, onNodeMousedown(event) { let self = this; // 交互过程中的信息 self.evtInfo = { action: null, node: event.item, target: event.target, }; if (self.evtInfo.target && self.evtInfo.target.attrs.name) { // todo...未来可能针对锚点增加其它功能(例如拖拽调整大小) switch (self.evtInfo.target.attrs.name) { case "anchor"://点击锚点中间 self.evtInfo.action = "drawEdge"; break; case "anchorBg"://点击锚点 self.evtInfo.action = "drawEdge"; break; } } if (self.evtInfo && self.evtInfo.action) { self[self.evtInfo.action].start.call(self, event); } }, onNodeMouseup(event) { let self = this; if (self.evtInfo && self.evtInfo.action) { self[self.evtInfo.action].stop.call(self, event); } }, onEdgeMouseup(event) { let self = this; if (self.evtInfo && self.evtInfo.action === "drawEdge") { self[self.evtInfo.action].stop.call(self, event); } }, onMousemove(event) { let self = this; if (self.evtInfo && self.evtInfo.action) { self[self.evtInfo.action].move.call(self, event); } }, drawEdge: { isMoving: false, currentLine: null, start: function (event) { let self = this; let themeStyle = theme.defaultStyle; // todo...先使用默认主题,后期可能增加其它风格的主体 // ************** 暂存【连线】前的数据状态 start ************** let graph = vm.getGraph(); self.historyData = JSON.stringify(graph.save()); // ************** 暂存【连线】前的数据状态 end ************** let sourceAnchor = self.evtInfo.node.getAnchorPoints(); let sourceNodeModel = toRaw(self.evtInfo.node.getModel()); // 锚点数据 let anchorPoints = self.evtInfo.node.getAnchorPoints(); // 处理线条目标点 if (anchorPoints && anchorPoints.length) { // 获取距离指定坐标最近的一个锚点 sourceAnchor = self.evtInfo.node.getLinkPoint({ x: event.x, y: event.y }) } // let relational = vm.getRelationalMap().get(sourceNodeModel.tableId) let relational = vm.getRelationalMap().map(item => { if (item.mainId === sourceNodeModel.tableId) { return item } }) //item.columnName+':'+item.columnComment let columns = [] sourceNodeModel.columns.forEach(item => { let column = { columnName: item.columnName, columnComment: item.columnComment } columns.push(column) }) self.drawEdge.currentLine = self.graph.addItem("edge", { // id: G6.Util.uniqueId(), // 这种生成id的方式有bug,会重复 id: utils.generateUUID(), // 起始节点 source: sourceNodeModel.id, sourceColumn: columns, sourceAnchor: sourceAnchor ? sourceAnchor.anchorIndex : "", // 终止节点/位置 relational: relational, target: { x: event.x, y: event.y }, type: self.graph.$C.edge.type || "top-cubic", style: themeStyle.edgeStyle.default || self.graph.$C.edge.style }); self.drawEdge.isMoving = true; }, move(event) { let self = this; if (self.drawEdge.isMoving && self.drawEdge.currentLine) { self.graph.updateItem(self.drawEdge.currentLine, { target: { x: event.x, y: event.y } }); } }, stop(event) { let self = this; if (self.drawEdge.isMoving) { if (self.drawEdge.currentLine === event.item) { // 画线过程中点击则移除当前画线 self.graph.removeItem(event.item); } else { let targetNode = event.item; let targetNodeModel = toRaw(targetNode.getModel());//节点的数据模型 let targetAnchor = null; // 锚点数据 let anchorPoints = targetNode.getAnchorPoints(); // 处理线条目标点 let relational = self.drawEdge.currentLine.getModel().relational//边的数据模型,start函数中定义的包含该节点的关联关系 let starts = false; let relationalItem = null; if (relational) { relational.map(item => { if (item) { if (item.childId === targetNodeModel.tableId) { starts = true relationalItem = item } else { starts = false } } }) } // 去掉关系验证 // starts = true if (starts) { if (anchorPoints && anchorPoints.length > 0) { // 获取距离指定坐标最近的一个锚点 targetAnchor = targetNode.getLinkPoint({ x: event.x, y: event.y }); } let columns = [] targetNodeModel.columns.forEach(item => { let column = { columnName: item.columnName, columnComment: item.columnComment } columns.push(column) }) self.graph.updateItem(self.drawEdge.currentLine, { target: targetNodeModel.id, relationalItem: relationalItem, targetAnchor: targetAnchor ? targetAnchor.anchorIndex : "", targetColumn: columns, }); // ************** 记录historyData的逻辑 start ************** if (self.historyData) { let graph = self.graph; // 如果当前点过【撤销】了,拖拽节点后没有【重做】功能 // 重置undoCount,拖拽后的数据给(当前所在historyIndex + 1),且清空这个时间点之后的记录 if (vm.getUndoCount() > 0) { vm.editHistoryIndex(vm.getHistoryIndex() - vm.getUndoCount()); // 此时的historyIndex应当更新为【撤销】后所在的索引位置 for (let i = 1; i <= vm.getUndoCount(); i++) { let key = `graph_history_${vm.getHistoryIndex() + i}`; vm.removeHistoryData(key); } vm.editUndoCount(0) } else { // 正常顺序执行的情况,记录拖拽线 前的数据状态 let key = `graph_history_${vm.getHistoryIndex()}`; vm.addHistoryData(key, self.historyData); } // 记录拖线后的数据状态 const index = vm.getHistoryIndex() + 1; vm.editHistoryIndex(index); let key = `graph_history_${index}`; let currentData = JSON.stringify(graph.save()); vm.addHistoryData(key, currentData); } } else { if (self.evtInfo.node.getModel().tableId === targetNodeModel.tableId) { ElMessage.warning("不可连接自身") } else { ElMessage.warning("两表之间无关联关系") } self.graph.removeItem(self.drawEdge.currentLine); } // ************** 记录historyData的逻辑 end ************** } } self.drawEdge.currentLine = null; self.drawEdge.isMoving = false; self.evtInfo = null; } } } };