UNPKG

ngx-diagrams

Version:

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

143 lines 16.2 kB
/** * @fileoverview added by tsickle * Generated from: lib/defaults/components/default-link/default-link.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ChangeDetectorRef, ViewChild, ViewContainerRef } from '@angular/core'; import { DefaultLinkModel } from '../../models/default-link.model'; import { generateCurvePath } from '../../../utils/tool-kit.util'; import { combineLatest, BehaviorSubject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; export class DefaultLinkComponent extends DefaultLinkModel { /** * @param {?} cdRef */ constructor(cdRef) { super('ngdx-default-link'); this.cdRef = cdRef; this._path$ = new BehaviorSubject(null); this.path$ = this._path$.asObservable(); this.points$ = new BehaviorSubject([]); } /** * @return {?} */ ngAfterViewInit() { /** @type {?} */ const firstPCoords$ = this.getFirstPoint().selectCoords(); /** @type {?} */ const lastPCoords$ = this.getLastPoint().selectCoords(); // Observe link coords and update drawing accordingly combineLatest([firstPCoords$, lastPCoords$]) .pipe(takeUntil(this.onEntityDestroy())) .subscribe((/** * @param {?} __0 * @return {?} */ ([firstPCoords, lastPCoords]) => { /** @type {?} */ const points = [firstPCoords, lastPCoords]; /** @type {?} */ const isHorizontal = Math.abs(firstPCoords.x - lastPCoords.x) > Math.abs(firstPCoords.y - lastPCoords.y); /** @type {?} */ const xOrY = isHorizontal ? 'x' : 'y'; // draw the smoothing // if the points are too close, just draw a straight line /** @type {?} */ let isStraight = false; if (Math.abs(points[0][xOrY] - points[1][xOrY]) < 50) { isStraight = true; } /** @type {?} */ const path = generateCurvePath(firstPCoords, lastPCoords, isStraight ? 0 : this.curvyness); this._path$.next(path); if (!this.getTargetPort()) { /** @type {?} */ const danglingPoint = this.generatePoint(lastPCoords); this.points$.next([danglingPoint]); } /** @type {?} */ const label = this.getLabel(); // update label position if (label) { label.setCoords(this.calcCenterOfPath(firstPCoords, lastPCoords)); // TODO: check whether we want the label to rotate along with the line // label.setRotation(this.calcLabelIncline(firstPCoords, lastPCoords)); } // TODO: handle the multiple lines in between the points // https://github.com/projectstorm/react-diagrams/blob/master/src/defaults/widgets/DefaultLinkWidget.tsx#L344-L371 this.cdRef.detectChanges(); })); // observe link label and draw/remove accordingly this.selectLabel() .pipe(filter(Boolean)) .subscribe((/** * @param {?} label * @return {?} */ (label) => { this.diagramEngine.generateWidgetForLabel(label, this.labelLayer); this.cdRef.detectChanges(); })); } /** * @param {?} firstPoint * @param {?} secondPoint * @return {?} */ calcLabelIncline(firstPoint, secondPoint) { /** @type {?} */ const dy = secondPoint.y - firstPoint.y; /** @type {?} */ const dx = secondPoint.x - firstPoint.x; if (dx === 0) { return 0; } /** @type {?} */ let inclineAngel = (Math.atan(dy / dx) * 180) / Math.PI; if (inclineAngel < 0) { inclineAngel += 180; } return inclineAngel; } /** * @param {?} firstPoint * @param {?} secondPoint * @return {?} */ calcCenterOfPath(firstPoint, secondPoint) { return { x: (firstPoint.x + secondPoint.x) / 2 + 20, y: (firstPoint.y + secondPoint.y) / 2 + 20 }; } } DefaultLinkComponent.decorators = [ { type: Component, args: [{ selector: 'ngdx-default-link', template: "<!-- Label Host -->\n<ng-template #labelLayer></ng-template>\n\n<!-- Link -->\n<svg class=\"default-link\">\n\t<g>\n\t\t<path [attr.stroke-width]=\"width\" [attr.stroke]=\"color\" [attr.d]=\"path$ | async\"></path>\n\t\t<path\n\t\t\t(mouseleave)=\"setSelected(false)\"\n\t\t\t(mouseenter)=\"setSelected()\"\n\t\t\t[attr.stroke-width]=\"20\"\n\t\t\t[attr.stroke]=\"color\"\n\t\t\t[attr.stroke-linecap]=\"'round'\"\n\t\t\t[attr.data-linkid]=\"id\"\n\t\t\t[attr.stroke-opacity]=\"(selectSelected() | async) ? '0.1' : '0'\"\n\t\t\t[attr.d]=\"path$ | async\"\n\t\t></path>\n\t</g>\n\t<g *ngFor=\"let point of points$ | async\">\n\t\t<circle [attr.cx]=\"point.selectX() | async\" [attr.cy]=\"point.selectY() | async\" r=\"5\" class=\"default-point\" />\n\n\t\t<circle\n\t\t\t(mouseleave)=\"setSelected(false)\"\n\t\t\t(mouseenter)=\"setSelected()\"\n\t\t\t[attr.data-id]=\"point.id\"\n\t\t\t[attr.data-linkid]=\"id\"\n\t\t\t[attr.cx]=\"point.selectX() | async\"\n\t\t\t[attr.cy]=\"point.selectY() | async\"\n\t\t\tr=\"15\"\n\t\t\t[attr.opacity]=\"0\"\n\t\t\tclass=\"default-point\"\n\t\t\t[ngClass]=\"{ 'default-point': true, selected: point.selectSelected() | async }\"\n\t\t/>\n\t\t{{ point.selectSelected() | async }}\n\t</g>\n</svg>\n", styles: [".default-link{fill:none;overflow:visible}.default-link .default-point{fill:rgba(255,255,255,.5)}.default-link .default-point.selected{fill:rgba(0,0,255,.5)}@-webkit-keyframes dash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}@keyframes dash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}.default-link path{fill:none;pointer-events:all}.default-link.path-selected{stroke:#00c0ff!important;stroke-dasharray:10,2;-webkit-animation:1s linear infinite dash;animation:1s linear infinite dash}"] }] } ]; /** @nocollapse */ DefaultLinkComponent.ctorParameters = () => [ { type: ChangeDetectorRef } ]; DefaultLinkComponent.propDecorators = { labelLayer: [{ type: ViewChild, args: ['labelLayer', { read: ViewContainerRef, static: true },] }] }; if (false) { /** @type {?} */ DefaultLinkComponent.prototype.labelLayer; /** @type {?} */ DefaultLinkComponent.prototype._path$; /** @type {?} */ DefaultLinkComponent.prototype.path$; /** @type {?} */ DefaultLinkComponent.prototype.points$; /** @type {?} */ DefaultLinkComponent.prototype.label$; /** * @type {?} * @private */ DefaultLinkComponent.prototype.cdRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC1saW5rLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1kaWFncmFtcy8iLCJzb3VyY2VzIjpbImxpYi9kZWZhdWx0cy9jb21wb25lbnRzL2RlZmF1bHQtbGluay9kZWZhdWx0LWxpbmsuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBaUIsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBR2xFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFRbkQsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGdCQUFnQjs7OztJQVF6RCxZQUFvQixLQUF3QjtRQUMzQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQURSLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBTDVDLFdBQU0sR0FBNEIsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUQsVUFBSyxHQUF1QixJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3ZELFlBQU8sR0FBa0MsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7SUFLakUsQ0FBQzs7OztJQUVELGVBQWU7O2NBQ1IsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxZQUFZLEVBQUU7O2NBQ25ELFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsWUFBWSxFQUFFO1FBRXZELHFEQUFxRDtRQUNyRCxhQUFhLENBQUMsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENB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LGdCQUFnQixDQUFDLFVBQWtCLEVBQUUsV0FBbUI7UUFDdkQsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQ25HLENBQUM7OztZQXhGRCxTQUFTLFNBQUM7Z0JBQ1YsUUFBUSxFQUFFLG1CQUFtQjtnQkFDN0IsNHRDQUE0Qzs7YUFFNUM7Ozs7WUFia0MsaUJBQWlCOzs7eUJBZWxELFNBQVMsU0FBQyxZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTs7OztJQUFqRSwwQ0FBZ0c7O0lBRWhHLHNDQUE0RDs7SUFDNUQscUNBQXVEOztJQUN2RCx1Q0FBaUU7O0lBQ2pFLHNDQUErQjs7Ozs7SUFFbkIscUNBQWdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiwgVmlld0NoaWxkLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEZWZhdWx0TGlua01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2RlZmF1bHQtbGluay5tb2RlbCc7XG5pbXBvcnQgeyBnZW5lcmF0ZUN1cnZlUGF0aCB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Rvb2wta2l0LnV0aWwnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCwgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBQb2ludE1vZGVsIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3BvaW50Lm1vZGVsJztcbmltcG9ydCB7IExhYmVsTW9kZWwgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvbGFiZWwubW9kZWwnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDb29yZHMgfSBmcm9tICcuLi8uLi8uLi9pbnRlcmZhY2VzJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnbmdkeC1kZWZhdWx0LWxpbmsnLFxuXHR0ZW1wbGF0ZVVybDogJy4vZGVmYXVsdC1saW5rLmNvbXBvbmVudC5odG1sJyxcblx0c3R5bGVVcmxzOiBbJy4vZGVmYXVsdC1saW5rLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRGVmYXVsdExpbmtDb21wb25lbnQgZXh0ZW5kcyBEZWZhdWx0TGlua01vZGVsIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cdEBWaWV3Q2hpbGQoJ2xhYmVsTGF5ZXInLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KSBsYWJlbExheWVyOiBWaWV3Q29udGFpbmVyUmVmO1xuXG5cdF9wYXRoJDogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KG51bGwpO1xuXHRwYXRoJDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5fcGF0aCQuYXNPYnNlcnZhYmxlKCk7XG5cdHBvaW50cyQ6IEJlaGF2aW9yU3ViamVjdDxQb2ludE1vZGVsW10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChbXSk7XG5cdGxhYmVsJDogT2JzZXJ2YWJsZTxMYWJlbE1vZGVsPjtcblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuXHRcdHN1cGVyKCduZ2R4LWRlZmF1bHQtbGluaycpO1xuXHR9XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdGNvbnN0IGZpcnN0UENvb3JkcyQgPSB0aGlzLmdldEZpcnN0UG9pbnQoKS5zZWxlY3RDb29yZHMoKTtcblx0XHRjb25zdCBsYXN0UENvb3JkcyQgPSB0aGlzLmdldExhc3RQb2ludCgpLnNlbGVjdENvb3JkcygpO1xuXG5cdFx0Ly8gT2JzZXJ2ZSBsaW5rIGNvb3JkcyBhbmQgdXBkYXRlIGRyYXdpbmcgYWNjb3JkaW5nbHlcblx0XHRjb21iaW5lTGF0ZXN0KFtmaXJzdFBDb29yZHMkLCBsYXN0UENvb3JkcyRdKVxuXHRcdFx0LnBpcGUodGFrZVVudGlsKHRoaXMub25FbnRpdHlEZXN0cm95KCkpKVxuXHRcdFx0LnN1YnNjcmliZSgoW2ZpcnN0UENvb3JkcywgbGFzdFBDb29yZHNdKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHBvaW50cyA9IFtmaXJzdFBDb29yZHMsIGxhc3RQQ29vcmRzXTtcblxuXHRcdFx0XHRjb25zdCBpc0hvcml6b250YWwgPSBNYXRoLmFicyhmaXJzdFBDb29yZHMueCAtIGxhc3RQQ29vcmRzLngpID4gTWF0aC5hYnMoZmlyc3RQQ29vcmRzLnkgLSBsYXN0UENvb3Jkcy55KTtcblx0XHRcdFx0Y29uc3QgeE9yWSA9IGlzSG9yaXpvbnRhbCA/ICd4JyA6ICd5JztcblxuXHRcdFx0XHQvLyBkcmF3IHRoZSBzbW9vdGhpbmdcblx0XHRcdFx0Ly8gaWYgdGhlIHBvaW50cyBhcmUgdG9vIGNsb3NlLCBqdXN0IGRyYXcgYSBzdHJhaWdodCBsaW5lXG5cdFx0XHRcdGxldCBpc1N0cmFpZ2h0ID0gZmFsc2U7XG5cdFx0XHRcdGlmIChNYXRoLmFicyhwb2ludHNbMF1beE9yWV0gLSBwb2ludHNbMV1beE9yWV0pIDwgNTApIHtcblx0XHRcdFx0XHRpc1N0cmFpZ2h0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IHBhdGggPSBnZW5lcmF0ZUN1cnZlUGF0aChmaXJzdFBDb29yZHMsIGxhc3RQQ29vcmRzLCBpc1N0cmFpZ2h0ID8gMCA6IHRoaXMuY3VydnluZXNzKTtcblx0XHRcdFx0dGhpcy5fcGF0aCQubmV4dChwYXRoKTtcblxuXHRcdFx0XHRpZiAoIXRoaXMuZ2V0VGFyZ2V0UG9ydCgpKSB7XG5cdFx0XHRcdFx0Y29uc3QgZGFuZ2xpbmdQb2ludCA9IHRoaXMuZ2VuZXJhdGVQb2ludChsYXN0UENvb3Jkcyk7XG5cdFx0XHRcdFx0dGhpcy5wb2ludHMkLm5leHQoW2RhbmdsaW5nUG9pbnRdKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IGxhYmVsID0gdGhpcy5nZXRMYWJlbCgpO1xuXHRcdFx0XHQvLyB1cGRhdGUgbGFiZWwgcG9zaXRpb25cblx0XHRcdFx0aWYgKGxhYmVsKSB7XG5cdFx0XHRcdFx0bGFiZWwuc2V0Q29vcmRzKHRoaXMuY2FsY0NlbnRlck9mUGF0aChmaXJzdFBDb29yZHMsIGxhc3RQQ29vcmRzKSk7XG5cblx0XHRcdFx0XHQvLyBUT0RPOiBjaGVjayB3aGV0aGVyIHdlIHdhbnQgdGhlIGxhYmVsIHRvIHJvdGF0ZSBhbG9uZyB3aXRoIHRoZSBsaW5lXG5cdFx0XHRcdFx0Ly8gbGFiZWwuc2V0Um90YXRpb24odGhpcy5jYWxjTGFiZWxJbmNsaW5lKGZpcnN0UENvb3JkcywgbGFzdFBDb29yZHMpKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRPRE86IGhhbmRsZSB0aGUgbXVsdGlwbGUgbGluZXMgaW4gYmV0d2VlbiB0aGUgcG9pbnRzXG5cdFx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm9qZWN0c3Rvcm0vcmVhY3QtZGlhZ3JhbXMvYmxvYi9tYXN0ZXIvc3JjL2RlZmF1bHRzL3dpZGdldHMvRGVmYXVsdExpbmtXaWRnZXQudHN4I0wzNDQtTDM3MVxuXG5cdFx0XHRcdHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXHRcdFx0fSk7XG5cblx0XHQvLyBvYnNlcnZlIGxpbmsgbGFiZWwgYW5kIGRyYXcvcmVtb3ZlIGFjY29yZGluZ2x5XG5cdFx0dGhpcy5zZWxlY3RMYWJlbCgpXG5cdFx0XHQucGlwZShmaWx0ZXIoQm9vbGVhbikpXG5cdFx0XHQuc3Vic2NyaWJlKChsYWJlbDogTGFiZWxNb2RlbCkgPT4ge1xuXHRcdFx0XHR0aGlzLmRpYWdyYW1FbmdpbmUuZ2VuZXJhdGVXaWRnZXRGb3JMYWJlbChsYWJlbCwgdGhpcy5sYWJlbExheWVyKTtcblx0XHRcdFx0dGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cdFx0XHR9KTtcblx0fVxuXG5cdGNhbGNMYWJlbEluY2xpbmUoZmlyc3RQb2ludDogQ29vcmRzLCBzZWNvbmRQb2ludDogQ29vcmRzKTogbnVtYmVyIHtcblx0XHRjb25zdCBkeSA9IHNlY29uZFBvaW50LnkgLSBmaXJzdFBvaW50Lnk7XG5cdFx0Y29uc3QgZHggPSBzZWNvbmRQb2ludC54IC0gZmlyc3RQb2ludC54O1xuXG5cdFx0aWYgKGR4ID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHRsZXQgaW5jbGluZUFuZ2VsID0gKE1hdGguYXRhbihkeSAvIGR4KSAqIDE4MCkgLyBNYXRoLlBJO1xuXG5cdFx0aWYgKGluY2xpbmVBbmdlbCA8IDApIHtcblx0XHRcdGluY2xpbmVBbmdlbCArPSAxODA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGluY2xpbmVBbmdlbDtcblx0fVxuXG5cdGNhbGNDZW50ZXJPZlBhdGgoZmlyc3RQb2ludDogQ29vcmRzLCBzZWNvbmRQb2ludDogQ29vcmRzKTogQ29vcmRzIHtcblx0XHRyZXR1cm4geyB4OiAoZmlyc3RQb2ludC54ICsgc2Vjb25kUG9pbnQueCkgLyAyICsgMjAsIHk6IChmaXJzdFBvaW50LnkgKyBzZWNvbmRQb2ludC55KSAvIDIgKyAyMCB9O1xuXHR9XG59XG4iXX0=