233 lines
8.3 KiB
JavaScript
233 lines
8.3 KiB
JavaScript
/**
|
||
* @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;
|
||
}
|
||
}
|
||
}
|
||
};
|