@progress/kendo-angular-gantt
Version:
Kendo UI Angular Gantt
92 lines (91 loc) • 4.79 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* 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
}] } });