@logicflow/extension
Version:
LogicFlow Extensions
236 lines (235 loc) • 9.48 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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));
};
import { uniqBy, concat } from 'lodash-es';
// 后续并入FlowPath
var getPath = function (id, lf) {
var el = lf.getModelById(id);
return getNodePath((el === null || el === void 0 ? void 0 : el.BaseType) === 'node' ? el : el === null || el === void 0 ? void 0 : el.targetNode, lf);
};
// dfs + 动态规划
// todo 算法优化
var getNodePath = function (node, lf) {
var incomingPaths = [];
var outgoingPaths = [];
var getIncomingPaths = function (curNode, path, prevNode) {
if (!curNode)
return;
if (prevNode) {
// * 上个节点和当前节点中间边
path.unshift.apply(path, __spreadArray([], __read(lf
.getEdgeModels({
sourceNodeId: curNode.id,
targetNodeId: prevNode === null || prevNode === void 0 ? void 0 : prevNode.id,
})
.map(function (item) { return item.id; })), false));
}
// * 路径中存在节点,则不再继续查找,说明出现环情况
if (path.includes(curNode.id)) {
incomingPaths.push(path);
return;
}
// * 路径中当前加入节点
path.unshift(curNode.id);
if (!curNode.incoming.nodes.length) {
incomingPaths.push(path);
return;
}
// * 往下找
curNode.incoming.nodes.forEach(function (nextNode) {
getIncomingPaths(nextNode, path.slice(), curNode);
});
};
// * 同上逻辑
var getOutgoingPaths = function (curNode, path, prevNode) {
if (!curNode)
return;
if (prevNode) {
path.push.apply(path, __spreadArray([], __read(lf
.getEdgeModels({
sourceNodeId: prevNode === null || prevNode === void 0 ? void 0 : prevNode.id,
targetNodeId: curNode.id,
})
.map(function (item) { return item.id; })), false));
}
if (path.includes(curNode.id)) {
outgoingPaths.push(path);
return;
}
path.push(curNode.id);
if (!curNode.outgoing.nodes.length) {
outgoingPaths.push(path);
return;
}
curNode.outgoing.nodes.forEach(function (nextNode) {
getOutgoingPaths(nextNode, path.slice(), curNode);
});
};
getIncomingPaths(node, []);
getOutgoingPaths(node, []);
return __spreadArray([], __read(new Set(__spreadArray(__spreadArray([], __read(incomingPaths.flat()), false), __read(outgoingPaths.flat()), false))), false);
};
var Highlight = /** @class */ (function () {
function Highlight(_a) {
var lf = _a.lf, options = _a.options;
this.mode = 'path';
this.enable = true;
this.tempStyles = {};
var _b = options.mode, mode = _b === void 0 ? 'path' : _b, _c = options.enable, enable = _c === void 0 ? true : _c;
this.lf = lf;
this.mode = mode;
this.enable = enable;
}
Highlight.prototype.setMode = function (mode) {
this.mode = mode;
};
Highlight.prototype.setEnable = function (enable) {
this.enable = enable;
};
Highlight.prototype.highlightSingle = function (id) {
var model = this.lf.getModelById(id);
if ((model === null || model === void 0 ? void 0 : model.BaseType) === 'node') {
// 高亮节点
model.updateStyles(this.tempStyles[id]);
}
else if ((model === null || model === void 0 ? void 0 : model.BaseType) === 'edge') {
// 高亮边及对应的节点
model.updateStyles(this.tempStyles[id]);
model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id]);
model.targetNode.updateStyles(this.tempStyles[model.targetNode.id]);
}
this.lf.emit('highlight:single', {
data: model,
});
};
Highlight.prototype.highlightNeighbours = function (id) {
var _this = this;
var model = this.lf.getModelById(id);
var relateElements = [];
if ((model === null || model === void 0 ? void 0 : model.BaseType) === 'node') {
// 高亮节点
model.updateStyles(this.tempStyles[id]);
var _a = model.incoming, incomingNodes = _a.nodes, incomingEdges = _a.edges;
var _b = model.outgoing, outgoingNodes = _b.nodes, outgoingEdges = _b.edges;
concat(incomingNodes, outgoingNodes).forEach(function (node) {
node.updateStyles(_this.tempStyles[node.id]);
});
concat(incomingEdges, outgoingEdges).forEach(function (edge) {
edge.updateStyles(_this.tempStyles[edge.id]);
});
relateElements = uniqBy(concat(relateElements, incomingNodes, outgoingNodes, incomingEdges, outgoingEdges), 'id');
}
else if ((model === null || model === void 0 ? void 0 : model.BaseType) === 'edge') {
// 高亮边及对应的节点
model.updateStyles(this.tempStyles[id]);
model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id]);
model.targetNode.updateStyles(this.tempStyles[model.targetNode.id]);
relateElements = [model.sourceNode, model.targetNode];
}
this.lf.emit('highlight:neighbours', {
data: model,
relateElements: relateElements,
});
};
Highlight.prototype.highlightPath = function (id) {
var _this = this;
var path = getPath(id, this.lf);
var relateElements = [];
path.forEach(function (_id) {
var elementModel = _this.lf.getModelById(_id);
// 高亮路径上所有的边和节点
elementModel === null || elementModel === void 0 ? void 0 : elementModel.updateStyles(_this.tempStyles[_id]);
relateElements.push(elementModel);
});
this.lf.emit('highlight:path', {
data: this.lf.getModelById(id),
relateElements: relateElements,
});
};
Highlight.prototype.highlight = function (id, mode) {
var _this = this;
if (mode === void 0) { mode = this.mode; }
if (!this.enable)
return;
if (Object.keys(this.tempStyles).length) {
this.restoreHighlight();
}
Object.values(this.lf.graphModel.modelsMap).forEach(function (item) {
// 所有节点样式都进行备份
var oStyle = item.BaseType === 'node' ? item.getNodeStyle() : item.getEdgeStyle();
_this.tempStyles[item.id] = __assign({}, oStyle);
// 所有节点都设置透明度为0.1
item.setStyles({ opacity: 0.1 });
});
var modeTrigger = {
single: this.highlightSingle.bind(this),
neighbour: this.highlightNeighbours.bind(this),
path: this.highlightPath.bind(this),
};
modeTrigger[mode](id);
};
Highlight.prototype.restoreHighlight = function () {
var _this = this;
// 恢复所有节点的样式
if (!Object.keys(this.tempStyles).length)
return;
Object.values(this.lf.graphModel.modelsMap).forEach(function (item) {
var _a;
var oStyle = (_a = _this.tempStyles[item.id]) !== null && _a !== void 0 ? _a : {};
item.updateStyles(__assign({}, oStyle));
});
this.tempStyles = {};
};
Highlight.prototype.render = function () {
var _this = this;
this.lf.on('node:mouseenter', function (_a) {
var data = _a.data;
return _this.highlight(data.id);
});
this.lf.on('edge:mouseenter', function (_a) {
var data = _a.data;
return _this.highlight(data.id);
});
this.lf.on('node:mouseleave', this.restoreHighlight.bind(this));
this.lf.on('edge:mouseleave', this.restoreHighlight.bind(this));
this.lf.on('history:change', this.restoreHighlight.bind(this));
};
Highlight.prototype.destroy = function () { };
Highlight.pluginName = 'highlight';
return Highlight;
}());
export { Highlight };
export default Highlight;