@logicflow/extension
Version:
LogicFlow Extensions
229 lines (228 loc) • 8.92 kB
JavaScript
/**
* 路径插件,此插件支持获取绘制的图中所有的路径。
* 需要指定开始节点类型。
*/
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowPath = void 0;
var getBpmnId_1 = require("../../bpmn/getBpmnId");
var FlowPath = /** @class */ (function () {
function FlowPath(_a) {
var lf = _a.lf;
var _this = this;
this.lf = lf;
this.paths = [];
// 给lf添加方法
lf.getPathes = function () {
if (!_this.startNodeType) {
throw new Error('需要预先指定开始节点类型');
}
return _this.getPathes();
};
lf.setRawPaths = function (paths) {
_this.setPathes(paths);
};
lf.getRawPathes = function () { return _this.paths; };
lf.setStartNodeType = function (type) {
_this.startNodeType = type;
};
}
FlowPath.prototype.setPathes = function (paths) {
this.paths = paths.map(function (_a) {
var routeId = _a.routeId, name = _a.name, elements = _a.elements, type = _a.type;
return ({
routeId: routeId,
name: name,
elements: elements,
type: type,
similarElement: null,
weight: 0,
});
});
};
FlowPath.prototype.getPathes = function () {
var _this = this;
var graphData = this.lf.getGraphRawData();
var nodesMap = new Map();
var startNodeIds = [];
graphData.nodes.forEach(function (node) {
nodesMap.set(node.id, {
id: node.id,
data: node,
nextNodes: [],
});
if (node.type === _this.startNodeType) {
startNodeIds.push(node.id);
}
});
graphData.edges.forEach(function (edge) {
var node = nodesMap.get(edge.sourceNodeId);
node === null || node === void 0 ? void 0 : node.nextNodes.push(edge.targetNodeId);
});
var pathElements = [];
startNodeIds.forEach(function (id) {
var node = nodesMap.get(id);
if (node) {
pathElements = pathElements.concat(_this.findPathElements(node, nodesMap, []));
}
});
return this.getNewPathes(pathElements);
};
FlowPath.prototype.findPathElements = function (node, nodesMap, elements) {
if (elements === void 0) { elements = []; }
var newPaths = __spreadArray([], __read(elements), false);
newPaths.push(node.id);
if (node.nextNodes.length === 0) {
return [newPaths];
}
var subPath = [];
for (var i = 0; i < node.nextNodes.length; i++) {
var n = nodesMap.get(node.nextNodes[i]);
var p
// 循环路径
= void 0;
// 循环路径
if (n) {
var idx = newPaths.indexOf(n.id);
if (idx !== -1) {
p = [__spreadArray(__spreadArray([], __read(newPaths.slice(idx)), false), [n.id], false)];
}
else {
p = this.findPathElements(n, nodesMap, __spreadArray([], __read(newPaths), false));
}
subPath = subPath.concat(p);
}
}
return subPath;
};
/**
* 设置路径id
* 如果存在原始路径Id, 则需要比较新路径是否在原始路径中存在相似路径
* 如果有,则尽量使用原始路径。
* 相似路径
* 1. 如果所有的节点都相同,则必定为同一路径。(包括顺序不同)
* 2. 如果新路径比原来路径少了或者多了部分节点,则记录为相似路径。基于不同的差异,标记不同的权重。
* 3. 基于新路径在旧路径占用权限,设置新路径Id.
* 4. 如果某一条旧路径被多条新路径标记为相同的权重,则这两条新路径都使用新Id.
*/
FlowPath.prototype.getNewPathes = function (pathElements) {
var _this = this;
var paths = [];
// 由于循环路径不包括开始,所以存在重复的情况,此处去重。
var LoopSet = new Set();
pathElements.forEach(function (elements) {
var routeId = _this.getNewId('path');
var name = _this.getNewId('路径');
var isLoop = _this.isLoopPath(elements);
var elementStr = elements.join(',');
if (!LoopSet.has(elementStr)) {
LoopSet.add(elementStr);
paths.push({
routeId: routeId,
name: name,
elements: elements,
type: isLoop,
weight: 0,
similarElement: '',
});
}
});
var oldPaths = JSON.parse(JSON.stringify(this.paths));
// 1) 找到所有路径最相似的路径, 给旧路径标记其最接近的路径
paths.forEach(function (newPath) {
for (var i = 0; i < oldPaths.length; i++) {
var oldPath = oldPaths[i];
var weight = _this.similar2Path(__spreadArray([], __read(newPath.elements), false), __spreadArray([], __read(oldPath.elements), false));
if (weight > newPath.weight && oldPath.weight <= weight) {
newPath.weight = weight;
newPath.similarElement = oldPath;
if (weight === oldPath.weight && oldPath.similarElement) {
// 特殊处理,如果两个路径都与同一条旧路径有相似的权重,则这两个路径的相似路径都置空
oldPath.similarElement.similarElement = null;
oldPath.similarElement.weight = 0;
oldPath.similarElement = null;
oldPath.weight = 0;
}
else {
oldPath.similarElement = newPath;
oldPath.weight = weight;
}
}
}
});
// 2) 再次遍历所有路径,如果该路径的相似路径对应的相似路径是自己,那么就设置该路径id和name为其相似路径。
paths.forEach(function (newPath) {
if (newPath.similarElement &&
newPath.similarElement.similarElement === newPath) {
newPath.routeId = newPath.similarElement.routeId;
newPath.name = newPath.similarElement.name;
}
delete newPath.similarElement;
delete newPath.weight;
});
this.setPathes(paths);
return paths;
};
FlowPath.prototype.similar2Path = function (x, y) {
var z = 0;
var s = x.length + y.length;
x.sort();
y.sort();
var a = x.shift();
var b = y.shift();
while (a !== undefined && b !== undefined) {
if (a === b) {
z++;
a = x.shift();
b = y.shift();
}
else if (a < b) {
a = x.shift();
}
else if (a > b) {
b = y.shift();
}
}
return (z / s) * 200;
};
FlowPath.prototype.getNewId = function (prefix) {
return "".concat(prefix, "_").concat((0, getBpmnId_1.getBpmnId)());
};
/**
* 判断是否为循环路径
* 由于前面进行了特殊处理,将循环部分单独提出来作为路径
* 所有循环路径必定开始节点等于结束节点。
*/
FlowPath.prototype.isLoopPath = function (elements) {
var length = elements.length;
return elements.indexOf(elements[length - 1]) !== length - 1 ? 1 : 0;
};
FlowPath.pluginName = 'flowPath';
return FlowPath;
}());
exports.FlowPath = FlowPath;
;