Files
mosr-web/src/views/custom-query/topo/top/behavior/drag-add-edge.js
2024-03-04 19:13:43 +08:00

233 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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;
}
}
}
};