collection.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  2. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  3. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  4. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  5. return c > 3 && r && Object.defineProperty(target, key, r), r;
  6. };
  7. import { ArrayExt, Basecoat } from '@antv/x6-common';
  8. export class Collection extends Basecoat {
  9. constructor(cells, options = {}) {
  10. super();
  11. this.length = 0;
  12. this.comparator = options.comparator || 'zIndex';
  13. this.clean();
  14. if (cells) {
  15. this.reset(cells, { silent: true });
  16. }
  17. }
  18. toJSON() {
  19. return this.cells.map((cell) => cell.toJSON());
  20. }
  21. add(cells, index, options) {
  22. let localIndex;
  23. let localOptions;
  24. if (typeof index === 'number') {
  25. localIndex = index;
  26. localOptions = Object.assign({ merge: false }, options);
  27. }
  28. else {
  29. localIndex = this.length;
  30. localOptions = Object.assign({ merge: false }, index);
  31. }
  32. if (localIndex > this.length) {
  33. localIndex = this.length;
  34. }
  35. if (localIndex < 0) {
  36. localIndex += this.length + 1;
  37. }
  38. const entities = Array.isArray(cells) ? cells : [cells];
  39. const sortable = this.comparator &&
  40. typeof index !== 'number' &&
  41. localOptions.sort !== false;
  42. const sortAttr = this.comparator || null;
  43. let sort = false;
  44. const added = [];
  45. const merged = [];
  46. entities.forEach((cell) => {
  47. const existing = this.get(cell);
  48. if (existing) {
  49. if (localOptions.merge && !cell.isSameStore(existing)) {
  50. existing.setProp(cell.getProp(), options); // merge
  51. merged.push(existing);
  52. if (sortable && !sort) {
  53. if (sortAttr == null || typeof sortAttr === 'function') {
  54. sort = existing.hasChanged();
  55. }
  56. else if (typeof sortAttr === 'string') {
  57. sort = existing.hasChanged(sortAttr);
  58. }
  59. else {
  60. sort = sortAttr.some((key) => existing.hasChanged(key));
  61. }
  62. }
  63. }
  64. }
  65. else {
  66. added.push(cell);
  67. this.reference(cell);
  68. }
  69. });
  70. if (added.length) {
  71. if (sortable) {
  72. sort = true;
  73. }
  74. this.cells.splice(localIndex, 0, ...added);
  75. this.length = this.cells.length;
  76. }
  77. if (sort) {
  78. this.sort({ silent: true });
  79. }
  80. if (!localOptions.silent) {
  81. added.forEach((cell, i) => {
  82. const args = {
  83. cell,
  84. index: localIndex + i,
  85. options: localOptions,
  86. };
  87. this.trigger('added', args);
  88. if (!localOptions.dryrun) {
  89. cell.notify('added', Object.assign({}, args));
  90. }
  91. });
  92. if (sort) {
  93. this.trigger('sorted');
  94. }
  95. if (added.length || merged.length) {
  96. this.trigger('updated', {
  97. added,
  98. merged,
  99. removed: [],
  100. options: localOptions,
  101. });
  102. }
  103. }
  104. return this;
  105. }
  106. remove(cells, options = {}) {
  107. const arr = Array.isArray(cells) ? cells : [cells];
  108. const removed = this.removeCells(arr, options);
  109. if (!options.silent && removed.length > 0) {
  110. this.trigger('updated', {
  111. options,
  112. removed,
  113. added: [],
  114. merged: [],
  115. });
  116. }
  117. return Array.isArray(cells) ? removed : removed[0];
  118. }
  119. removeCells(cells, options) {
  120. const removed = [];
  121. for (let i = 0; i < cells.length; i += 1) {
  122. const cell = this.get(cells[i]);
  123. if (cell == null) {
  124. continue;
  125. }
  126. const index = this.cells.indexOf(cell);
  127. this.cells.splice(index, 1);
  128. this.length -= 1;
  129. delete this.map[cell.id];
  130. removed.push(cell);
  131. this.unreference(cell);
  132. if (!options.dryrun) {
  133. cell.remove();
  134. }
  135. if (!options.silent) {
  136. this.trigger('removed', { cell, index, options });
  137. if (!options.dryrun) {
  138. cell.notify('removed', { cell, index, options });
  139. }
  140. }
  141. }
  142. return removed;
  143. }
  144. reset(cells, options = {}) {
  145. const previous = this.cells.slice();
  146. previous.forEach((cell) => this.unreference(cell));
  147. this.clean();
  148. this.add(cells, Object.assign({ silent: true }, options));
  149. if (!options.silent) {
  150. const current = this.cells.slice();
  151. this.trigger('reseted', {
  152. options,
  153. previous,
  154. current,
  155. });
  156. const added = [];
  157. const removed = [];
  158. current.forEach((a) => {
  159. const exist = previous.some((b) => b.id === a.id);
  160. if (!exist) {
  161. added.push(a);
  162. }
  163. });
  164. previous.forEach((a) => {
  165. const exist = current.some((b) => b.id === a.id);
  166. if (!exist) {
  167. removed.push(a);
  168. }
  169. });
  170. this.trigger('updated', { options, added, removed, merged: [] });
  171. }
  172. return this;
  173. }
  174. push(cell, options) {
  175. return this.add(cell, this.length, options);
  176. }
  177. pop(options) {
  178. const cell = this.at(this.length - 1);
  179. return this.remove(cell, options);
  180. }
  181. unshift(cell, options) {
  182. return this.add(cell, 0, options);
  183. }
  184. shift(options) {
  185. const cell = this.at(0);
  186. return this.remove(cell, options);
  187. }
  188. get(cell) {
  189. if (cell == null) {
  190. return null;
  191. }
  192. const id = typeof cell === 'string' || typeof cell === 'number' ? cell : cell.id;
  193. return this.map[id] || null;
  194. }
  195. has(cell) {
  196. return this.get(cell) != null;
  197. }
  198. at(index) {
  199. if (index < 0) {
  200. index += this.length; // eslint-disable-line
  201. }
  202. return this.cells[index] || null;
  203. }
  204. first() {
  205. return this.at(0);
  206. }
  207. last() {
  208. return this.at(-1);
  209. }
  210. indexOf(cell) {
  211. return this.cells.indexOf(cell);
  212. }
  213. toArray() {
  214. return this.cells.slice();
  215. }
  216. sort(options = {}) {
  217. if (this.comparator != null) {
  218. this.cells = ArrayExt.sortBy(this.cells, this.comparator);
  219. if (!options.silent) {
  220. this.trigger('sorted');
  221. }
  222. }
  223. return this;
  224. }
  225. clone() {
  226. const constructor = this.constructor;
  227. return new constructor(this.cells.slice(), {
  228. comparator: this.comparator,
  229. });
  230. }
  231. reference(cell) {
  232. this.map[cell.id] = cell;
  233. cell.on('*', this.notifyCellEvent, this);
  234. }
  235. unreference(cell) {
  236. cell.off('*', this.notifyCellEvent, this);
  237. delete this.map[cell.id];
  238. }
  239. notifyCellEvent(name, args) {
  240. const cell = args.cell;
  241. this.trigger(`cell:${name}`, args);
  242. if (cell) {
  243. if (cell.isNode()) {
  244. this.trigger(`node:${name}`, Object.assign(Object.assign({}, args), { node: cell }));
  245. }
  246. else if (cell.isEdge()) {
  247. this.trigger(`edge:${name}`, Object.assign(Object.assign({}, args), { edge: cell }));
  248. }
  249. }
  250. }
  251. clean() {
  252. this.length = 0;
  253. this.cells = [];
  254. this.map = {};
  255. }
  256. dispose() {
  257. this.reset([]);
  258. }
  259. }
  260. __decorate([
  261. Collection.dispose()
  262. ], Collection.prototype, "dispose", null);
  263. //# sourceMappingURL=collection.js.map