ng-devui
Version:
DevUI components based on Angular
1 lines • 153 kB
Source Map (JSON)
{"version":3,"file":"ng-devui-gantt.mjs","sources":["../../devui/gantt/gantt.model.ts","../../devui/gantt/gantt.service.ts","../../devui/gantt/gantt-bar-parent/gantt-bar-parent.component.ts","../../devui/gantt/gantt-bar-parent/gantt-bar-parent.component.html","../../devui/gantt/gantt-bar/gantt-bar.component.ts","../../devui/gantt/gantt-bar/gantt-bar.component.html","../../devui/gantt/gantt-marker.directive.ts","../../devui/gantt/gantt-milestone/gantt-milestone.component.ts","../../devui/gantt/gantt-milestone/gantt-milestone.component.html","../../devui/gantt/gantt-scale/gantt-scale.component.ts","../../devui/gantt/gantt-scale/gantt-scale.component.html","../../devui/gantt/gantt-tools/gantt-tools.component.ts","../../devui/gantt/gantt-tools/gantt-tools.component.html","../../devui/gantt/resize-handle.directive.ts","../../devui/gantt/gantt.module.ts","../../devui/gantt/ng-devui-gantt.ts"],"sourcesContent":["export interface GanttScaleDateInfo {\n dayOfMonthLabel: string;\n dayOfWeekLabel: string;\n monthLabel: string;\n yearLabel: string;\n date: Date;\n monthStart?: boolean;\n weekend?: boolean;\n today?: boolean;\n highlight?: boolean;\n highlightStart?: boolean;\n milestone?: string;\n scaleStartVisable?: boolean;\n index?: number;\n}\n\nexport enum GanttScaleUnit {\n day = 'day',\n week = 'week',\n month = 'month',\n}\nexport interface GanttBarStatus {\n focused: boolean;\n startDate: Date;\n endDate: Date;\n}\n\nexport interface GanttScaleConfig {\n startDate?: Date;\n endDate?: Date;\n unit?: GanttScaleUnit;\n viewChange?: boolean;\n}\n\nexport enum GanttMarkerType {\n milestone = 'milestone',\n month = 'month',\n week = 'week',\n}\n\nexport interface GanttMilestone {\n date: Date;\n lable: string;\n}\n\nexport interface GanttTaskInfo {\n id: string;\n startDate: Date;\n endDate: Date;\n title?: string;\n progress: string;\n duration: string;\n moveOffset?: number;\n left?: number;\n width?: number;\n}\n\nexport enum UnitRole {\n day = 10,\n week = 20,\n month = 30,\n}\n\nexport type GanttRailStatus = 'normal' | 'overdue' | 'done';\n","import { Injectable } from '@angular/core';\nimport { fromEvent, merge, Observable, ReplaySubject, Subject } from 'rxjs';\nimport { pluck } from 'rxjs/operators';\nimport { GanttBarStatus, GanttScaleConfig, GanttScaleUnit } from './gantt.model';\n\n@Injectable()\nexport class GanttService {\n static DAY_DURATION = 24 * 60 * 60 * 1000;\n scaleUnit = GanttScaleUnit.day;\n scaleStartDate: Date;\n scaleEndDate: Date;\n ganttBarStatusChange = new Subject<GanttBarStatus>();\n ganttScaleConfigChange = new ReplaySubject<GanttScaleConfig>(1);\n\n mouseDownListener: Observable<number>;\n mouseMoveListener = new Observable();\n mouseEndListener = new Observable();\n\n constructor() {}\n changeGanttBarStatus(status: GanttBarStatus) {\n this.ganttBarStatusChange.next(status);\n }\n\n registContainerEvents(scrollContainer: HTMLElement) {\n // 背景拖拽\n this.mouseDownListener = fromEvent(scrollContainer, 'mousedown').pipe(pluck<MouseEvent, 'pageX'>('pageX'));\n\n this.mouseMoveListener = fromEvent(scrollContainer, 'mousemove').pipe(pluck<MouseEvent, 'pageX'>('pageX'));\n\n this.mouseEndListener = merge(fromEvent(scrollContainer, 'mouseup'), fromEvent(scrollContainer, 'mouseout')).pipe(\n pluck<MouseEvent, 'pageX'>('pageX')\n );\n }\n\n changeGanttScaleConfig(status: GanttScaleConfig) {\n this.ganttScaleConfigChange.next(status);\n }\n\n setScaleConfig(config: GanttScaleConfig) {\n if (config.startDate) {\n this.scaleStartDate = config.startDate;\n }\n if (config.endDate) {\n this.scaleEndDate = config.endDate;\n }\n if (config.unit) {\n this.scaleUnit = config.unit;\n }\n this.changeGanttScaleConfig(config);\n }\n\n getScaleUnitPixel() {\n switch (this.scaleUnit) {\n case GanttScaleUnit.day:\n return 40;\n break;\n case GanttScaleUnit.week:\n return 30;\n break;\n case GanttScaleUnit.month:\n return 20;\n break;\n default:\n break;\n }\n }\n\n getDatePostionOffset(date: Date): number {\n if (date && this.scaleStartDate) {\n const timeOffset = date.getTime() - this.scaleStartDate.getTime();\n const units = timeOffset / GanttService.DAY_DURATION;\n return units * this.getScaleUnitPixel();\n }\n }\n\n getDuration(startDate: Date, endDate: Date): number {\n if (startDate && endDate) {\n const timeOffset = endDate.getTime() - startDate.getTime();\n const duration = timeOffset / GanttService.DAY_DURATION + 1;\n return Math.round(duration);\n }\n }\n\n getDurationWidth(startDate: Date, endDate: Date): number {\n if (startDate && endDate) {\n const duration = this.getDuration(startDate, endDate);\n return duration * this.getScaleUnitPixel();\n }\n }\n\n isSomeDate(date: Date, compareDate: Date) {\n if (date.getFullYear() !== compareDate.getFullYear()) {\n return false;\n }\n\n if (date.getMonth() !== compareDate.getMonth()) {\n return false;\n }\n\n if (date.getDate() !== compareDate.getDate()) {\n return false;\n }\n return true;\n }\n\n roundDate(date: Date) {\n if (date.getHours() >= 12) {\n date.setDate(date.getDate() + 1);\n date.setHours(0, 0, 0);\n } else if (date.getHours() < 12) {\n date.setHours(0, 0, 0);\n }\n }\n\n unRegistContainerEvents() {}\n}\n","import {\r\n AfterViewInit,\r\n ChangeDetectorRef,\r\n Component,\r\n ElementRef,\r\n Input,\r\n OnChanges,\r\n OnDestroy,\r\n OnInit,\r\n SimpleChanges,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { GanttService } from '../gantt.service';\r\n\r\n@Component({\r\n selector: 'd-gantt-bar-parent',\r\n templateUrl: './gantt-bar-parent.component.html',\r\n styleUrls: ['./gantt-bar-parent.component.scss'],\r\n})\r\nexport class GanttBarParentComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {\r\n @ViewChild('ganttBarProgress') ganttBarProgress: ElementRef;\r\n @ViewChild('ganttBarTrack') ganttBarTrack: ElementRef;\r\n @ViewChild('ganttBarRail') ganttBarRail: ElementRef;\r\n @Input() startDate: Date;\r\n @Input() endDate: Date;\r\n @Input() progressRate = 0;\r\n @Input() data: any;\r\n @Input() id: string;\r\n @Input() tip: string;\r\n\r\n private ganttScaleStatusHandler: Subscription;\r\n public tipHovered = false;\r\n percentage: number;\r\n left = 0;\r\n width = 0;\r\n private max = 100;\r\n private min = 0;\r\n public duration: string;\r\n\r\n constructor(private cdr: ChangeDetectorRef, private ganttService: GanttService) {}\r\n\r\n ngOnInit() {\r\n if (this.progressRate === null) {\r\n this.setValue(this.ensureValueInRange(null));\r\n }\r\n this.duration = this.ganttService.getDuration(this.startDate, this.endDate) + 'd';\r\n\r\n this.ganttScaleStatusHandler = this.ganttService.ganttScaleConfigChange.subscribe((config) => {\r\n if (config.startDate) {\r\n this.left = this.ganttService.getDatePostionOffset(this.startDate);\r\n }\r\n if (config.unit) {\r\n this.left = this.ganttService.getDatePostionOffset(this.startDate);\r\n this.width = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n }\r\n });\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n const { progressRate, startDate, endDate } = changes;\r\n if (progressRate && this.progressRate > 0) {\r\n this.updateTrackAndHandle();\r\n }\r\n\r\n if (startDate) {\r\n this.left = this.ganttService.getDatePostionOffset(this.startDate);\r\n this.width = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n }\r\n\r\n if (endDate) {\r\n this.width = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n }\r\n }\r\n\r\n ngAfterViewInit() {\r\n if (this.progressRate && this.progressRate > 0) {\r\n this.updateTrackAndHandle();\r\n }\r\n }\r\n\r\n private setValue(value: number | null): void {\r\n if (this.progressRate !== value) {\r\n this.progressRate = value;\r\n this.updateTrackAndHandle();\r\n }\r\n }\r\n\r\n private ensureValueInRange(value: number | null): number {\r\n let safeValue;\r\n if (!this.valueMustBeValid(value)) {\r\n safeValue = this.min;\r\n } else {\r\n safeValue = this.clamp(this.min, value as number, this.max);\r\n }\r\n return safeValue;\r\n }\r\n\r\n private valueMustBeValid(value: number): boolean {\r\n return !isNaN(typeof value !== 'number' ? parseFloat(value) : value);\r\n }\r\n\r\n private clamp(min: number, n: number, max: number) {\r\n return Math.max(min, Math.min(n, max));\r\n }\r\n\r\n private updateTrackAndHandle(): void {\r\n const value = this.progressRate;\r\n const offset = this.valueToOffset(value);\r\n this.updateStyle(offset / 100);\r\n this.cdr.markForCheck();\r\n }\r\n\r\n private valueToOffset(value: number): number {\r\n return ((value - this.min) / (this.max - this.min)) * 100;\r\n }\r\n\r\n private updateStyle(percentage) {\r\n this.percentage = Math.min(1, Math.max(0, percentage));\r\n if (this.ganttBarTrack && this.ganttBarTrack.nativeElement) {\r\n this.ganttBarTrack.nativeElement.style.width = `${this.percentage * 100}%`;\r\n }\r\n\r\n if (this.ganttBarProgress && this.ganttBarProgress.nativeElement) {\r\n this.ganttBarProgress.nativeElement.style.left = `${this.percentage * 100}%`;\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.ganttScaleStatusHandler) {\r\n this.ganttScaleStatusHandler.unsubscribe();\r\n this.ganttScaleStatusHandler = null;\r\n }\r\n }\r\n}\r\n","<div\n *ngIf=\"startDate && endDate\"\n #ganttBar\n class=\"devui-gantt-bar-parent\"\n [style.left]=\"left + 'px'\"\n [style.width]=\"width + 'px'\"\n dTooltip\n [content]=\"tip\"\n>\n <div class=\"devui-gantt-bar-rail\" #ganttBarRail></div>\n <div class=\"devui-gantt-bar-track\" [ngClass]=\"{ head: percentage > 0, tail: percentage === 1 }\" #ganttBarTrack></div>\n</div>\n","import {\r\n AfterViewInit,\r\n ChangeDetectorRef,\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n Input,\r\n OnChanges,\r\n OnDestroy,\r\n OnInit,\r\n Output,\r\n SimpleChanges,\r\n TemplateRef,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport { Observable, Subscription, fromEvent } from 'rxjs';\r\nimport { distinctUntilChanged, map, pluck, takeUntil, tap } from 'rxjs/operators';\r\nimport { GanttRailStatus, GanttTaskInfo } from '../gantt.model';\r\nimport { GanttService } from '../gantt.service';\r\n\r\n@Component({\r\n selector: 'd-gantt-bar',\r\n templateUrl: './gantt-bar.component.html',\r\n styleUrls: ['./gantt-bar.component.scss'],\r\n})\r\nexport class GanttBarComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {\r\n private moveBarStartListener: Observable<number>;\r\n private resizeBarLeftStartListener: Observable<number>;\r\n private resizeBarRightStartListener: Observable<number>;\r\n private dragProgressStartListener: Observable<number>;\r\n private mouseMoveListener: Observable<number>;\r\n private mouseEndListener: Observable<Event>;\r\n\r\n private moveBarStartHandler: Subscription | null;\r\n private resizeBarLeftStartHandler: Subscription | null;\r\n private resizeBarRightStartHandler: Subscription | null;\r\n private dragProgressStartHandler: Subscription | null;\r\n private mouseMoveHandler: Subscription | null;\r\n private mouseEndHandler: Subscription | null;\r\n private mouseOverProgressHandler: Subscription | null;\r\n private mouseLeaveProgressHandler: Subscription | null;\r\n mouseMoveTimer: any = null;\r\n mouseLeaveTimer: any = null;\r\n\r\n dragProgressStart: boolean;\r\n moveBarStart: boolean;\r\n private resizeBarLeftStart: boolean;\r\n private resizeBarRightStart: boolean;\r\n\r\n private barMoveStartPageX: number;\r\n private barResizeStartPageX: number;\r\n private barOriginLeft: number;\r\n private barOriginWidth: string;\r\n private originStartDate: Date;\r\n private originEndDate: Date;\r\n\r\n private barHovering = false;\r\n private progressHovering = false;\r\n\r\n private ganttScaleStatusHandler: Subscription;\r\n public focused = false;\r\n private MIN_WIDTH = 10;\r\n left = 0;\r\n width = 0;\r\n private EARLYOFFSET = 3;\r\n\r\n cdkOverlayOffsetX = 0;\r\n\r\n @ViewChild('ganttBar') ganttBar: ElementRef;\r\n @ViewChild('ganttBarMain') ganttBarMain: ElementRef;\r\n @ViewChild('ganttBarProgress') ganttBarProgress: ElementRef;\r\n @ViewChild('ganttBarTrack') ganttBarTrack: ElementRef;\r\n @ViewChild('ganttBarRail') ganttBarRail: ElementRef;\r\n @ViewChild('ganttBarDarggerLeft') ganttBarDarggerLeft: ElementRef;\r\n @ViewChild('ganttBarDarggerRight') ganttBarDarggerRight: ElementRef;\r\n private max = 100;\r\n private min = 0;\r\n private step = 1;\r\n private mouseEventDalay = 100;\r\n\r\n public duration: string;\r\n public tipHovered = false;\r\n public mouseMoveOnBar = false;\r\n percentage: number;\r\n private movedOut = false;\r\n private mouseenterHandler: Subscription;\r\n private mouseleaveHandler: Subscription;\r\n private scrollTimer = null;\r\n private SCROLL_STEP = 10;\r\n private outDirection = 'right';\r\n private scrollViewRange = [0, 0];\r\n\r\n @Input() barMoveDisabled = false;\r\n @Input() barResizeDisabled = false;\r\n @Input() progressDisabled = false;\r\n\r\n @Input() startDate: Date;\r\n @Input() endDate: Date;\r\n @Input() progressRate = 0;\r\n @Input() tipTemplateRef: TemplateRef<any>;\r\n @Input() titleTemplateRef: TemplateRef<any>;\r\n @Input() data: any;\r\n\r\n @Input() originOffsetX = 0;\r\n\r\n @Input() id: string;\r\n\r\n @Input() title: string;\r\n\r\n @Input() showTitle = false;\r\n\r\n @Input() customBarClass = '';\r\n\r\n @Input() customBgClass = '';\r\n\r\n @Input() customTitleClass = '';\r\n\r\n @Input() scrollElement: HTMLElement;\r\n\r\n @Input() status: GanttRailStatus = 'normal';\r\n\r\n @Output() barMoveStartEvent = new EventEmitter<GanttTaskInfo>();\r\n @Output() barMovingEvent = new EventEmitter<GanttTaskInfo>();\r\n @Output() barMoveEndEvent = new EventEmitter<GanttTaskInfo>();\r\n\r\n @Output() barResizeStartEvent = new EventEmitter<GanttTaskInfo>();\r\n @Output() barResizingEvent = new EventEmitter<GanttTaskInfo>();\r\n @Output() barResizeEndEvent = new EventEmitter<GanttTaskInfo>();\r\n\r\n @Output() barProgressEvent = new EventEmitter<number>();\r\n\r\n constructor(private cdr: ChangeDetectorRef, private ganttService: GanttService, private ele: ElementRef) {}\r\n\r\n ngOnInit() {\r\n this.checkRangeValues(this.min, this.max);\r\n this.checkStepValue();\r\n if (this.progressRate === null) {\r\n this.setValue(this.ensureValueInRange(null));\r\n }\r\n this.originStartDate = this.startDate;\r\n this.originEndDate = this.endDate;\r\n this.duration = this.ganttService.getDuration(this.startDate, this.endDate) + 'd';\r\n\r\n this.ganttScaleStatusHandler = this.ganttService.ganttScaleConfigChange.subscribe((config) => {\r\n if (config.startDate) {\r\n this.left = this.ganttService.getDatePostionOffset(this.startDate);\r\n }\r\n if (config.unit) {\r\n this.left = this.ganttService.getDatePostionOffset(this.startDate);\r\n this.width = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n }\r\n });\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n const { progressRate, startDate, endDate, barMoveDisabled, barResizeDisabled, progressDisabled } = changes;\r\n if (\r\n Object.prototype.hasOwnProperty.call(changes, 'min') ||\r\n Object.prototype.hasOwnProperty.call(changes, 'max') ||\r\n Object.prototype.hasOwnProperty.call(changes, 'step')\r\n ) {\r\n this.checkRangeValues(this.min, this.max);\r\n this.checkStepValue();\r\n }\r\n\r\n if (progressRate && this.progressRate >= 0) {\r\n this.updateTrackAndHandle();\r\n }\r\n\r\n if (startDate) {\r\n this.left = this.ganttService.getDatePostionOffset(this.startDate);\r\n this.width = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n }\r\n\r\n if (endDate) {\r\n this.width = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n }\r\n\r\n if (barMoveDisabled) {\r\n if (this.barMoveDisabled) {\r\n this.unsubscribeMouseActions(['start'], ['barMove']);\r\n } else {\r\n this.subscribeMouseActions(['start'], ['barMove']);\r\n }\r\n }\r\n\r\n if (barResizeDisabled) {\r\n if (this.barResizeDisabled) {\r\n this.unsubscribeMouseActions(['start'], ['barResize']);\r\n } else {\r\n this.subscribeMouseActions(['start'], ['barResize']);\r\n }\r\n }\r\n\r\n if (progressDisabled) {\r\n if (this.progressDisabled) {\r\n this.unsubscribeMouseActions(['start'], ['progress']);\r\n } else {\r\n this.subscribeMouseActions(['start'], ['progress']);\r\n }\r\n }\r\n }\r\n\r\n ngAfterViewInit() {\r\n if (this.startDate && this.endDate) {\r\n this.registerMouseEventsListeners();\r\n this.registerHandleHoverPopoverListener();\r\n if (!this.barMoveDisabled) {\r\n this.subscribeMouseActions(['start'], ['barMove']);\r\n }\r\n\r\n if (!this.barResizeDisabled) {\r\n this.subscribeMouseActions(['start'], ['barResize']);\r\n }\r\n\r\n if (!this.progressDisabled) {\r\n this.subscribeMouseActions(['start'], ['progress']);\r\n }\r\n }\r\n\r\n if (this.progressRate && this.progressRate > 0) {\r\n this.updateTrackAndHandle();\r\n }\r\n }\r\n\r\n registerOnChange(fn: any): void {\r\n this.onChangeCallback = fn;\r\n }\r\n\r\n registerOnTouched(fn: any): void {\r\n this.onTouchedCallback = fn;\r\n }\r\n\r\n writeValue(newValue: number): void {\r\n this.setValue(this.ensureValueInRange(newValue));\r\n }\r\n\r\n private onTouchedCallback = (v: any) => {};\r\n\r\n private onChangeCallback = (v: any) => {};\r\n\r\n private checkRangeValues(minValue, maxValue) {\r\n if (maxValue <= minValue) {\r\n throw new Error(`max value must be greater than min value`);\r\n }\r\n }\r\n\r\n private checkStepValue() {\r\n if (this.step < 0 || !this.step) {\r\n throw new Error('step value must be greater than 0.');\r\n } else if ((this.max - this.min) % this.step) {\r\n throw new Error('(max - min) must be divisible by step.');\r\n }\r\n }\r\n\r\n private ratioToValue(ratio: number, min: number, max: number, step: number): number {\r\n let value = (max - min) * ratio + min;\r\n if (step > 0) {\r\n value = Math.round(value / step) * step;\r\n }\r\n return this.clamp(min, value, max);\r\n }\r\n\r\n private convertHandlePositionToRatio(handleX: number, startX: number, totalLength: number): number {\r\n return this.clamp(0, (handleX - startX) / totalLength, 1);\r\n }\r\n\r\n private clamp(min: number, n: number, max: number) {\r\n return Math.max(min, Math.min(n, max));\r\n }\r\n\r\n private updateStyle(percentage) {\r\n this.percentage = Math.min(1, Math.max(0, percentage));\r\n if (this.ganttBarTrack && this.ganttBarTrack.nativeElement) {\r\n this.ganttBarTrack.nativeElement.style.width = `${this.percentage * 100}%`;\r\n }\r\n\r\n if (this.ganttBarProgress && this.ganttBarProgress.nativeElement) {\r\n this.ganttBarProgress.nativeElement.style.left = `${this.percentage * 100}%`;\r\n }\r\n }\r\n\r\n private registerMouseEventsListeners(): void {\r\n this.moveBarStartListener = fromEvent(this.ganttBarMain.nativeElement, 'mousedown').pipe(\r\n tap((e: Event) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }),\r\n pluck<MouseEvent, 'pageX'>('pageX')\r\n );\r\n\r\n this.dragProgressStartListener = fromEvent(this.ganttBarProgress.nativeElement, 'mousedown').pipe(\r\n tap((e: Event) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }),\r\n pluck<MouseEvent, 'pageX'>('pageX'),\r\n map((position: number) => this.mousePositionToAdaptiveValue(position))\r\n );\r\n\r\n this.resizeBarLeftStartListener = fromEvent(this.ganttBarDarggerLeft.nativeElement, 'mousedown').pipe(\r\n tap((e: Event) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }),\r\n pluck<MouseEvent, 'pageX'>('pageX')\r\n );\r\n\r\n this.resizeBarRightStartListener = fromEvent(this.ganttBarDarggerRight.nativeElement, 'mousedown').pipe(\r\n tap((e: Event) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }),\r\n pluck<MouseEvent, 'pageX'>('pageX')\r\n );\r\n\r\n this.mouseEndListener = fromEvent(document, 'mouseup');\r\n this.mouseMoveListener = fromEvent(document, 'mousemove').pipe(\r\n tap((e: Event) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }),\r\n pluck<MouseEvent, 'pageX'>('pageX'),\r\n distinctUntilChanged(),\r\n takeUntil(this.mouseEndListener)\r\n );\r\n }\r\n\r\n private getSliderPagePosition(): number {\r\n const rect = this.ganttBar.nativeElement.getBoundingClientRect();\r\n const window = this.ganttBar.nativeElement.ownerDocument.defaultView;\r\n return rect.left + window.pageXOffset;\r\n }\r\n\r\n private getRailLength(): number {\r\n return this.ganttBarRail.nativeElement.clientWidth;\r\n }\r\n\r\n private mousePositionToAdaptiveValue(handleX: number): number {\r\n const sliderStartX = this.getSliderPagePosition();\r\n const sliderLength = this.getRailLength();\r\n const ratio = this.convertHandlePositionToRatio(handleX, sliderStartX, sliderLength);\r\n const value = this.ratioToValue(ratio, this.min, this.max, this.step);\r\n return parseFloat(value.toFixed(this.getDecimals(this.step)));\r\n }\r\n\r\n private getDecimals(value: number): number {\r\n const valueString = value.toString();\r\n const integerLength = valueString.indexOf('.') + 1;\r\n return integerLength >= 0 ? valueString.length - integerLength : 0;\r\n }\r\n\r\n private progressStartDrag(value: number): void {\r\n this.dragProgressStart = true;\r\n this.handleController(true);\r\n this.setValue(value);\r\n }\r\n\r\n private barStartMoving(value: number): void {\r\n this.scrollViewRange = [\r\n this.scrollElement.getBoundingClientRect().left + this.originOffsetX,\r\n this.scrollElement.getBoundingClientRect().right,\r\n ];\r\n this.moveBarStart = true;\r\n this.barMoveStartPageX = value;\r\n this.barOriginLeft = parseInt(this.ganttBar.nativeElement.style.left, 10);\r\n this.handleController(true);\r\n this.barMoveStartEvent.emit(this.getGanttTaskInfo());\r\n }\r\n\r\n private barLeftStartResizing(value: number): void {\r\n this.resizeBarLeftStart = true;\r\n this.barResizeStartPageX = value;\r\n this.barOriginLeft = parseInt(this.ganttBar.nativeElement.style.left, 10);\r\n this.barOriginWidth = this.ganttBar.nativeElement.style.width;\r\n this.handleController(true);\r\n this.barResizeStartEvent.emit(this.getGanttTaskInfo());\r\n }\r\n\r\n private barRightStartResizing(value: number): void {\r\n this.resizeBarRightStart = true;\r\n this.barResizeStartPageX = value;\r\n this.barOriginLeft = parseInt(this.ganttBar.nativeElement.style.left, 10);\r\n this.barOriginWidth = this.ganttBar.nativeElement.style.width;\r\n this.handleController(true);\r\n this.barResizeStartEvent.emit(this.getGanttTaskInfo());\r\n }\r\n\r\n private mouseMoving(value: number): void {\r\n if (this.dragProgressStart) {\r\n this.setValue(this.mousePositionToAdaptiveValue(value));\r\n this.cdr.markForCheck();\r\n }\r\n\r\n if (this.resizeBarLeftStart) {\r\n this.mouseMoveOnBar = true;\r\n const offset = value - this.barResizeStartPageX;\r\n const finalWidth = parseInt(this.barOriginWidth, 10) - Math.round(offset);\r\n\r\n if (finalWidth < this.MIN_WIDTH) {\r\n return;\r\n }\r\n\r\n const timeOffset = Math.round((offset / this.ganttService.getScaleUnitPixel()) * GanttService.DAY_DURATION);\r\n this.startDate = new Date(this.originStartDate.getTime() + timeOffset);\r\n this.ganttService.roundDate(this.startDate);\r\n if (this.endDate < this.startDate) {\r\n this.startDate = this.endDate;\r\n }\r\n\r\n const earlyDateTime = this.startDate.getTime() - this.EARLYOFFSET * GanttService.DAY_DURATION;\r\n if (offset < 0 && earlyDateTime < this.ganttService.scaleStartDate.getTime()) {\r\n this.ganttService.setScaleConfig({ startDate: new Date(earlyDateTime) });\r\n this.barOriginLeft = this.EARLYOFFSET * this.ganttService.getScaleUnitPixel() - Math.round(offset);\r\n }\r\n const finalLeft = this.barOriginLeft + Math.round(offset);\r\n this.left = finalLeft;\r\n\r\n this.width = finalWidth;\r\n this.dispatchGanttBarStatus();\r\n const info = this.getGanttTaskInfo();\r\n info.moveOffset = offset;\r\n this.barResizingEvent.emit(info);\r\n }\r\n\r\n if (this.resizeBarRightStart) {\r\n this.mouseMoveOnBar = true;\r\n const offset = value - this.barResizeStartPageX;\r\n const finalWidth = parseInt(this.barOriginWidth, 10) + Math.round(offset);\r\n\r\n if (finalWidth < this.MIN_WIDTH) {\r\n return;\r\n }\r\n\r\n const timeOffset = Math.round((offset / this.ganttService.getScaleUnitPixel()) * GanttService.DAY_DURATION);\r\n this.endDate = new Date(this.originEndDate.getTime() + timeOffset);\r\n this.ganttService.roundDate(this.endDate);\r\n if (this.endDate < this.startDate) {\r\n this.endDate = this.startDate;\r\n }\r\n\r\n const lateDateTime = this.endDate.getTime() + this.EARLYOFFSET * GanttService.DAY_DURATION;\r\n if (offset > 0 && lateDateTime > this.ganttService.scaleEndDate.getTime()) {\r\n this.ganttService.setScaleConfig({ endDate: new Date(lateDateTime) });\r\n }\r\n\r\n this.width = finalWidth;\r\n this.dispatchGanttBarStatus();\r\n const info = this.getGanttTaskInfo();\r\n info.moveOffset = offset;\r\n this.barResizingEvent.emit(info);\r\n }\r\n\r\n if (this.moveBarStart) {\r\n this.checkIsOut(value);\r\n if (this.movedOut) {\r\n return;\r\n }\r\n this.mouseMoveOnBar = true;\r\n const offset = value - this.barMoveStartPageX;\r\n\r\n const timeOffset = Math.round((Math.round(offset) / this.ganttService.getScaleUnitPixel()) * GanttService.DAY_DURATION);\r\n\r\n const newStartDate = new Date(this.originStartDate.getTime() + timeOffset);\r\n this.ganttService.roundDate(newStartDate);\r\n this.startDate = newStartDate;\r\n\r\n const newEndDate = new Date(this.originEndDate.getTime() + timeOffset);\r\n this.ganttService.roundDate(newEndDate);\r\n this.endDate = newEndDate;\r\n\r\n const earlyDateTime = this.startDate.getTime() - this.EARLYOFFSET * GanttService.DAY_DURATION;\r\n const lateDateTime = this.endDate.getTime() + this.EARLYOFFSET * GanttService.DAY_DURATION;\r\n if (earlyDateTime < this.ganttService.scaleStartDate.getTime()) {\r\n this.ganttService.setScaleConfig({ startDate: new Date(earlyDateTime) });\r\n } else if (lateDateTime > this.ganttService.scaleEndDate.getTime()) {\r\n this.ganttService.setScaleConfig({ endDate: new Date(lateDateTime) });\r\n }\r\n const finalLeft = this.barOriginLeft + Math.round(offset);\r\n this.left = finalLeft;\r\n\r\n this.dispatchGanttBarStatus();\r\n const info = this.getGanttTaskInfo();\r\n info.moveOffset = offset;\r\n this.barMovingEvent.emit(info);\r\n }\r\n }\r\n\r\n private checkIsOut(value) {\r\n this.outDirection = value - this.barMoveStartPageX > 0 ? 'right' : 'left';\r\n if (this.outDirection === 'left') {\r\n this.movedOut = value < this.scrollViewRange[0];\r\n } else {\r\n this.movedOut = value > this.scrollViewRange[1];\r\n }\r\n if (this.movedOut) {\r\n this.autoScroll();\r\n } else if (this.scrollTimer) {\r\n const left =\r\n this.outDirection === 'left'\r\n ? this.scrollElement.scrollLeft + (value - this.scrollElement.getBoundingClientRect().left) - this.originOffsetX\r\n : this.scrollElement.scrollLeft + this.scrollElement.clientWidth - this.originOffsetX;\r\n this.setLeft(Math.round(left));\r\n this.stopAutoScroll();\r\n this.barMoveStartPageX = value;\r\n }\r\n }\r\n\r\n private autoScroll() {\r\n if (!this.scrollTimer) {\r\n this.scrollTimer = setInterval(() => {\r\n this.outDirection === 'left'\r\n ? (this.scrollElement.scrollLeft -= this.SCROLL_STEP)\r\n : (this.scrollElement.scrollLeft += this.SCROLL_STEP);\r\n }, 10);\r\n }\r\n }\r\n\r\n private stopAutoScroll() {\r\n clearInterval(this.scrollTimer);\r\n this.scrollTimer = null;\r\n }\r\n\r\n private setLeft(left) {\r\n const offset = left - this.left;\r\n const timeOffset = (Math.round(offset) / this.ganttService.getScaleUnitPixel()) * GanttService.DAY_DURATION;\r\n\r\n const newStartDate = new Date(this.startDate.getTime() + timeOffset);\r\n this.ganttService.roundDate(newStartDate);\r\n this.startDate = newStartDate;\r\n\r\n const newEndDate = new Date(this.endDate.getTime() + timeOffset);\r\n this.ganttService.roundDate(newEndDate);\r\n this.endDate = newEndDate;\r\n\r\n this.originStartDate = this.startDate;\r\n this.originEndDate = this.endDate;\r\n this.barOriginLeft = left;\r\n this.left = left;\r\n }\r\n\r\n private getGanttTaskInfo(): GanttTaskInfo {\r\n this.duration = this.ganttService.getDuration(this.startDate, this.endDate) + 'd';\r\n const progress = this.progressRate + '%';\r\n const taskInfo = {\r\n id: this.id,\r\n startDate: this.startDate,\r\n endDate: this.endDate,\r\n duration: this.duration,\r\n progress: progress,\r\n left: this.left,\r\n width: this.width,\r\n };\r\n return taskInfo;\r\n }\r\n private mouseStopMoving(): void {\r\n this.mouseMoveOnBar = false;\r\n this.ganttService.roundDate(this.startDate);\r\n this.ganttService.roundDate(this.endDate);\r\n this.originStartDate = this.startDate;\r\n this.originEndDate = this.endDate;\r\n const taskInfo = this.getGanttTaskInfo();\r\n if (this.moveBarStart) {\r\n const finalLeft = this.ganttService.getDatePostionOffset(this.startDate);\r\n this.left = finalLeft > 0 ? finalLeft : 0;\r\n this.barMoveEndEvent.emit(taskInfo);\r\n }\r\n if (this.resizeBarLeftStart) {\r\n const finalLeft = this.ganttService.getDatePostionOffset(this.startDate);\r\n const finalWidth = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n this.left = finalLeft > 0 ? finalLeft : 0;\r\n this.width = finalWidth;\r\n this.barResizeEndEvent.emit(taskInfo);\r\n }\r\n if (this.resizeBarRightStart) {\r\n const finalWidth = this.ganttService.getDurationWidth(this.startDate, this.endDate);\r\n this.width = finalWidth;\r\n this.barResizeEndEvent.emit(taskInfo);\r\n }\r\n if (this.dragProgressStart) {\r\n this.barProgressEvent.emit(this.progressRate);\r\n }\r\n this.handleController(false);\r\n this.stopAutoScroll();\r\n this.cdr.markForCheck();\r\n }\r\n\r\n private subscribeMouseActions(\r\n mouseActions: string[] = ['start', 'move', 'end'],\r\n events: string[] = ['barMove', 'barResize', 'progress']\r\n ): void {\r\n if (\r\n mouseActions.indexOf('start') !== -1 &&\r\n this.dragProgressStartListener &&\r\n !this.dragProgressStartHandler &&\r\n events.indexOf('progress') !== -1\r\n ) {\r\n this.dragProgressStartHandler = this.dragProgressStartListener.subscribe(this.progressStartDrag.bind(this));\r\n }\r\n\r\n if (\r\n mouseActions.indexOf('start') !== -1 &&\r\n this.moveBarStartListener &&\r\n !this.moveBarStartHandler &&\r\n events.indexOf('barMove') !== -1\r\n ) {\r\n this.moveBarStartHandler = this.moveBarStartListener.subscribe(this.barStartMoving.bind(this));\r\n }\r\n\r\n if (\r\n mouseActions.indexOf('start') !== -1 &&\r\n this.resizeBarLeftStartListener &&\r\n !this.resizeBarLeftStartHandler &&\r\n events.indexOf('barResize') !== -1\r\n ) {\r\n this.resizeBarLeftStartHandler = this.resizeBarLeftStartListener.subscribe(this.barLeftStartResizing.bind(this));\r\n }\r\n\r\n if (\r\n mouseActions.indexOf('start') !== -1 &&\r\n this.resizeBarRightStartListener &&\r\n !this.resizeBarRightStartHandler &&\r\n events.indexOf('barResize') !== -1\r\n ) {\r\n this.resizeBarRightStartHandler = this.resizeBarRightStartListener.subscribe(this.barRightStartResizing.bind(this));\r\n }\r\n\r\n if (mouseActions.indexOf('move') !== -1 && this.mouseMoveListener && !this.mouseMoveHandler) {\r\n this.mouseMoveHandler = this.mouseMoveListener.subscribe(this.mouseMoving.bind(this));\r\n }\r\n\r\n if (mouseActions.indexOf('end') !== -1 && this.mouseEndListener && !this.mouseEndHandler) {\r\n this.mouseEndHandler = this.mouseEndListener.subscribe(this.mouseStopMoving.bind(this));\r\n }\r\n }\r\n\r\n private unsubscribeMouseActions(\r\n dragStages: string[] = ['start', 'move', 'end'],\r\n events: string[] = ['barMove', 'barResize', 'progress']\r\n ): void {\r\n if (dragStages.indexOf('start') !== -1 && events.indexOf('progress') !== -1 && this.dragProgressStartHandler) {\r\n this.dragProgressStartHandler.unsubscribe();\r\n this.dragProgressStartHandler = null;\r\n }\r\n\r\n if (dragStages.indexOf('start') !== -1 && events.indexOf('barMove') !== -1 && this.moveBarStartHandler) {\r\n this.moveBarStartHandler.unsubscribe();\r\n this.moveBarStartHandler = null;\r\n }\r\n\r\n if (dragStages.indexOf('start') !== -1 && events.indexOf('barResize') !== -1 && this.resizeBarLeftStartHandler) {\r\n this.resizeBarLeftStartHandler.unsubscribe();\r\n this.resizeBarLeftStartHandler = null;\r\n }\r\n\r\n if (dragStages.indexOf('start') !== -1 && events.indexOf('barResize') !== -1 && this.resizeBarRightStartHandler) {\r\n this.resizeBarRightStartHandler.unsubscribe();\r\n this.resizeBarRightStartHandler = null;\r\n }\r\n\r\n if (dragStages.indexOf('move') !== -1 && this.mouseMoveHandler) {\r\n this.mouseMoveHandler.unsubscribe();\r\n this.mouseMoveHandler = null;\r\n }\r\n\r\n if (dragStages.indexOf('end') !== -1 && this.mouseEndHandler) {\r\n this.mouseEndHandler.unsubscribe();\r\n this.mouseEndHandler = null;\r\n }\r\n }\r\n\r\n private handleController(movable: boolean): void {\r\n if (movable) {\r\n this.focused = this.focusController();\r\n this.subscribeMouseActions(['move', 'end']);\r\n } else {\r\n this.dragProgressStart = false;\r\n this.moveBarStart = false;\r\n this.resizeBarLeftStart = false;\r\n this.resizeBarRightStart = false;\r\n this.focused = this.focusController();\r\n this.unsubscribeMouseActions(['move', 'end']);\r\n }\r\n }\r\n\r\n private setValue(value: number | null): void {\r\n if (this.progressRate !== value) {\r\n this.progressRate = value;\r\n this.updateTrackAndHandle();\r\n }\r\n this.onChangeCallback(this.progressRate);\r\n }\r\n\r\n private ensureValueInRange(value: number | null): number {\r\n let safeValue;\r\n if (!this.valueMustBeValid(value)) {\r\n safeValue = this.min;\r\n } else {\r\n safeValue = this.clamp(this.min, value as number, this.max);\r\n }\r\n return safeValue;\r\n }\r\n\r\n private updateTrackAndHandle(): void {\r\n const value = this.progressRate;\r\n const offset = this.valueToOffset(value);\r\n this.updateStyle(offset / 100);\r\n this.cdr.markForCheck();\r\n }\r\n\r\n private valueMustBeValid(value: number): boolean {\r\n return !isNaN(typeof value !== 'number' ? parseFloat(value) : value);\r\n }\r\n\r\n private valueToOffset(value: number): number {\r\n return ((value - this.min) / (this.max - this.min)) * 100;\r\n }\r\n\r\n private registerHandleHoverPopoverListener() {\r\n const mouseOverProgressListener = fromEvent(this.ganttBarProgress.nativeElement, 'mouseover');\r\n const mouseLeaveProgressListener = fromEvent(this.ganttBarProgress.nativeElement, 'mouseout');\r\n this.mouseOverProgressHandler = mouseOverProgressListener.subscribe(this.ganttProgressPopoverOnMouseHover.bind(this));\r\n this.mouseLeaveProgressHandler = mouseLeaveProgressListener.subscribe(this.ganttProgressPopoverOnMouseLeave.bind(this));\r\n }\r\n\r\n ganttBarPopoverOnMouseHover($event) {\r\n if (this.mouseLeaveTimer) {\r\n clearTimeout(this.mouseLeaveTimer);\r\n }\r\n this.mouseMoveTimer = setTimeout(() => {\r\n const barLeft = this.ganttBar.nativeElement.getClientRects()[0].left;\r\n const eventLeft = $event.clientX;\r\n this.cdkOverlayOffsetX = eventLeft - barLeft;\r\n\r\n this.barHovering = true;\r\n this.focused = this.focusController();\r\n this.dispatchGanttBarStatus();\r\n this.cdr.markForCheck();\r\n }, this.mouseEventDalay);\r\n }\r\n\r\n ganttBarPopoverOnMouseLeave() {\r\n if (this.mouseMoveTimer) {\r\n clearTimeout(this.mouseMoveTimer);\r\n }\r\n this.mouseLeaveTimer = setTimeout(() => {\r\n this.barHovering = false;\r\n this.focused = this.focusController();\r\n this.dispatchGanttBarStatus();\r\n this.cdr.markForCheck();\r\n }, this.mouseEventDalay);\r\n }\r\n\r\n mouseLeaveTip() {\r\n setTimeout(() => {\r\n this.tipHovered = false;\r\n }, this.mouseEventDalay);\r\n }\r\n\r\n private ganttProgressPopoverOnMouseHover() {\r\n this.progressHovering = true;\r\n }\r\n\r\n private ganttProgressPopoverOnMouseLeave() {\r\n this.progressHovering = false;\r\n }\r\n\r\n private unregisterHandleHoverTooltip() {\r\n if (this.mouseOverProgressHandler) {\r\n this.mouseOverProgressHandler.unsubscribe();\r\n this.mouseOverProgressHandler = null;\r\n }\r\n\r\n if (this.mouseLeaveProgressHandler) {\r\n this.mouseLeaveProgressHandler.unsubscribe();\r\n this.mouseLeaveProgressHandler = null;\r\n }\r\n }\r\n\r\n private clearTimer() {\r\n if (this.mouseLeaveTimer) {\r\n clearTimeout(this.mouseLeaveTimer);\r\n }\r\n if (this.mouseMoveTimer) {\r\n clearTimeout(this.mouseMoveTimer);\r\n }\r\n }\r\n\r\n private focusController() {\r\n return this.dragProgressStart || this.moveBarStart || this.resizeBarLeftStart || this.resizeBarRightStart || this.barHovering;\r\n }\r\n\r\n dispatchGanttBarStatus() {\r\n const status = {\r\n focused: this.focused,\r\n startDate: this.startDate,\r\n endDate: this.endDate,\r\n };\r\n this.ganttService.changeGanttBarStatus(status);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.clearTimer();\r\n this.unsubscribeMouseActions();\r\n this.unregisterHandleHoverTooltip();\r\n if (this.ganttScaleStatusHandler) {\r\n this.ganttScaleStatusHandler.unsubscribe();\r\n this.ganttScaleStatusHandler = null;\r\n }\r\n }\r\n}\r\n","<div\n *ngIf=\"startDate && endDate\"\n class=\"devui-gantt-bar {{ customBarClass }}\"\n #ganttBar\n cdk-overlay-origin\n #progress=\"cdkOverlayOrigin\"\n [style.left]=\"left + 'px'\"\n [style.width]=\"width + 'px'\"\n (mouseover)=\"ganttBarPopoverOnMouseHover($event)\"\n (mouseleave)=\"ganttBarPopoverOnMouseLeave()\"\n>\n <div class=\"devui-gantt-hover-layer\" [style.width]=\"width + 24 + 'px'\" [style.display]=\"focused ? 'block' : 'none'\">\n <div #ganttBarDarggerLeft class=\"devui-gantt-dragger left\">\n <div class=\"handle\" [ngClass]=\"{ disabled: barResizeDisabled }\"></div>\n </div>\n <div #ganttBarDarggerRight class=\"devui-gantt-dragger right\">\n <div class=\"handle\" [ngClass]=\"{ disabled: barResizeDisabled }\"></div>\n </div>\n </div>\n <div #ganttBarMain class=\"devui-gantt-main\" [ngClass]=\"{ disabled: barMoveDisabled }\">\n <div class=\"devui-gantt-bar-rail devui-gantt-bar-rail-{{ status }}\" #ganttBarRail></div>\n <div class=\"devui-gantt-bar-track devui-gantt-bar-track-{{ status }}\" #ganttBarTrack></div>\n </div>\n <div\n class=\"devui-gantt-bar-progress\"\n #ganttBarProgress\n [ngClass]=\"{ disabled: progressDisabled, visible: focused }\"\n [attr.title]=\"progressRate ? progressRate : 0 + '%'\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n width=\"12px\"\n height=\"16px\"\n viewBox=\"0 0 12 16\"\n version=\"1.1\"\n >\n <g id=\"gantt-bar-handle\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M7.06066017,1.35355339 C6.76776695,1.06066017 6.38388348,0.914213562 6,0.914213562 C5.61611652,0.914213562 5.23223305,1.06066017 4.93933983,1.35355339 L0.5,5.79289322 L0.5,13 C0.5,13.6903559 0.779822031,14.3153559 1.23223305,14.767767 C1.68464406,15.220178 2.30964406,15.5 3,15.5 L9,15.5 C9.69035594,15.5 10.3153559,15.220178 10.767767,14.767767 C11.220178,14.3153559 11.5,13.6903559 11.5,13 L11.5,5.79289322 L7.06066017,1.35355339 Z\"\n stroke=\"none\"\n fill=\"none\"\n />\n </g>\n </svg>\n </div>\n <div class=\"devui-gantt-bar-title {{ customTitleClass }}\" *ngIf=\"showTitle\">\n <ng-container *ngIf=\"titleTemplateRef\">\n <ng-template [ngTemplateOutlet]=\"titleTemplateRef\" [ngTemplateOutletContext]=\"{ data: data }\"></ng-template>\n </ng-container>\n <ng-container *ngIf=\"!titleTemplateRef\">{{ title }}</ng-container>\n </div>\n <ng-template\n *ngIf=\"tipTemplateRef\"\n cdk-connected-overlay\n [cdkConnectedOverlayOffsetX]=\"cdkOverlayOffsetX\"\n [cdkConnectedOverlayOrigin]=\"progress\"\n [cdkConnectedOverlayOpen]=\"(focused || tipHovered) && !mouseMoveOnBar\"\n >\n <div class=\"devui-gantt-tips\" (mouseover)=\"tipHovered = true\" (mouseleave)=\"mouseLeaveTip()\">\n <ng-template [ngTemplateOutlet]=\"tipTemplateRef\" [ngTemplateOutletContext]=\"{ ganttInstance: this, data: data }\"></ng-template>\n </div>\n </ng-template>\n</div>\n\n<div\n *ngIf=\"moveBarStart\"\n class=\"moving-bg {{ customBgClass }}\"\n [style.left]=\"originOffsetX + left + 'px'\"\n [style.width]=\"width + 'px'\"\n></div>\n","import { Directive, ElementRef, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges } from '@angular/core';\r\nimport { GanttScaleUnit } from './gantt.model';\r\n\r\n@Directive({\r\n selector: '[dGanttMarker]',\r\n})\r\nexport class GanttMarkerDirective implements OnChanges, OnDestroy {\r\n @Input() ganttBarContainerElement: HTMLElement;\r\n @Input() ganttScaleContainerOffsetLeft: number;\r\n @Input() monthMark = false;\r\n @Input() weekend = false;\r\n @Input() today = false;\r\n @Input() index: number;\r\n @Input() milestone = '';\r\n @Input() unit: GanttScaleUnit;\r\n @Input() date: Date;\r\n @Input() last: boolean;\r\n @Input() showDaySplitLine = false;\r\n hostElement: HTMLElement;\r\n monthMarkElement: HTMLElement;\r\n weekendElement: HTMLElement;\r\n todayElement: HTMLElement;\r\n milestoneElement: HTMLElement;\r\n daySplitLineElement: HTMLElement;\r\n\r\n constructor(element: ElementRef, private renderer: Renderer2) {\r\n this.hostElement = element.nativeElement;\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n const { index, ganttBarContainerElement, ganttScaleContainerOffsetLeft, monthMark, weekend, last, today, milestone, unit } = changes;\r\n if (this.showDaySplitLine && index) {\r\n if (this.index >= 0 && !this.daySplitLineElement && this.unit === GanttScaleUnit.day) {\r\n this.drawSplitLine();\r\n } else if (this.index >= 0 && this.daySplitLineElement && this.unit === GanttScaleUnit.day) {\r\n this.updateSplitLine();\r\n }\r\n }\r\n\r\n if (ganttBarContainerElement && this.ganttBarContainerElement) {\r\n this.initMarkElement();\r\n }\r\n\r\n if (ganttScaleContainerOffsetLeft && this.ganttScaleContainerOffsetLeft) {\r\n this.setElementsStyle();\r\n }\r\n\r\n if (monthMark) {\r\n if (this.monthMark) {\r\n this.initMarkElement();\r\n } else {\r\n this.destroyMarkElement('monthMark');\r\n }\r\n }\r\n\r\n if (weekend || last) {\r\n if (this.weekend && !this.last) {\r\n this.initMarkElement();\r\n } else {\r\n this.destroyMarkElement('weekend');\r\n }\r\n }\r\n\r\n if (today) {\r\n if (this.today) {\r\n this.initMarkElement();\r\n } else {\r\n this.destroyMarkElement('today');\r\n }\r\n }\r\n\r\n if (milestone) {\r\n if (this.milestone) {\r\n this.initMarkElement();\r\n } else {\r\n this.destroyMarkElement('milestone');\r\n }\r\n }\r\n\r\n if (unit && this.unit) {\r\n if (this.unit !== GanttScaleUnit.day) {\r\n this.destorySplitLine();\r\n }\r\n this.setElementsStyle();\r\n }\r\n }\r\n\r\n initMarkElement() {\r\n if (this.ganttBarContainerElement) {\r\n if (this.monthMark && !this.monthMarkElement) {\r\n const node = this.renderer.createElement('div');\r\n this.renderer.addClass(node, 'devui-mark-line');\r\n this.renderer.appendChild(this.ganttBarContainerElement, node);\r\n this.monthMarkElement = node;\r\n this.setElementsStyle();\r\n }\r\n if (this.weekend && !this.last && !this.weekendElement) {\r\n const node = this.renderer.createElement('div');\r\n this.renderer.addClass(node, 'devui-mark-stripe');\r\n this.renderer.addClass(node, this.unit);\r\n this.renderer.appendChild(this.ganttBarContainerElement, node);\r\n this.weekendElement = node;\r\n this.setElementsStyle();\r\n }\r\n if (this.today && !this.todayElement) {\r\n const node = this.renderer.createElement('div');\r\n this.renderer.addClass(node, 'devui-mark-line');\r\n this.renderer.addClass(node, 'today');\r\n this.renderer.addClass(node, this.unit);\r\n this.renderer.appendChild(this.ganttBarContainerElement, node);\r\n this.todayElement = node;\r\n this.setElementsStyle();\r\n }\r\n if (this.milestone && !this.milestoneElement) {\r\n const node = this.renderer.createElement('div');\r\n this.renderer.addClass(node, 'devui-mark-line');\r\n this.renderer.addClass(node, 'milestone');\r\n this.renderer.addClass(node, this.unit);\r\n this.renderer.appendChild(this.ganttBarContainerElement, node);\r\n this.milestoneElement = node;\r\n this.setElementsStyle();\r\n }\r\n }\r\n }\r\n\r\n drawSplitLine() {\r\n const node = this.renderer.createElement('div');\r\n this.renderer.addClass(node, 'devui-day-split-line');\r\n this.renderer.appendChild(this.ganttBarContainerElement, node);\r\n this.daySplitLineElement = node;\r\n this.updateSplitLine();\r\n }\r\n\r\n updateSplitLine() {\r\n this.ganttScaleContainerOffsetLeft = this.ganttScaleContainerOffsetLeft ? this.ganttScaleContainerOffsetLeft : 0;\r\n const leftOffset = this.hostElement.offsetLeft + this.ganttScaleContainerOffsetLeft + 'px';\r\n if (!this.weekend && this.index && this.daySplitLineElement) {\r\n this.renderer.setStyle(this.daySplitLineElement, 'left', leftOffset);\r\n }\r\n }\r\n\r\n destorySplitLine() {\r\n if (this.showDaySplitLine && this.daySplitLineElement) {\r\n this.renderer.removeChild(this.ganttBarContainerElement, this.daySplitLineElement);\r\n this.daySplitLineElement = null;\r\n }\r\n }\r\n\r\n removeMonthMark() {\r\n if (this.monthMarkElement) {\r\n this.renderer.removeChild(this.ganttBarContainerElement, this.monthMarkElement);\r\n this.monthMarkElement = null;\r\n }\r\n }\r\n\r\n removeWeekendMark() {\r\n if (this.weekendElement) {\r\n this.renderer.removeChild(this.ganttBarContainerElement, this.weekendElement);\r\n this.weekendElement = null;\r\n }\r\n }\r\n\r\n removeTodayMark() {\r\n if (this.todayElement) {\r\n this.renderer.removeChild(this.ganttBarContainerElement, this.todayElement);\r\n this.todayElement = null;\r\n }\r\n }\r\n\r\n removeMileStoneMark() {\r\n if (this.milestoneElement) {\r\n this.renderer.removeChild(this.ganttBarContainerElement, this.milestoneElement);\r\n this.milestoneElement = null;\r\n }\r\n }\r\n\r\n destroyMarkElement(type = 'all') {\r\n switch (type) {\r\n case 'monthMark':\r\n this.removeMonthMark();\r\n break;\r\n case 'weekend':\r\n this.removeWeekendMark();\r\n break;\r\n case 'today':\r\n this.removeTodayMark();\r\n break;\r\n case 'milestone':\r\n this.removeMileStoneMark();\r\n break;\r\n case 'all':\r\n this.removeMonthMark();\r\n this.removeWeekendMark();\r\n this.removeTodayMark();\r\n this.removeMileStoneMark();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n private setElementsStyle() {\r\n this.ganttScaleContainerOffsetLeft = this.ganttScaleContainerOffsetLeft ? this.ganttScaleContainerOffsetLeft : 0;\r\n const leftOffset = this.hostElement.offsetLeft + this.ganttScaleContainerOffsetLeft + 'px';\r\n if (this