UNPKG

ngx-diagrams

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.

2,103 lines (2,087 loc) 130 kB
import { EventEmitter, Component, ChangeDetectionStrategy, Renderer2, ChangeDetectorRef, Input, Output, ViewChild, ViewContainerRef, ElementRef, NgModule, Injectable, ComponentFactoryResolver, RendererFactory2, ɵɵdefineInjectable, ɵɵinject } from '@angular/core'; import { Subject, BehaviorSubject, ReplaySubject, combineLatest } from 'rxjs'; import { tap, takeUntil, map, filter, mapTo, distinctUntilChanged, take, delay } from 'rxjs/operators'; import { flatMap, uniq, some } from 'lodash'; import { CommonModule } from '@angular/common'; import { graphlib, layout } from 'dagre'; /** * @fileoverview added by tsickle * Generated from: lib/utils/tool-kit.util.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @enum {number} */ const LOG_LEVEL = { 'LOG': 0, 'ERROR': 1, }; LOG_LEVEL[LOG_LEVEL['LOG']] = 'LOG'; LOG_LEVEL[LOG_LEVEL['ERROR']] = 'ERROR'; // @internal /** @type {?} */ let __DEV__ = true; // @internal /** @type {?} */ let __LOG__ = LOG_LEVEL.ERROR; /** * @return {?} */ function enableDiagramProdMode() { __DEV__ = false; } // @internal /** * @param {?} level * @return {?} */ function setLogLevel(level) { __LOG__ = level; } // @internal /** * @return {?} */ function isDev() { return __DEV__; } // @internal /** * @param {?} message * @param {?=} level * @param {...?} args * @return {?} */ function log(message, level = LOG_LEVEL.LOG, ...args) { if (isDev() && __LOG__ === level) { if (__LOG__ === LOG_LEVEL.ERROR) { console.error(message, ...args); } console.log(message, ...args); } } /** * rxjs log operator * \@internal * @param {?} message * @param {?=} level * @param {...?} args * @return {?} */ function withLog(message, level = LOG_LEVEL.LOG, ...args) { return (/** * @template T * @param {?} source * @return {?} */ (source) => (isDev() ? source.pipe(tap((/** * @param {?} val * @return {?} */ val => log(message, level, val, ...args)))) : source)); } /** * Generates a unique ID * @return {?} */ function UID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (/** * @param {?} c * @return {?} */ c => { /** @type {?} */ const r = (Math.random() * 16) | 0; /** @type {?} */ const v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); })); } /** * @template T * @param {?} val * @return {?} */ function isArray(val) { return Array.isArray(val); } /** * @param {?} val * @return {?} */ function isString(val) { return typeof val === 'string'; } /** * @param {?} val * @return {?} */ function isFunction(val) { return typeof val === 'function'; } // @internal /** * @param {?} v * @return {?} */ function isNil(v) { return v === null || v === undefined; } /** * @template T * @param {?} value * @return {?} */ function coerceArray(value) { if (isNil(value)) { return []; } return Array.isArray(value) ? value : [value]; } /** * @template T * @param {?} map * @return {?} */ function mapToArray(map) { /** @type {?} */ const result = []; for (const key in map) { if (!isNil(map[key])) { result.push(map[key]); } } return result; } /** * @template T * @param {?} arr * @return {?} */ function arrayToMap(arr) { /** @type {?} */ const result = {}; for (const val of arr) { if (!isNil(val)) { result[val.id] = val; } } return result; } /** * @param {?} firstPoint * @param {?} lastPoint * @return {?} */ function generateLinePath(firstPoint, lastPoint) { return `M${firstPoint.x$},${firstPoint.y} L ${lastPoint.x$},${lastPoint.y}`; } /** * @param {?} firstPoint * @param {?} lastPoint * @param {?=} curvy * @return {?} */ function generateCurvePath(firstPoint, lastPoint, curvy = 0) { /** @type {?} */ const isHorizontal = Math.abs(firstPoint.x - lastPoint.x) > Math.abs(firstPoint.y - lastPoint.y); /** @type {?} */ const curvyX = isHorizontal ? curvy : 0; /** @type {?} */ const curvyY = isHorizontal ? 0 : curvy; return `M${firstPoint.x},${firstPoint.y} C ${firstPoint.x + curvyX},${firstPoint.y + curvyY} ${lastPoint.x - curvyX},${lastPoint.y - curvyY} ${lastPoint.x},${lastPoint.y}`; } /** * @fileoverview added by tsickle * Generated from: lib/interfaces/event.interface.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // region events /** * @template T */ class BaseEvent { /** * @param {?} entity */ constructor(entity) { this.id = UID(); this.entity = entity; this.entityId = entity.id; this.firing = true; this.stopPropagation = (/** * @return {?} */ () => (this.firing = false)); } } if (false) { /** @type {?} */ BaseEvent.prototype.entity; /** @type {?} */ BaseEvent.prototype.entityId; /** @type {?} */ BaseEvent.prototype.stopPropagation; /** @type {?} */ BaseEvent.prototype.firing; /** @type {?} */ BaseEvent.prototype.id; } /** * @template T */ class LockEvent extends BaseEvent { /** * @param {?} entity * @param {?=} locked */ constructor(entity, locked = false) { super(entity); this.locked = locked; } } if (false) { /** @type {?} */ LockEvent.prototype.locked; } /** * @template P, T */ class ParentChangeEvent extends BaseEvent { /** * @param {?} entity * @param {?} parent */ constructor(entity, parent) { super(entity); this.parent = parent; } } if (false) { /** @type {?} */ ParentChangeEvent.prototype.parent; } /** * @template T */ class SelectionEvent extends BaseEvent { /** * @param {?} entity * @param {?} selected */ constructor(entity, selected) { super(entity); this.isSelected = selected; } } if (false) { /** @type {?} */ SelectionEvent.prototype.isSelected; } /** * @template T */ class PaintedEvent extends BaseEvent { /** * @param {?} entity * @param {?=} painted */ constructor(entity, painted = false) { super(entity); this.isPainted = painted; } } if (false) { /** @type {?} */ PaintedEvent.prototype.isPainted; } /** * @record */ function DestroyOptions() { } if (false) { /** @type {?|undefined} */ DestroyOptions.prototype.propagate; /** @type {?|undefined} */ DestroyOptions.prototype.emit; } /** * @fileoverview added by tsickle * Generated from: lib/base.entity.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class BaseEntity { /** * @param {?=} id * @param {?=} logPrefix */ constructor(id, logPrefix = '') { this._destroyed = new Subject(); this._destroyed$ = this._destroyed.asObservable(); this._locked = new BehaviorSubject(false); this._locked$ = this._locked.asObservable(); this._id = id || UID(); this._logPrefix = `${logPrefix}`; } /** * @return {?} */ get id() { return this._id; } /** * @param {?} id * @return {?} */ set id(id) { this._id = id; } /** * @param {?} message * @param {...?} args * @return {?} */ log(message, ...args) { log(`${this._logPrefix} ${message}: `, LOG_LEVEL.LOG, ...args); } /** * @param {?} message * @param {...?} args * @return {?} */ withLog(message, ...args) { return withLog(`${this._logPrefix} ${message}: `, LOG_LEVEL.LOG, ...args); } /** * @return {?} */ getLocked() { return this._locked.getValue(); } /** * @param {?=} locked * @return {?} */ setLocked(locked = true) { this._locked.next(locked); } // tslint:disable-next-line /** * @param {?=} lookupTable * @param {?=} clone * @return {?} */ doClone(lookupTable = {}, clone) { /*noop*/ } /** * @param {?=} lookupTable * @return {?} */ clone(lookupTable = {}) { // try and use an existing clone first if (lookupTable[this.id]) { return lookupTable[this.id]; } /** @type {?} */ const clone = Object.assign({}, this); clone.id = UID(); // clone.clearListeners(); lookupTable[this.id] = clone; this.doClone(lookupTable, clone); return clone; } /** * @return {?} */ lockChanges() { return this._locked$.pipe(takeUntil(this.onEntityDestroy()), map((/** * @param {?} locked * @return {?} */ locked => new LockEvent(this, locked))), this.withLog('lockChanges')); } /** * @param {?=} options * @return {?} */ destroy(options) { /** @type {?} */ const defaultOptions = Object.assign({ emit: true, propagate: true }, options); this.log('entity destroyed'); this._destroyed.next(defaultOptions); this._destroyed.complete(); } /** * @return {?} */ onEntityDestroy() { return this._destroyed$.pipe(filter((/** * @param {?} opts * @return {?} */ opts => opts.emit)), mapTo(new BaseEvent(this))); } } if (false) { /** * @type {?} * @private */ BaseEntity.prototype._id; /** * a prefix to make logs more easier * @type {?} * @private */ BaseEntity.prototype._logPrefix; /** * @type {?} * @private */ BaseEntity.prototype._destroyed; /** * @type {?} * @private */ BaseEntity.prototype._destroyed$; /** * @type {?} * @private */ BaseEntity.prototype._locked; /** * @type {?} * @private */ BaseEntity.prototype._locked$; } /** * @fileoverview added by tsickle * Generated from: lib/models/base.model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @template X */ class BaseModel extends BaseEntity { /** * @param {?=} type * @param {?=} id * @param {?=} logPrefix */ constructor(type, id, logPrefix = '[Base]') { super(id, logPrefix); this._parent = new BehaviorSubject(null); this._parent$ = this._parent.asObservable(); this._selected = new BehaviorSubject(false); this._selected$ = this._selected.asObservable(); this._painted = new BehaviorSubject(false); this._painted$ = this._painted.asObservable(); this._type = type; } /** * @return {?} */ getParent() { return this._parent.getValue(); } /** * @param {?} parent * @return {?} */ setParent(parent) { this._parent.next(parent); } /** * @return {?} */ parentChanges() { return this._parent$.pipe(takeUntil(this.onEntityDestroy()), map((/** * @param {?} p * @return {?} */ p => new ParentChangeEvent(this, p)))); } /** * @return {?} */ getPainted() { return this._painted.getValue(); } /** * @param {?=} painted * @return {?} */ setPainted(painted = true) { this._painted.next(painted); } /** * @return {?} */ paintChanges() { return this._painted$.pipe(takeUntil(this.onEntityDestroy()), map((/** * @param {?} p * @return {?} */ p => new PaintedEvent(this, p)))); } /** * @return {?} */ getType() { return this._type; } /** * @return {?} */ getSelected() { return this._selected.getValue(); } /** * @return {?} */ selectSelected() { return this._selected.asObservable(); } /** * @param {?=} selected * @return {?} */ setSelected(selected = true) { this._selected.next(selected); } /** * @return {?} */ selectionChanges() { return this._selected$.pipe(takeUntil(this.onEntityDestroy()), map((/** * @param {?} s * @return {?} */ s => new SelectionEvent(this, s))), this.withLog('selectionChanges')); } /** * @return {?} */ getSelectedEntities() { return this._selected.value ? [this] : []; } } if (false) { /** * @type {?} * @private */ BaseModel.prototype._type; /** * @type {?} * @private */ BaseModel.prototype._parent; /** * @type {?} * @private */ BaseModel.prototype._parent$; /** * @type {?} * @private */ BaseModel.prototype._selected; /** * @type {?} * @private */ BaseModel.prototype._selected$; /** * @type {?} * @private */ BaseModel.prototype._painted; /** * @type {?} * @private */ BaseModel.prototype._painted$; } /** * @fileoverview added by tsickle * Generated from: lib/models/node.model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @template P */ class NodeModel extends BaseModel { /** * @param {?=} nodeType * @param {?=} id * @param {?=} extras * @param {?=} x * @param {?=} y * @param {?=} width * @param {?=} height * @param {?=} logPrefix */ constructor(nodeType = 'default', id, extras = {}, x = 0, y = 0, width = 0, height = 0, logPrefix = '[Node]') { super(nodeType, id, logPrefix); this._extras = new BehaviorSubject(extras); this._ports = new BehaviorSubject({}); this._dimensions = new BehaviorSubject({ width, height }); this._coords = new BehaviorSubject({ x, y }); this.extras$ = this._extras.asObservable(); this.ports$ = this._ports.asObservable(); this.coords$ = this._coords.asObservable(); this.dimensions$ = this._dimensions.asObservable(); } /** * @return {?} */ getCoords() { return this._coords.getValue(); } /** * @param {?} __0 * @return {?} */ setCoords({ x, y }) { const { x: oldX, y: oldY } = this.getCoords(); Object.values(this._ports.getValue()).forEach((/** * @param {?} port * @return {?} */ port => { Object.values(port.getLinks()).forEach((/** * @param {?} link * @return {?} */ link => { /** @type {?} */ const point = link.getPointForPort(port); const { x: pointX, y: pointY } = point.getCoords(); point.setCoords({ x: pointX + x - oldX, y: pointY + y - oldY }); })); })); this._coords.next({ x, y }); } // TODO: implement better transition on auto arrange! /** * @param {?} __0 * @return {?} */ transitionToCoords({ x, y }) { // const transitionCompleted = new ReplaySubject(1); // let { x: oldX, y: oldY } = this.getCoords(); // console.log(x, y, oldX, oldY); // interval(0) // .pipe(takeUntil(transitionCompleted)) // .subscribe( // () => { // if (oldX < x) { // oldX++; // } else if (oldX > x) { // oldX--; // } // if (y > oldY) { // oldY++; // } else if (y < oldY) { // oldY--; // } // Object.values(this._ports.getValue()).forEach(port => { // Object.values(port.getLinks()).forEach(link => { // const point = link.getPointForPort(port); // const { x: pointX, y: pointY } = point.getCoords(); // point.setCoords({ x: pointX + x - oldX, y: pointY + y - oldY }); // }); // }); // this._coords.next({ x: oldX, y: oldY }); // if (x === oldX && y === oldY) { // transitionCompleted.next(true); // transitionCompleted.complete(); // } // }, // err => { // console.error(err); // }, // () => { // console.log('finished transition'); // } // ); } // TODO: override selectionChanges and replace this with it (convert to rx) /** * @return {?} */ getSelectedEntities() { /** @type {?} */ let entities = super.getSelectedEntities(); // add the points of each link that are selected here if (this.getSelected()) { Object.values(this._ports.getValue()).forEach((/** * @param {?} port * @return {?} */ port => { /** @type {?} */ const links = Object.values(port.getLinks()); entities = entities.concat(links.map((/** * @param {?} link * @return {?} */ link => { return link.getPointForPort(port); }))); })); } this.log('selectedEntities', entities); return entities; } // TODO: map to BaseEvent /** * @return {?} */ coordsChanges() { return this.coords$.pipe(takeUntil(this.onEntityDestroy())); } /** * @return {?} */ selectCoords() { return this.coords$.pipe(takeUntil(this.onEntityDestroy()), distinctUntilChanged()); } /** * @return {?} */ selectX() { return this.selectCoords().pipe(map((/** * @param {?} c * @return {?} */ c => c.x)), this.withLog('selectX'), distinctUntilChanged()); } /** * @return {?} */ selectY() { return this.selectCoords().pipe(map((/** * @param {?} c * @return {?} */ c => c.y)), this.withLog('selectY'), distinctUntilChanged()); } /** * Assign a port to the node and set the node as its getParent * @param {?} port * @return {?} the inserted port */ addPort(port) { port.setParent(this); this._ports.next(Object.assign({}, this._ports.value, { [port.id]: port })); return port; } /** * @param {?} id * @return {?} */ getPort(id) { return this._ports.value[id]; } /** * @param {?=} selector * @return {?} */ selectPorts(selector) { // TODO: implement selector // TODO: create coerce func return this.ports$.pipe(takeUntil(this.onEntityDestroy()), distinctUntilChanged(), map((/** * @param {?} ports * @return {?} */ ports => mapToArray(ports))), this.withLog('selectPorts')); } /** * @param {?=} ids * @return {?} */ getPorts(ids) { return this._ports.getValue(); } /** * @param {?} __0 * @return {?} */ setDimensions({ width, height }) { this._dimensions.next({ width, height }); } /** * @return {?} */ getDimensions() { return this._dimensions.getValue(); } // TODO: return BaseEvent extension /** * @return {?} */ dimensionChanges() { return this.dimensions$.pipe(takeUntil(this.onEntityDestroy()), distinctUntilChanged(), this.withLog('DimensionChanges')); } /** * @return {?} */ getHeight() { return this._dimensions.getValue().height; } /** * @return {?} */ getWidth() { return this._dimensions.getValue().width; } /** * @return {?} */ selectWidth() { return this.dimensions$.pipe(takeUntil(this.onEntityDestroy()), map((/** * @param {?} d * @return {?} */ d => d.width)), distinctUntilChanged(), this.withLog('selectWidth')); } /** * @return {?} */ selectHeight() { return this.dimensions$.pipe(takeUntil(this.onEntityDestroy()), map((/** * @param {?} d * @return {?} */ d => d.width)), distinctUntilChanged(), this.withLog('selectHeight')); } /** * @param {?} extras * @return {?} */ setExtras(extras) { this._extras.next(extras); } /** * @return {?} */ getExtras() { return this._extras.getValue(); } /** * @template E * @param {?=} selector * @return {?} */ selectExtras(selector) { // TODO: impl selector return this.extras$.pipe(takeUntil(this.onEntityDestroy()), distinctUntilChanged()); } } if (false) { /** @type {?} */ NodeModel.prototype.id; /** @type {?} */ NodeModel.prototype.diagramEngine; /** * @type {?} * @private */ NodeModel.prototype._extras; /** * @type {?} * @private */ NodeModel.prototype._ports; /** * @type {?} * @private */ NodeModel.prototype._coords; /** * @type {?} * @private */ NodeModel.prototype._dimensions; /** * @type {?} * @private */ NodeModel.prototype.extras$; /** * @type {?} * @private */ NodeModel.prototype.ports$; /** * @type {?} * @private */ NodeModel.prototype.coords$; /** * @type {?} * @private */ NodeModel.prototype.dimensions$; } /** * @fileoverview added by tsickle * Generated from: lib/models/point.model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class PointModel extends BaseModel { /** * @param {?} link * @param {?} __1 */ constructor(link, { x, y }) { super(); this._coords = new BehaviorSubject({ x, y }); this.coords$ = this._coords.asObservable(); this.setParent(link); } /** * @return {?} */ isConnectedToPort() { return this.getParent().getPortForPoint(this) !== null; } /** * @return {?} */ getLink() { return this.getParent(); } /** * @param {?=} options * @return {?} */ destroy(options) { if (this.getParent) { this.getParent().removePoint(this); } super.destroy(options); } /** * @param {?} newCoords * @return {?} */ setCoords(newCoords) { this._coords.next(Object.assign({}, this._coords.getValue(), newCoords)); } /** * @return {?} */ selectCoords() { return this.coords$.pipe(takeUntil(this.onEntityDestroy()), distinctUntilChanged()); } /** * @return {?} */ getCoords() { return this._coords.getValue(); } /** * @return {?} */ selectX() { return this.selectCoords().pipe(map((/** * @param {?} c * @return {?} */ c => c.x)), distinctUntilChanged()); } /** * @return {?} */ selectY() { return this.selectCoords().pipe(map((/** * @param {?} c * @return {?} */ c => c.y)), distinctUntilChanged()); } } if (false) { /** * @type {?} * @private */ PointModel.prototype._coords; /** * @type {?} * @private */ PointModel.prototype.coords$; } /** * @fileoverview added by tsickle * Generated from: lib/models/link.model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class LinkModel extends BaseModel { /** * @param {?=} linkType * @param {?=} id */ constructor(linkType = 'default', id) { super(linkType, id); this.label = new BehaviorSubject(null); this.points = [new PointModel(this, { x: 0, y: 0 }), new PointModel(this, { x: 0, y: 0 })]; this.extras = {}; this.sourcePort = null; this.targetPort = null; } /** * @param {?} name * @return {?} */ setName(name) { this.name = name; } /** * @return {?} */ getName() { return this.name; } /** * @return {?} */ getExtras() { return this.extras; } /** * @param {?} extras * @return {?} */ setExtras(extras) { this.extras = extras; } /** * @param {?=} options * @return {?} */ destroy(options) { if (this.sourcePort) { this.sourcePort.removeLink(this); } if (this.targetPort) { this.targetPort.removeLink(this); } super.destroy(options); } /** * @param {?=} lookupTable * @param {?=} clone * @return {?} */ doClone(lookupTable = {}, clone) { clone.setPoints(this.getPoints().map((/** * @param {?} point * @return {?} */ (point) => { return point.clone(lookupTable); }))); if (this.sourcePort) { clone.setSourcePort(this.sourcePort.clone(lookupTable)); } if (this.targetPort) { clone.setTargetPort(this.targetPort.clone(lookupTable)); } } /** * @param {?} point * @return {?} */ isLastPoint(point) { /** @type {?} */ const index = this.getPointIndex(point); return index === this.points.length - 1; } /** * @param {?} point * @return {?} */ getPointIndex(point) { return this.points.indexOf(point); } /** * @param {?} id * @return {?} */ getPointModel(id) { for (const point of this.points) { if (point.id === id) { return point; } } return null; } /** * @param {?} point * @return {?} */ getPortForPoint(point) { if (this.sourcePort !== null && this.getFirstPoint().id === point.id) { return this.sourcePort; } if (this.targetPort !== null && this.getLastPoint().id === point.id) { return this.targetPort; } return null; } /** * @param {?} port * @return {?} */ getPointForPort(port) { if (this.sourcePort !== null && this.sourcePort.id === port.id) { return this.getFirstPoint(); } if (this.targetPort !== null && this.targetPort.id === port.id) { return this.getLastPoint(); } return null; } /** * @return {?} */ getFirstPoint() { return this.points[0]; } /** * @return {?} */ getLastPoint() { return this.points[this.points.length - 1]; } /** * @param {?} port * @return {?} */ setSourcePort(port) { if (port !== null) { port.addLink(this); } if (this.sourcePort !== null) { this.sourcePort.removeLink(this); } this.sourcePort = port; } /** * @return {?} */ getSourcePort() { return this.sourcePort; } /** * @return {?} */ getTargetPort() { return this.targetPort; } /** * @param {?} port * @return {?} */ setTargetPort(port) { if (port !== null) { port.addLink(this); } if (this.targetPort !== null) { this.targetPort.removeLink(this); } this.targetPort = port; } /** * @param {?} __0 * @return {?} */ point({ x, y }) { return this.addPoint(this.generatePoint({ x, y })); } /** * @return {?} */ getPoints() { return this.points; } /** * @param {?} points * @return {?} */ setPoints(points) { points.forEach((/** * @param {?} point * @return {?} */ point => { point.setParent(this); })); this.points = points; } /** * @param {?} label * @return {?} */ setLabel(label) { label.setParent(this); this.label.next(label); label.setPainted(); } /** * @return {?} */ selectLabel() { return this.label.asObservable(); } /** * @return {?} */ getLabel() { return this.label.getValue(); } /** * @return {?} */ resetLabel() { /** @type {?} */ const currentLabel = this.label.getValue(); if (currentLabel) { currentLabel.setParent(null); currentLabel.setPainted(false); } this.label.next(null); } /** * @param {?} pointModel * @return {?} */ removePoint(pointModel) { this.points.splice(this.getPointIndex(pointModel), 1); } /** * @param {?} pointModel * @return {?} */ removePointsBefore(pointModel) { this.points.splice(0, this.getPointIndex(pointModel)); } /** * @param {?} pointModel * @return {?} */ removePointsAfter(pointModel) { this.points.splice(this.getPointIndex(pointModel) + 1); } /** * @return {?} */ removeMiddlePoints() { if (this.points.length > 2) { this.points.splice(0, this.points.length - 2); } } /** * @template P * @param {?} pointModel * @param {?=} index * @return {?} */ addPoint(pointModel, index = 1) { pointModel.setParent(this); this.points.splice(index, 0, pointModel); return pointModel; } /** * @param {?} __0 * @return {?} */ generatePoint({ x = 0, y = 0 }) { return new PointModel(this, { x, y }); } } if (false) { /** @type {?} */ LinkModel.prototype.diagramEngine; /** * @type {?} * @private */ LinkModel.prototype.name; /** * @type {?} * @private */ LinkModel.prototype.sourcePort; /** * @type {?} * @private */ LinkModel.prototype.targetPort; /** * @type {?} * @private */ LinkModel.prototype.points; /** * @type {?} * @private */ LinkModel.prototype.extras; /** * @type {?} * @private */ LinkModel.prototype.label; } /** * @fileoverview added by tsickle * Generated from: lib/models/port.model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class PortModel extends BaseModel { /** * @param {?} name * @param {?=} type * @param {?=} id * @param {?=} maximumLinks * @param {?=} linkType */ constructor(name, type, id, maximumLinks, linkType) { super(type, id); this.name = name; this.links$ = new BehaviorSubject({}); this.maximumLinks = maximumLinks; this.x$ = new BehaviorSubject(0); this.y$ = new BehaviorSubject(0); this.height$ = new BehaviorSubject(0); this.width$ = new BehaviorSubject(0); this.linkType = linkType; } /** * @return {?} */ getNode() { return this.getParent(); } /** * @return {?} */ getName() { return this.name; } /** * @return {?} */ selectX() { return this.x$.asObservable(); } /** * @return {?} */ selectY() { return this.y$.asObservable(); } /** * @return {?} */ getY() { return this.y$.getValue(); } /** * @return {?} */ getX() { return this.x$.getValue(); } /** * @return {?} */ getHeight() { return this.height$.getValue(); } /** * @return {?} */ getWidth() { return this.width$.getValue(); } /** * @return {?} */ getMaximumLinks() { return this.maximumLinks; } /** * @param {?} maximumLinks * @return {?} */ setMaximumLinks(maximumLinks) { this.maximumLinks = maximumLinks; } /** * @return {?} */ getLinkType() { return this.linkType; } /** * @param {?} type * @return {?} */ setLinkType(type) { this.linkType = type; } /** * @param {?} link * @return {?} */ removeLink(link) { /** @type {?} */ const links = this.links$.getValue(); delete links[link.id]; this.links$.next(Object.assign({}, links)); } /** * @param {?} link * @return {?} */ addLink(link) { this.links$.next(Object.assign({}, this.links$.value, { [link.id]: link })); } /** * @return {?} */ getLinks() { return this.links$.getValue(); } /** * @return {?} */ selectLinks() { return this.links$.asObservable(); } /** * @param {?} __0 * @return {?} */ updateCoords({ x, y, width, height }) { this.x$.next(x); this.y$.next(y); this.width$.next(width); this.height$.next(height); } /** * @param {?} port * @return {?} */ canLinkToPort(port) { return true; } /** * @return {?} */ isLocked() { return super.getLocked(); } /** * @return {?} */ createLinkModel() { /** @type {?} */ const numberOfLinks = Object.keys(this.links$.getValue()).length; if (this.maximumLinks === 1 && numberOfLinks >= 1) { /** @type {?} */ const linkToRemove = Object.values(this.links$.getValue())[0]; linkToRemove.destroy(); return null; } else if (numberOfLinks >= this.maximumLinks) { // for the moment we will remove the first link by default /** @type {?} */ const linkToRemove = Object.values(this.links$.getValue())[0]; linkToRemove.destroy(); return null; } return null; } } if (false) { /** * @type {?} * @private */ PortModel.prototype.name; /** * @type {?} * @private */ PortModel.prototype.links$; /** * @type {?} * @private */ PortModel.prototype.maximumLinks; /** * @type {?} * @private */ PortModel.prototype.linkType; /** * @type {?} * @private */ PortModel.prototype.x$; /** * @type {?} * @private */ PortModel.prototype.y$; /** * @type {?} * @private */ PortModel.prototype.width$; /** * @type {?} * @private */ PortModel.prototype.height$; } /** * @fileoverview added by tsickle * Generated from: lib/models/diagram.model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class DiagramModel extends BaseEntity { /** * @param {?} diagramEngine * @param {?=} id */ constructor(diagramEngine, id) { super(id); this.diagramEngine = diagramEngine; this.nodes$ = new BehaviorSubject({}); this.links$ = new BehaviorSubject({}); this.zoom$ = new BehaviorSubject(100); this.offsetX$ = new BehaviorSubject(0); this.offsetY$ = new BehaviorSubject(0); this.gridSize$ = new BehaviorSubject(0); } // TODO: support the following events for links and nodes // removed, updated<positionChanged/dataChanged>, added /** * @return {?} */ getNodes() { return this.nodes$.getValue(); } /** * @param {?} id * @return {?} */ getNode(id) { return this.nodes$.getValue()[id]; } /** * @param {?} id * @return {?} */ getLink(id) { return this.links$.getValue()[id]; } /** * @return {?} */ getLinks() { return this.links$.getValue(); } /** * Add a node to the diagram * @param {?} node * @return {?} Inserted Node */ addNode(node) { this.nodes$.next(Object.assign({}, this.nodes$.value, { [node.id]: node })); return node; } /** * Delete a node from the diagram * @param {?} nodeOrId * @return {?} */ deleteNode(nodeOrId) { /** @type {?} */ const nodeID = typeof nodeOrId === 'string' ? nodeOrId : nodeOrId.id; // TODO: delete all related links /** @type {?} */ const updNodes = Object.assign({}, this.nodes$.value); delete updNodes[nodeID]; this.nodes$.next(updNodes); } /** * Get nodes behaviour subject, use `.getValue()` for snapshot * @return {?} */ selectNodes() { return this.nodes$.asObservable(); } /** * Add link * @param {?} link * @return {?} Newly created link */ addLink(link) { this.links$.next(Object.assign({}, this.links$.value, { [link.id]: link })); return link; } /** * Delete link * @param {?} linkOrId * @return {?} */ deleteLink(linkOrId) { /** @type {?} */ const linkID = typeof linkOrId === 'string' ? linkOrId : linkOrId.id; /** @type {?} */ const updLinks = Object.assign({}, this.links$.value); delete updLinks[linkID]; this.links$.next(updLinks); } /** * Get links behaviour subject, use `.getValue()` for snapshot * @return {?} */ selectLinks() { return this.links$.asObservable(); } /** * Serialize the diagram model * @returns diagram model as a string */ // serialize(): string { // return JSON.stringify(this.model); // } /** * Load into the diagram model a serialized diagram * @param {?} x * @param {?} y * @return {?} */ // deserialize(serializedModel: string) { // this.model = JSON.parse(serializedModel); // } setOffset(x, y) { this.offsetX$.next(x); this.offsetY$.next(y); } /** * @param {?} x * @return {?} */ setOffsetX(x) { this.offsetX$.next(x); } /** * @return {?} */ getOffsetX() { return this.offsetX$.getValue(); } /** * @return {?} */ selectOffsetX() { return this.offsetX$.asObservable(); } /** * @param {?} y * @return {?} */ setOffsetY(y) { this.offsetY$.next(y); } /** * @return {?} */ getOffsetY() { return this.offsetY$.getValue(); } /** * @return {?} */ selectOffsetY() { return this.offsetY$.asObservable(); } /** * @param {?} z * @return {?} */ setZoomLevel(z) { this.zoom$.next(z); } /** * @return {?} */ getZoomLevel() { return this.zoom$.getValue(); } /** * @return {?} */ selectZoomLevel() { return this.zoom$.asObservable(); } /** * @return {?} */ getDiagramEngine() { return this.diagramEngine; } /** * @param {?=} ignore * @return {?} */ clearSelection(ignore = null) { this.getSelectedItems().forEach((/** * @param {?} element * @return {?} */ element => { if (ignore && ignore.id === element.id) { return; } element.setSelected(false); })); } /** * @param {?} __0 * @return {?} */ getGridPosition({ x, y }) { /** @type {?} */ const gridSize = this.gridSize$.getValue(); if (gridSize === 0) { return { x, y }; } return { x: gridSize * Math.floor((x + gridSize / 2) / gridSize), y: gridSize * Math.floor((y + gridSize / 2) / gridSize) }; } /** * @param {...?} filters * @return {?} */ getSelectedItems(...filters) { if (!Array.isArray(filters)) { filters = [filters]; } /** @type {?} */ let items = []; // run through nodes items = items.concat(flatMap(this.nodes$.getValue(), (/** * @param {?} node * @return {?} */ node => { return node.getSelectedEntities(); }))); // find all the links items = items.concat(flatMap(this.links$.getValue(), (/** * @param {?} link * @return {?} */ link => { return link.getSelectedEntities(); }))); // find all points items = items.concat(flatMap(this.links$.getValue(), (/** * @param {?} link * @return {?} */ link => { return flatMap(link.getPoints(), (/** * @param {?} point * @return {?} */ point => { return point.getSelectedEntities(); })); }))); items = uniq(items); if (filters.length > 0) { items = uniq(items).filter((/** * @param {?} item * @return {?} */ (item) => { if (filters.includes('node') && item instanceof NodeModel) { return true; } if (filters.includes('link') && item instanceof LinkModel) { return true; } if (filters.includes('port') && item instanceof PortModel) { return true; } if (filters.includes('point') && item instanceof PointModel) { return true; } return false; })); } return items; } /** * @param {...?} models * @return {?} */ addAll(...models) { models.forEach((/** * @param {?} model * @return {?} */ model => { if (model instanceof LinkModel) { this.addLink(model); } else if (model instanceof NodeModel) { this.addNode(model); } })); return models; } } if (false) { /** @type {?} */ DiagramModel.prototype.links$; /** @type {?} */ DiagramModel.prototype.nodes$; /** @type {?} */ DiagramModel.prototype.zoom$; /** @type {?} */ DiagramModel.prototype.offsetX$; /** @type {?} */ DiagramModel.prototype.offsetY$; /** @type {?} */ DiagramModel.prototype.gridSize$; /** * @type {?} * @private */ DiagramModel.prototype.diagramEngine; } /** * @fileoverview added by tsickle * Generated from: lib/actions/base.action.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class BaseAction { /** * @param {?} mouseX * @param {?} mouseY */ constructor(mouseX, mouseY) { this.mouseX = mouseX; this.mouseY = mouseY; this.ms = new Date().getTime(); } } if (false) { /** @type {?} */ BaseAction.prototype.mouseX; /** @type {?} */ BaseAction.prototype.mouseY; /** @type {?} */ BaseAction.prototype.ms; } /** * @fileoverview added by tsickle * Generated from: lib/actions/move-canvas.action.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MoveCanvasAction extends BaseAction { /** * @param {?} mouseX * @param {?} mouseY * @param {?} diagramModel */ constructor(mouseX, mouseY, diagramModel) { super(mouseX, mouseY); this.initialOffsetX = diagramModel.getOffsetX(); this.initialOffsetY = diagramModel.getOffsetY(); } } if (false) { /** @type {?} */ MoveCanvasAction.prototype.initialOffsetX; /** @type {?} */ MoveCanvasAction.prototype.initialOffsetY; } /** * @fileoverview added by tsickle * Generated from: lib/actions/selecting.action.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class SelectingAction extends BaseAction { /** * @param {?} mouseX * @param {?} mouseY */ constructor(mouseX, mouseY) { super(mouseX, mouseY); this.mouseX2 = mouseX; this.mouseY2 = mouseY; } /** * @return {?} */ getBoxDimensions() { this.dimensions = { left: this.mouseX2 > this.mouseX ? this.mouseX : this.mouseX2, top: this.mouseY2 > this.mouseY ? this.mouseY : this.mouseY2, width: Math.abs(this.mouseX2 - this.mouseX), height: Math.abs(this.mouseY2 - this.mouseY), right: this.mouseX2 < this.mouseX ? this.mouseX : this.mouseX2, bottom: this.mouseY2 < this.mouseY ? this.mouseY : this.mouseY2 }; return this.dimensions; } /** * @param {?} __0 * @param {?} diagramModel * @return {?} */ containsElement({ x, y }, diagramModel) { /** @type {?} */ const z = diagramModel.getZoomLevel() / 100.0; /** @type {?} */ const dimensions = this.getBoxDimensions(); return (x * z + diagramModel.getOffsetX() > dimensions.left && x * z + diagramModel.getOffsetX() < dimensions.right && y * z + diagramModel.getOffsetY() > dimensions.top && y * z + diagramModel.getOffsetY() < dimensions.bottom); } } if (false) { /** @type {?} */ SelectingAction.prototype.mouseX2; /** @type {?} */ SelectingAction.prototype.mouseY2; /** @type {?} */ SelectingAction.prototype.dimensions; } /** * @fileoverview added by tsickle * Generated from: lib/actions/move-items.action.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MoveItemsAction extends BaseAction { /** * @param {?} mouseX * @param {?} mouseY * @param {?} diagramEngine */ constructor(mouseX, mouseY, diagramEngine) { super(mouseX, mouseY); this.moved = false; /** @type {?} */ let selectedItems = diagramEngine.getDiagramModel().getSelectedItems(); // dont allow items which are locked to move and links which generate their position based on points. selectedItems = selectedItems.filter((/** * @param {?} item * @return {?} */ item => { return !diagramEngine.isModelLocked(item) && !(item instanceof LinkModel); })); this.selectionModels = selectedItems.map((/** * @param {?} item * @return {?} */ (item) => { const { x: initialX, y: initialY } = item.getCoords(); return { model: item, initialX, initialY }; })); } } if (false) { /** @type {?} */ MoveItemsAction.prototype.selectionModels; /** @type {?} */ MoveItemsAction.prototype.moved; } /** * @fileoverview added by tsickle * Generated from: lib/actions/links-created.action.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // TODO: refactor into entity-created.action, and fire every time a new entity is created! class LinkCreatedAction extends BaseAction { /** * @param {?} mouseX * @param {?} mouseY * @param {?} link */ constructor(mouseX, mouseY, link) { super(mouseX, mouseY); this.sourcePort = link.getSourcePort(); this.targetPort = link.getTargetPort(); this.link = link; } /** * @return {?} */ getOutPortNode() { return this.sourcePort.getParent(); } /** * @return {?} */ getInPortNode() { return this.targetPort.getParent(); } } if (false) { /** @type {?} */ LinkCreatedAction.prototype.sourcePort; /** @type {?} */ LinkCreatedAction.prototype.targetPort; /** @type {?} */ LinkCreatedAction.prototype.link; } /** * @fileoverview added by tsickle * Generated from: lib/actions/index.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * Generated from: lib/containers/diagram/diagram.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgxDiagramComponent { /** * @param {?} renderer * @param {?} cdRef */ constructor(renderer, cdRef) { this.renderer = renderer; this.cdRef = cdRef; this.allowCanvasZoon = true; this.allowCanvasTranslation = true; this.inverseZoom = true; this.allowLooseLinks = true; this.actionStartedFiring = new EventEmitter(); th