UNPKG

@progress/kendo-angular-gantt

Version:
92 lines (91 loc) 4.79 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Directive, ElementRef, Input, NgZone, Renderer2 } from '@angular/core'; import { Subscription } from 'rxjs'; import { map, switchMap, take } from 'rxjs/operators'; import { MappingService } from '../common/mapping.service'; import { DependencyDomService } from './dependency-dom.service'; import { isPresent } from '../utils'; import { dependencyCoordinates, getElementRect } from './utils'; import { isDocumentAvailable } from '@progress/kendo-angular-common'; import * as i0 from "@angular/core"; import * as i1 from "../common/mapping.service"; import * as i2 from "./dependency-dom.service"; /** * Defines the size of the arrow that will be drawn at the end of each Gantt dependency. */ const ARROW_SIZE = 4; /** * Defines the distance the polyline will cover from the task element before making a turn. */ const MIN_DISTANCE_BEFORE_TURN = 10; /** * @hidden */ export class GanttDependencyDirective { polyline; zone; renderer; mapper; dependencyDomService; dependency; subscriptions = new Subscription(); constructor(polyline, zone, renderer, mapper, dependencyDomService) { this.polyline = polyline; this.zone = zone; this.renderer = renderer; this.mapper = mapper; this.dependencyDomService = dependencyDomService; this.subscriptions.add(dependencyDomService.taskChanges .pipe(switchMap(changes => // reacts only on the very last event emission, // ensures that the tasks are drawn in the DOM this.zone.onStable.pipe(take(1), map(() => changes)))) .subscribe(changes => this.updatePoints(changes))); } ngOnDestroy() { this.subscriptions.unsubscribe(); } ngOnChanges(changes) { if (isPresent(changes['dependency'])) { this.updatePoints(this.dependencyDomService.dependencyDomArgs); } } updatePoints({ timelineRow, contentContainer, tasks }) { if (!isPresent(timelineRow) || !isPresent(contentContainer) || !isPresent(tasks) || tasks.size === 0 || !tasks.has(this.mapper.extractFromDependency(this.dependency, 'fromId')) || !tasks.has(this.mapper.extractFromDependency(this.dependency, 'toId'))) { this.clearPoints(); return; } const fromCoordinates = getElementRect(tasks.get(this.mapper.extractFromDependency(this.dependency, 'fromId')), contentContainer); const toCoordinates = getElementRect(tasks.get(this.mapper.extractFromDependency(this.dependency, 'toId')), contentContainer); const timelineRowHeight = isDocumentAvailable() ? timelineRow.getBoundingClientRect().height : 0; const points = dependencyCoordinates(fromCoordinates, toCoordinates, timelineRowHeight, this.dependency.type, MIN_DISTANCE_BEFORE_TURN, ARROW_SIZE); this.drawPoints(points); } clearPoints() { this.renderer.setAttribute(this.polyline.nativeElement, 'points', ''); } drawPoints(points) { if (!isPresent(points) || points.length === 0) { this.clearPoints(); return; } const parsedCoords = points.map(({ left, top }) => `${left},${top}`).join(' '); this.renderer.setAttribute(this.polyline.nativeElement, 'points', parsedCoords); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GanttDependencyDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i1.MappingService }, { token: i2.DependencyDomService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: GanttDependencyDirective, isStandalone: true, selector: "[kendoGanttDependency]", inputs: { dependency: "dependency" }, usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GanttDependencyDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoGanttDependency]', standalone: true }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.MappingService }, { type: i2.DependencyDomService }], propDecorators: { dependency: [{ type: Input }] } });