index.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. var __read = (this && this.__read) || function (o, n) {
  2. var m = typeof Symbol === "function" && o[Symbol.iterator];
  3. if (!m) return o;
  4. var i = m.call(o), r, ar = [], e;
  5. try {
  6. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  7. }
  8. catch (error) { e = { error: error }; }
  9. finally {
  10. try {
  11. if (r && !r.done && (m = i["return"])) m.call(i);
  12. }
  13. finally { if (e) throw e.error; }
  14. }
  15. return ar;
  16. };
  17. var COMMON_TYPE_KEY = 'menu-common';
  18. var NEXT_X_DISTANCE = 200;
  19. var NEXT_Y_DISTANCE = 100;
  20. var ContextMenu = /** @class */ (function () {
  21. function ContextMenu(_a) {
  22. var _this = this;
  23. var lf = _a.lf;
  24. this.menuTypeMap = new Map();
  25. this.listenDelete = function () {
  26. _this.hideContextMenu();
  27. };
  28. this.lf = lf;
  29. this.__menuDOM = document.createElement('div');
  30. this.__menuDOM.className = 'lf-inner-context';
  31. this.menuTypeMap.set(COMMON_TYPE_KEY, []);
  32. this.lf.setContextMenuByType = function (type, menus) {
  33. _this.setContextMenuByType(type, menus);
  34. };
  35. this.lf.setContextMenuItems = function (menus) {
  36. _this.setContextMenuItems(menus);
  37. };
  38. this.lf.showContextMenu = function (data) {
  39. _this.showContextMenu(data);
  40. };
  41. this.lf.hideContextMenu = function () {
  42. _this.hideContextMenu();
  43. };
  44. }
  45. ContextMenu.prototype.render = function (lf, container) {
  46. var _this = this;
  47. this.container = container;
  48. lf.on('node:click', function (_a) {
  49. var data = _a.data;
  50. _this._activeData = data;
  51. _this.createContextMenu();
  52. });
  53. lf.on('edge:click', function (_a) {
  54. var data = _a.data;
  55. // 获取右上角坐标
  56. _this._activeData = data;
  57. _this.createContextMenu();
  58. });
  59. lf.on('blank:click', function () {
  60. _this.hideContextMenu();
  61. });
  62. };
  63. ContextMenu.prototype.setContextMenuByType = function (type, menus) {
  64. this.menuTypeMap.set(type, menus);
  65. };
  66. /**
  67. * 隐藏菜单
  68. */
  69. ContextMenu.prototype.hideContextMenu = function () {
  70. this.__menuDOM.innerHTML = '';
  71. this.__menuDOM.style.display = 'none';
  72. if (this.isShow) {
  73. this.container.removeChild(this.__menuDOM);
  74. }
  75. this.lf.off('node:delete,edge:delete,node:drag,graph:transform', this.listenDelete);
  76. this.isShow = false;
  77. };
  78. /**
  79. * 显示指定元素菜单
  80. * @param data 节点id、节点类型、菜单位置
  81. */
  82. ContextMenu.prototype.showContextMenu = function (data) {
  83. if (!data || !data.id) {
  84. console.warn('请检查传入的参数');
  85. return;
  86. }
  87. this._activeData = data;
  88. this.createContextMenu();
  89. };
  90. ContextMenu.prototype.setContextMenuItems = function (menus) {
  91. this.menuTypeMap.set(COMMON_TYPE_KEY, menus);
  92. };
  93. /**
  94. * 获取新菜单位置
  95. */
  96. ContextMenu.prototype.getContextMenuPosition = function () {
  97. var data = this._activeData;
  98. var Model = this.lf.graphModel.getElement(data.id);
  99. if (!Model) {
  100. console.warn("\u627E\u4E0D\u5230\u5143\u7D20" + data.id);
  101. return;
  102. }
  103. var x;
  104. var y;
  105. if (Model.BaseType === 'edge') {
  106. x = Number.MIN_SAFE_INTEGER;
  107. y = Number.MAX_SAFE_INTEGER;
  108. var edgeData = Model.getData();
  109. x = Math.max(edgeData.startPoint.x, x);
  110. y = Math.min(edgeData.startPoint.y, y);
  111. x = Math.max(edgeData.endPoint.x, x);
  112. y = Math.min(edgeData.endPoint.y, y);
  113. if (edgeData.pointsList) {
  114. edgeData.pointsList.forEach(function (point) {
  115. x = Math.max(point.x, x);
  116. y = Math.min(point.y, y);
  117. });
  118. }
  119. }
  120. if (Model.BaseType === 'node') {
  121. x = data.x + Model.width / 2;
  122. y = data.y - Model.height / 2;
  123. }
  124. return this.lf.graphModel.transformModel.CanvasPointToHtmlPoint([x, y]);
  125. };
  126. ContextMenu.prototype.createContextMenu = function () {
  127. var _this = this;
  128. var isSilentMode = this.lf.options.isSilentMode;
  129. // 静默模式不显示菜单
  130. if (isSilentMode) {
  131. return;
  132. }
  133. var items = this.menuTypeMap.get(this._activeData.type) || [];
  134. items = items.concat(this.menuTypeMap.get(COMMON_TYPE_KEY));
  135. var menus = document.createDocumentFragment();
  136. items.forEach(function (item) {
  137. var menuItem = document.createElement('div');
  138. menuItem.className = 'lf-context-item';
  139. var img = document.createElement('img');
  140. img.src = item.icon;
  141. img.className = 'lf-context-img';
  142. if (item.className) {
  143. menuItem.className = menuItem.className + " " + item.className;
  144. }
  145. img.addEventListener('click', function () {
  146. _this.hideContextMenu();
  147. if (item.callback) {
  148. item.callback(_this._activeData);
  149. }
  150. else {
  151. _this.addNode({
  152. sourceId: _this._activeData.id,
  153. x: _this._activeData.x,
  154. y: _this._activeData.y,
  155. properties: item.properties,
  156. type: item.type,
  157. });
  158. }
  159. });
  160. menuItem.appendChild(img);
  161. menus.appendChild(menuItem);
  162. });
  163. this.__menuDOM.innerHTML = '';
  164. this.__menuDOM.appendChild(menus);
  165. this.showMenu();
  166. };
  167. ContextMenu.prototype.addNode = function (node, y) {
  168. var isDeep = y !== undefined;
  169. if (y === undefined) {
  170. y = node.y;
  171. }
  172. var nodeModel = this.lf.getNodeModelById(node.sourceId);
  173. var leftTopX = node.x - nodeModel.width + NEXT_X_DISTANCE;
  174. var leftTopY = y - node.y / 2 - 20;
  175. var rightBottomX = node.x + nodeModel.width + NEXT_X_DISTANCE;
  176. var rightBottomY = y + node.y / 2 + 20;
  177. var existElements = this.lf.getAreaElement([leftTopX, leftTopY], [rightBottomX, rightBottomY]);
  178. if (existElements.length) {
  179. y = y + NEXT_Y_DISTANCE;
  180. this.addNode(node, y);
  181. return;
  182. }
  183. var newNode = this.lf.addNode({
  184. type: node.type,
  185. x: node.x + 200,
  186. y: y,
  187. properties: node.properties,
  188. });
  189. var startPoint;
  190. var endPoint;
  191. if (isDeep) {
  192. startPoint = {
  193. x: node.x,
  194. y: node.y + nodeModel.height / 2,
  195. };
  196. endPoint = {
  197. x: newNode.x - newNode.width / 2,
  198. y: newNode.y,
  199. };
  200. }
  201. this.lf.addEdge({
  202. sourceNodeId: node.sourceId,
  203. targetNodeId: newNode.id,
  204. startPoint: startPoint,
  205. endPoint: endPoint,
  206. });
  207. };
  208. ContextMenu.prototype.showMenu = function () {
  209. var _a = __read(this.getContextMenuPosition(), 2), x = _a[0], y = _a[1];
  210. this.__menuDOM.style.display = 'flex';
  211. this.__menuDOM.style.top = y + "px";
  212. this.__menuDOM.style.left = x + 10 + "px";
  213. this.container.appendChild(this.__menuDOM);
  214. // 菜单显示的时候,监听删除,同时隐藏
  215. !this.isShow && this.lf.on('node:delete,edge:delete,node:drag,graph:transform', this.listenDelete);
  216. this.isShow = true;
  217. };
  218. ContextMenu.pluginName = 'contextMenu';
  219. return ContextMenu;
  220. }());
  221. export default ContextMenu;
  222. export { ContextMenu, };