index.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. var __assign = (this && this.__assign) || function () {
  2. __assign = Object.assign || function(t) {
  3. for (var s, i = 1, n = arguments.length; i < n; i++) {
  4. s = arguments[i];
  5. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  6. t[p] = s[p];
  7. }
  8. return t;
  9. };
  10. return __assign.apply(this, arguments);
  11. };
  12. var __read = (this && this.__read) || function (o, n) {
  13. var m = typeof Symbol === "function" && o[Symbol.iterator];
  14. if (!m) return o;
  15. var i = m.call(o), r, ar = [], e;
  16. try {
  17. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  18. }
  19. catch (error) { e = { error: error }; }
  20. finally {
  21. try {
  22. if (r && !r.done && (m = i["return"])) m.call(i);
  23. }
  24. finally { if (e) throw e.error; }
  25. }
  26. return ar;
  27. };
  28. var __spread = (this && this.__spread) || function () {
  29. for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
  30. return ar;
  31. };
  32. // 后续并入FlowPath
  33. var getPath = function (id, lf) {
  34. var el = lf.getModelById(id);
  35. return getNodePath(el.BaseType === 'node' ? el : el.targetNode, lf);
  36. };
  37. // dfs + 动态规划
  38. // todo 算法优化
  39. var getNodePath = function (node, lf) {
  40. var incomingPaths = [];
  41. var outgoingPaths = [];
  42. var getIncomingPaths = function (curNode, path, prevNode) {
  43. if (prevNode === void 0) { prevNode = null; }
  44. if (prevNode) {
  45. // * 上个节点和当前节点中间边
  46. path.unshift.apply(path, __spread(lf
  47. .getEdgeModels({
  48. sourceNodeId: curNode.id,
  49. targetNodeId: prevNode.id,
  50. })
  51. .map(function (item) { return item.id; })));
  52. }
  53. // * 路径中存在节点,则不再继续查找,说明出现环情况
  54. if (path.includes(curNode.id)) {
  55. incomingPaths.push(path);
  56. return;
  57. }
  58. // * 路径中当前加入节点
  59. path.unshift(curNode.id);
  60. if (!curNode.incoming.nodes.length) {
  61. incomingPaths.push(path);
  62. return;
  63. }
  64. // * 往下找
  65. curNode.incoming.nodes.forEach(function (nextNode) {
  66. getIncomingPaths(nextNode, path.slice(), curNode);
  67. });
  68. };
  69. // * 同上逻辑
  70. var getOutgoingPaths = function (curNode, path, prevNode) {
  71. if (prevNode === void 0) { prevNode = null; }
  72. if (prevNode) {
  73. path.push.apply(path, __spread(lf
  74. .getEdgeModels({
  75. sourceNodeId: prevNode.id,
  76. targetNodeId: curNode.id,
  77. })
  78. .map(function (item) { return item.id; })));
  79. }
  80. if (path.includes(curNode.id)) {
  81. outgoingPaths.push(path);
  82. return;
  83. }
  84. path.push(curNode.id);
  85. if (!curNode.outgoing.nodes.length) {
  86. outgoingPaths.push(path);
  87. return;
  88. }
  89. curNode.outgoing.nodes.forEach(function (nextNode) {
  90. getOutgoingPaths(nextNode, path.slice(), curNode);
  91. });
  92. };
  93. getIncomingPaths(node, []);
  94. getOutgoingPaths(node, []);
  95. return __spread(new Set(__spread(incomingPaths.flat(), outgoingPaths.flat())));
  96. };
  97. var Highlight = /** @class */ (function () {
  98. function Highlight(_a) {
  99. var lf = _a.lf;
  100. this.mode = 'path';
  101. this.manual = false;
  102. this.tempStyles = {};
  103. this.lf = lf;
  104. }
  105. Highlight.prototype.setMode = function (mode) {
  106. this.mode = mode;
  107. };
  108. Highlight.prototype.setManual = function (manual) {
  109. this.manual = manual;
  110. };
  111. Highlight.prototype.highlightSingle = function (id) {
  112. var model = this.lf.getModelById(id);
  113. if (model.BaseType === 'node') {
  114. // 高亮节点
  115. model.updateStyles(this.tempStyles[id]);
  116. }
  117. else if (model.BaseType === 'edge') {
  118. // 高亮边及对应的节点
  119. model.updateStyles(this.tempStyles[id]);
  120. model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id]);
  121. model.targetNode.updateStyles(this.tempStyles[model.targetNode.id]);
  122. }
  123. };
  124. Highlight.prototype.highlightPath = function (id) {
  125. var _this = this;
  126. var path = getPath(id, this.lf);
  127. path.forEach(function (_id) {
  128. // 高亮路径上所有的边和节点
  129. _this.lf.getModelById(_id).updateStyles(_this.tempStyles[_id]);
  130. });
  131. };
  132. Highlight.prototype.highlight = function (id, mode) {
  133. var _this = this;
  134. if (mode === void 0) { mode = this.mode; }
  135. if (this.manual)
  136. return;
  137. if (Object.keys(this.tempStyles).length) {
  138. this.restoreHighlight();
  139. }
  140. Object.values(this.lf.graphModel.modelsMap).forEach(function (item) {
  141. // 所有节点样式都进行备份
  142. var oStyle = item.BaseType === 'node' ? item.getNodeStyle() : item.getEdgeStyle();
  143. _this.tempStyles[item.id] = __assign({}, oStyle);
  144. // 所有节点都设置透明度为0.1
  145. item.setStyles({ opacity: 0.1 });
  146. });
  147. var modeTrigger = {
  148. single: this.highlightSingle.bind(this),
  149. path: this.highlightPath.bind(this),
  150. };
  151. modeTrigger[mode](id);
  152. };
  153. Highlight.prototype.restoreHighlight = function () {
  154. var _this = this;
  155. // 恢复所有节点的样式
  156. if (!Object.keys(this.tempStyles).length)
  157. return;
  158. Object.values(this.lf.graphModel.modelsMap).forEach(function (item) {
  159. var _a;
  160. var oStyle = (_a = _this.tempStyles[item.id]) !== null && _a !== void 0 ? _a : {};
  161. item.updateStyles(__assign({}, oStyle));
  162. });
  163. this.tempStyles = {};
  164. };
  165. Highlight.prototype.render = function (lf, domContainer) {
  166. var _this = this;
  167. this.lf.on('node:mouseenter', function (_a) {
  168. var data = _a.data;
  169. return _this.highlight(data.id);
  170. });
  171. this.lf.on('edge:mouseenter', function (_a) {
  172. var data = _a.data;
  173. return _this.highlight(data.id);
  174. });
  175. this.lf.on('node:mouseleave', this.restoreHighlight.bind(this));
  176. this.lf.on('edge:mouseleave', this.restoreHighlight.bind(this));
  177. this.lf.on('history:change', this.restoreHighlight.bind(this));
  178. };
  179. Highlight.prototype.destroy = function () { };
  180. Highlight.pluginName = 'highlight';
  181. return Highlight;
  182. }());
  183. export { Highlight };