UNPKG

@syncfusion/ej2-gantt

Version:
976 lines 120 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import { createElement, isNullOrUndefined, getValue, extend, append } from '@syncfusion/ej2-base'; import * as cls from '../base/css-constants'; import { DataUtil } from '@syncfusion/ej2-data'; import { getUniversalTime } from '../base/utils'; /** * Configures the `Timeline` of the gantt. */ var Timeline = /** @class */ (function () { function Timeline(ganttObj) { this.isZoomIn = false; this.isZooming = false; this.isZoomToFit = false; this.topTierCollection = []; this.bottomTierCollection = []; this.pdfExportTopTierCollection = []; this.pdfExportBottomTierCollection = []; this.restrictRender = true; this.applyDstHour = false; this.performedTimeSpanAction = false; this.dstIncreaseHour = false; this.fromDummyDate = false; this.isZoomedToFit = false; this.isZoomingAction = false; this.increaseIteration = false; this.isFirstLoop = false; this.inconsistenceDstApplied = false; this.parent = ganttObj; this.initProperties(); } /** * To initialize the public property. * * @returns {void} * @private */ Timeline.prototype.initProperties = function () { this.timelineStartDate = null; this.timelineEndDate = null; this.totalTimelineWidth = 0; this.customTimelineSettings = null; this.parent.isTimelineRoundOff = this.isZoomToFit ? false : isNullOrUndefined(this.parent.projectStartDate) ? true : false; if (this.parent.enablePersistence && this.parent.isLoad) { this.parent.timelineSettings = this.parent.currentZoomingLevel; } }; /** * To render timeline header series. * * @returns {void} * @private */ Timeline.prototype.validateTimelineProp = function () { this.roundOffDays(); this.processTimelineProperty(); this.timelineWidthCalculation(); }; /** * Function used to refresh Gantt rows. * * @returns {void} * @private */ Timeline.prototype.refreshTimeline = function () { this.initProperties(); this.processTimelineUnit(); if (!this.parent.undoRedoModule || (this.parent.undoRedoModule && !this.parent.undoRedoModule['isZoomingUndoRedoProgress'])) { this.parent.dataOperation.calculateProjectDates(); } if (!this.parent.isFromOnPropertyChange) { this.parent.updateProjectDates(this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate, this.parent.isTimelineRoundOff); } var timelineContainer = this.parent.element.getElementsByClassName('e-timeline-header-container')[0]['offsetHeight']; this.parent.element.getElementsByClassName('e-gridcontent')[0]['style'].height = 'calc(100% - ' + timelineContainer + 'px)'; this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0]['style'].height = 'calc(100% - ' + timelineContainer + 'px)'; }; /** * Function used to refresh Gantt rows. * * @returns {void} * @private */ Timeline.prototype.refreshTimelineByTimeSpan = function () { this.validateTimelineProp(); if (!this.parent.pdfExportModule || (this.parent.pdfExportModule && !this.parent.pdfExportModule.isPdfExport) || (this.parent.pdfExportModule && this.parent.pdfExportModule.isPdfExport && this.parent.pdfExportModule.helper.exportProps && !this.parent.pdfExportModule.helper.exportProps.fitToWidthSettings.isFitToWidth)) { this.parent.ganttChartModule.chartTimelineContainer.innerHTML = ''; } this.createTimelineSeries(); }; /** * Function used to refresh Gantt rows. * * @returns {void} * @private */ Timeline.prototype.updateChartByNewTimeline = function () { this.parent.chartRowsModule.refreshChartByTimeline(); var currentScrollLeft = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0].scrollLeft; this.parent.element.getElementsByClassName('e-timeline-header-container')[0].scrollLeft = currentScrollLeft; this.parent.notify('refreshDayMarkers', {}); }; /** * Function used to perform Zoomin and Zoomout actions in Gantt control. * * @param {boolean} isZoomIn . * @private * @returns {void} */ Timeline.prototype.processZooming = function (isZoomIn) { if (this.parent.isReact) { this.parent['clearTemplate'](['TaskbarTemplate', 'ParentTaskbarTemplate', 'MilestoneTemplate', 'TaskLabelTemplate', 'RightLabelTemplate', 'LeftLabelTemplate']); } this.isZoomToFit = this.isZoomedToFit = false; this.updateUndoRedo(isZoomIn); if (!this.parent['isProjectDateUpdated']) { this.parent.dateValidationModule.calculateProjectDates(); } if (this.parent.zoomingProjectStartDate) { this.parent.cloneProjectStartDate = this.parent.zoomingProjectStartDate; this.parent.cloneProjectEndDate = this.parent.zoomingProjectEndDate; } this.parent.zoomingProjectStartDate = this.parent.zoomingProjectEndDate = null; var currentZoomingLevel = this.checkCurrentZoomingLevel(); this.isZoomIn = isZoomIn; this.isZooming = true; var currentLevel = this.getZoomLevel(currentZoomingLevel, isZoomIn); this.updateToolbar(currentLevel, isZoomIn); currentLevel = this.parent.zoomingLevels.findIndex(function (tempLevel) { return tempLevel.level === currentLevel; }); var newTimeline = this.parent.zoomingLevels[currentLevel]; var args = { requestType: isZoomIn ? 'beforeZoomIn' : 'beforeZoomOut', timeline: newTimeline, cancel: false }; this.parent.trigger('actionBegin', args); if (!args.cancel) { this.parent['showLoadingIndicator'](); newTimeline = args.timeline; this.changeTimelineSettings(newTimeline); } this.isZooming = false; }; Timeline.prototype.updateUndoRedo = function (isZoomIn) { var action = isZoomIn ? 'ZoomIn' : 'ZoomOut'; if (this.parent.undoRedoModule && this.parent['isUndoRedoItemPresent'](action)) { if (this.parent.undoRedoModule['redoEnabled']) { this.parent.undoRedoModule['disableRedo'](); } this.parent.undoRedoModule['createUndoCollection'](); var previousTimeline = { action: action, previousZoomingLevel: extend({}, {}, this.parent.currentZoomingLevel, true) }; previousTimeline['previousZoomingLevel'].bottomTier.format = this.customTimelineSettings.bottomTier.format; previousTimeline['previousZoomingLevel'].topTier.format = this.customTimelineSettings.topTier.format; this.parent.undoRedoModule['getUndoCollection'][this.parent.undoRedoModule['getUndoCollection'].length - 1] = previousTimeline; } }; Timeline.prototype.getZoomLevel = function (currentZoomingLevel, isZoomIn) { var levelChange = isZoomIn ? 1 : -1; var level = currentZoomingLevel + levelChange; var foundLevel = this.parent.zoomingLevels.find(function (tempLevel) { return tempLevel.level === level; }); return foundLevel ? level : currentZoomingLevel; }; Timeline.prototype.updateToolbar = function (currentLevel, isZoomIn) { if (this.parent.toolbarModule) { if (isZoomIn) { if (currentLevel === this.parent.zoomingLevels[this.parent.zoomingLevels.length - 1].level) { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomin'], false); // disable toolbar items. this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomout'], true); } else { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomout'], true); // disable toolbar items. } } else { if (currentLevel === this.parent.zoomingLevels[0].level) { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomout'], false); // disable toolbar items. this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomin'], true); } else { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomin'], true); // enable toolbar items. } } } }; /** * To change the timeline settings property values based upon the Zooming levels. * * @param {ZoomTimelineSettings} newTimeline . * @returns {void} * @private */ Timeline.prototype.changeTimelineSettings = function (newTimeline) { var _this = this; if (this.isZoomToFit || this.isZooming) { this.isSingleTier = this.customTimelineSettings.topTier.unit === 'None' || this.customTimelineSettings.bottomTier.unit === 'None' ? true : false; } else { this.isSingleTier = newTimeline.topTier.unit === 'None' || newTimeline.bottomTier.unit === 'None' ? true : false; } var skipProperty = this.isSingleTier ? this.customTimelineSettings.topTier.unit === 'None' ? 'topTier' : 'bottomTier' : null; Object.keys(this.customTimelineSettings).forEach(function (property) { if (property !== skipProperty) { _this.customTimelineSettings[property] = (typeof newTimeline[property] === 'object' && !isNullOrUndefined(newTimeline[property])) ? __assign({}, newTimeline[property]) : newTimeline[property]; } else { var value = property === 'topTier' ? 'bottomTier' : 'topTier'; var assignValue = 'bottomTier'; if (newTimeline["" + assignValue].unit !== 'None') { _this.customTimelineSettings[value] = __assign({}, newTimeline[assignValue]); } } }); this.parent.isTimelineRoundOff = this.isZoomToFit ? false : isNullOrUndefined(this.parent.projectStartDate) ? true : false; this.processTimelineUnit(); this.parent.updateProjectDates(this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate, this.parent.isTimelineRoundOff); var criticalModule = this.parent.criticalPathModule; if (this.parent.enableCriticalPath && criticalModule && criticalModule.criticalPathCollection) { criticalModule.criticalConnectorLine(criticalModule.criticalPathCollection, criticalModule.detailPredecessorCollection, true, criticalModule.predecessorCollectionTaskIds); } if (this.isZooming || this.isZoomToFit) { var args = { requestType: this.isZoomIn ? 'AfterZoomIn' : this.isZoomToFit ? 'AfterZoomToProject' : 'AfterZoomOut', timeline: this.parent.currentZoomingLevel }; this.parent.trigger('actionComplete', args); this.parent['hideLoadingIndicator'](); } var tier = this.topTier === 'None' ? 'bottomTier' : 'topTier'; if (this.parent.enableTimelineVirtualization && (!this.parent.pdfExportModule || this.parent.pdfExportModule && !this.parent.pdfExportModule.isPdfExport)) { this.wholeTimelineWidth = this.calculateWidthBetweenTwoDate(tier, this.parent.timelineModule.timelineStartDate, this.parent.timelineModule.timelineEndDate); if (this.wholeTimelineWidth <= this.totalTimelineWidth) { this.wholeTimelineWidth = this.totalTimelineWidth; } // Handled zoomtofit horizontal scrollbar hide while performing different zooming levels in browser at virtualtimeline mode-Task(919516) if (this.isZoomToFit) { this.clientWidthDifference = Math.abs(this.wholeTimelineWidth - this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0].clientWidth) + 1; this.parent.element.querySelectorAll('.e-chart-scroll-container')[0].querySelector('.e-virtualtrack')['style'].width = (this.wholeTimelineWidth - this.clientWidthDifference) + 'px'; if (!isNullOrUndefined(this.parent.element.querySelectorAll('.e-timeline-header-container')[0].querySelector('.e-virtualtrack'))) { this.parent.element.querySelectorAll('.e-timeline-header-container')[0].querySelector('.e-virtualtrack')['style'].width = (this.wholeTimelineWidth - this.clientWidthDifference) + 'px'; } } else { this.parent.element.querySelectorAll('.e-chart-scroll-container')[0].querySelector('.e-virtualtrack')['style'].width = this.wholeTimelineWidth + 'px'; if (!isNullOrUndefined(this.parent.element.querySelectorAll('.e-timeline-header-container')[0].querySelector('.e-virtualtrack'))) { this.parent.element.querySelectorAll('.e-timeline-header-container')[0].querySelector('.e-virtualtrack')['style'].width = this.wholeTimelineWidth + 'px'; } } this.parent.ganttChartModule.updateWidthAndHeight(); } }; /** * To perform the zoom to fit operation in Gantt. * * @returns {void} * @private */ Timeline.prototype.processZoomToFit = function () { if (this.parent.isReact) { this.parent['clearTemplate'](['TaskbarTemplate', 'ParentTaskbarTemplate', 'MilestoneTemplate', 'TaskLabelTemplate', 'RightLabelTemplate', 'LeftLabelTemplate']); } this.isZoomToFit = true; this.isZooming = false; this.isZoomedToFit = true; var previousTimeline = {}; if (this.parent.undoRedoModule && !this.parent.undoRedoModule['isUndoRedoPerformed'] && this.parent['isUndoRedoItemPresent']('ZoomToFit')) { if (this.parent.undoRedoModule['redoEnabled']) { this.parent.undoRedoModule['disableRedo'](); } this.parent.undoRedoModule['createUndoCollection'](); previousTimeline['action'] = 'ZoomToFit'; previousTimeline['previousTimelineStartDate'] = extend([], [], [this.parent.cloneProjectStartDate], true)[0]; previousTimeline['previousTimelineEndDate'] = extend([], [], [this.parent.cloneProjectEndDate], true)[0]; previousTimeline['previousZoomingLevel'] = extend({}, {}, this.parent.currentZoomingLevel, true); this.parent.undoRedoModule['getUndoCollection'][this.parent.undoRedoModule['getUndoCollection'].length - 1] = previousTimeline; } if (!this.parent.zoomingProjectStartDate) { this.parent.zoomingProjectStartDate = this.parent.cloneProjectStartDate; this.parent.zoomingProjectEndDate = this.parent.cloneProjectEndDate; } if (this.parent.zoomingProjectStartDate > this.parent.cloneProjectStartDate) { this.parent.cloneProjectStartDate = new Date(this.parent.allowUnscheduledTasks ? this.parent.zoomingProjectStartDate : this.parent.cloneProjectStartDate); } if (isNullOrUndefined(this.parent.projectStartDate) && isNullOrUndefined(this.parent.projectEndDate)) { this.parent.dataOperation.calculateProjectDates(); } var totalDays; var nonWorkingDays = 0; if (!this.parent.timelineSettings.showWeekend) { nonWorkingDays = this.calculateNonWorkingDaysBetweenDates(this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate); } var timeDifference = (this.parent.cloneProjectEndDate.getTime() - this.parent.cloneProjectStartDate.getTime()); totalDays = (timeDifference / (1000 * 3600 * 24)); totalDays = totalDays - nonWorkingDays; var chartWidth = this.parent.ganttChartModule.chartElement.offsetWidth; var perDayWidth = chartWidth / totalDays; var zoomingLevel; var firstValue; var secondValue; var zoomingCollections = this.parent.zoomingLevels.slice(); var sortedCollectons = zoomingCollections.sort(function (a, b) { return (!a.perDayWidth && !b.perDayWidth ? 0 : (a.perDayWidth < b.perDayWidth) ? 1 : -1); }); if (perDayWidth === 0) { // return when the Gantt chart is not in viewable state. return; } for (var i = 0; i < sortedCollectons.length; i++) { firstValue = sortedCollectons[i]; if (i === sortedCollectons.length - 1) { zoomingLevel = sortedCollectons[i]; break; } else { secondValue = sortedCollectons[i + 1]; } if (perDayWidth >= firstValue.perDayWidth) { zoomingLevel = sortedCollectons[i]; break; } if (perDayWidth < firstValue.perDayWidth && perDayWidth > secondValue.perDayWidth) { zoomingLevel = sortedCollectons[i + 1]; break; } } var newTimeline = extend({}, {}, zoomingLevel, true); if (isNullOrUndefined(this.parent.projectStartDate)) { this.roundOffDateToZoom(this.parent.cloneProjectStartDate, true, perDayWidth, newTimeline.bottomTier.unit, zoomingLevel); } if (isNullOrUndefined(this.parent.projectEndDate)) { this.roundOffDateToZoom(this.parent.cloneProjectEndDate, false, perDayWidth, newTimeline.bottomTier.unit, zoomingLevel); } var numberOfCells = this.calculateNumberOfTimelineCells(newTimeline); var scrollHeight = this.parent.ganttChartModule.scrollElement.offsetHeight - 17; //17 is horizontal scrollbar width var contentHeight = this.parent.ganttChartModule.chartBodyContent.offsetHeight; var emptySpace = contentHeight <= scrollHeight ? 0 : 17; newTimeline.timelineUnitSize = Math.abs((chartWidth - emptySpace)) / numberOfCells; var args = { requestType: 'beforeZoomToProject', timeline: newTimeline }; if (this.parent.toolbarModule) { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomin', this.parent.controlId + '_zoomout'], true); } this.parent.trigger('actionBegin', args); if (!args.cancel) { this.parent['showLoadingIndicator'](); this.changeTimelineSettings(newTimeline); this.parent.isTimelineRoundOff = isNullOrUndefined(this.parent.projectStartDate) ? true : false; } this.isZoomToFit = false; }; Timeline.prototype.bottomTierCellWidthCalc = function (mode, zoomLevel, date) { var convertedMilliSeconds; switch (mode) { case 'Minutes': convertedMilliSeconds = zoomLevel.bottomTier.count * (60 * 1000); break; case 'Hour': convertedMilliSeconds = zoomLevel.bottomTier.count * (60 * 60 * 1000); break; case 'Week': convertedMilliSeconds = zoomLevel.bottomTier.count * (7 * 24 * 60 * 60 * 1000); break; case 'Day': convertedMilliSeconds = zoomLevel.bottomTier.count * (24 * 60 * 60 * 1000); break; case 'Month': { var daysInMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); convertedMilliSeconds = zoomLevel.bottomTier.count * (60 * 60 * 24 * daysInMonth * 1000); break; } case 'Year': { var daysInYear = (date.getFullYear() % 400 === 0 || (date.getFullYear() % 100 !== 0 && date.getFullYear() % 4 === 0)) ? 366 : 365; convertedMilliSeconds = zoomLevel.bottomTier.count * (60 * 60 * 24 * daysInYear * 1000); break; } } return convertedMilliSeconds; }; Timeline.prototype.roundOffDateToZoom = function (date, isStartDate, perDayWidth, tierMode, zoomingLevel) { var roundOffTime = this.bottomTierCellWidthCalc(tierMode, zoomingLevel, date); if (isStartDate) { date.setTime(date.getTime() - roundOffTime); } else { date.setTime(date.getTime() + roundOffTime); } }; /** * Calculates the number of timeline cells required for a given timeline configuration. * * @param {ZoomTimelineSettings} newTimeline - The configuration settings for the timeline, including tier settings. * @returns {number} - Returns the calculated number of timeline cells based on the unit and count. * * The method determines the number of days between the project start and end dates, adjusts this value * by excluding non-working days if weekends are hidden, and calculates the number of timeline cells * that fit within this adjusted duration according to the specified timeline settings. */ Timeline.prototype.calculateNumberOfTimelineCells = function (newTimeline) { var sDate = new Date(this.parent.cloneProjectStartDate.getTime()); var eDate = new Date(this.parent.cloneProjectEndDate.getTime()); this.parent.dateValidationModule['updateDateWithTimeZone'](sDate, eDate); var numberOfDays; var nonWorkingDays = 0; if (!this.parent.timelineSettings.showWeekend) { nonWorkingDays = this.calculateNonWorkingDaysBetweenDates(this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate); } numberOfDays = Math.abs((eDate.getTime() - sDate.getTime()) / (24 * 60 * 60 * 1000)); numberOfDays -= nonWorkingDays; var count = newTimeline.bottomTier.count; var unit = newTimeline.bottomTier.unit; if (unit === 'Day') { return numberOfDays / count; } else if (unit === 'Week') { return (numberOfDays / count) / 7; } else if (unit === 'Month') { return (numberOfDays / count) / 28; } else if (unit === 'Year') { return (numberOfDays / count) / (12 * 28); } else if (unit === 'Hour') { return numberOfDays * (24 / count); } else { return numberOfDays * ((60 * 24) / count); } }; /** * To validate time line unit. * * @returns {void} * @private */ Timeline.prototype.processTimelineUnit = function () { var directProperty = ['timelineViewMode', 'timelineUnitSize', 'weekStartDay', 'weekendBackground']; var innerProperty = { 'topTier': ['unit', 'format', 'count', 'formatter'], 'bottomTier': ['unit', 'format', 'count', 'formatter'] }; var tierUnits = ['Year', 'Month', 'Week', 'Day', 'Hour', 'Minutes']; this.customTimelineSettings = this.customTimelineSettings ? this.customTimelineSettings : this.extendFunction(this.parent.timelineSettings, directProperty, innerProperty); if ((tierUnits.indexOf(this.customTimelineSettings.topTier.unit) === -1) && (tierUnits.indexOf(this.customTimelineSettings.bottomTier.unit) === -1)) { this.customTimelineSettings.topTier.unit = tierUnits.indexOf(this.customTimelineSettings.timelineViewMode) !== -1 ? this.customTimelineSettings.timelineViewMode : 'Week'; this.customTimelineSettings.bottomTier.unit = tierUnits.indexOf(this.customTimelineSettings.topTier.unit) !== 5 ? tierUnits[tierUnits.indexOf(this.customTimelineSettings.topTier.unit) + 1] : 'None'; } else if ((tierUnits.indexOf(this.customTimelineSettings.topTier.unit) !== -1 && tierUnits.indexOf(this.customTimelineSettings.bottomTier.unit) !== -1) && (tierUnits.indexOf(this.customTimelineSettings.topTier.unit) > tierUnits.indexOf(this.customTimelineSettings.bottomTier.unit))) { this.customTimelineSettings.bottomTier.unit = this.customTimelineSettings.topTier.unit; } else { this.customTimelineSettings.topTier.unit = tierUnits.indexOf(this.customTimelineSettings.topTier.unit) === -1 ? 'None' : this.customTimelineSettings.topTier.unit; this.customTimelineSettings.bottomTier.unit = tierUnits.indexOf(this.customTimelineSettings.bottomTier.unit) === -1 ? 'None' : this.customTimelineSettings.bottomTier.unit; } this.topTier = this.customTimelineSettings.topTier.unit; this.bottomTier = this.customTimelineSettings.bottomTier.unit; this.previousIsSingleTier = this.isSingleTier; this.isSingleTier = this.topTier === 'None' || this.bottomTier === 'None' ? true : false; }; /** * To validate timeline properties. * * @returns {void} * @private */ Timeline.prototype.processTimelineProperty = function () { this.customTimelineSettings.topTier.count = (this.topTier === 'None') ? 1 : this.validateCount(this.customTimelineSettings.topTier.unit, this.customTimelineSettings.topTier.count, 'topTier'); this.customTimelineSettings.bottomTier.count = this.customTimelineSettings.bottomTier.unit === 'None' ? 1 : this.validateCount(this.customTimelineSettings.bottomTier.unit, this.customTimelineSettings.bottomTier.count, 'bottomTier'); this.customTimelineSettings.bottomTier.format = this.validateFormat(this.customTimelineSettings.bottomTier.unit, this.customTimelineSettings.bottomTier.format); this.customTimelineSettings.topTier.format = this.validateFormat(this.topTier, this.customTimelineSettings.topTier.format); this.customTimelineSettings.weekStartDay = this.customTimelineSettings.weekStartDay >= 0 && this.customTimelineSettings.weekStartDay <= 6 ? this.customTimelineSettings.weekStartDay : 0; if (!(this.parent.pdfExportModule && this.parent.pdfExportModule.helper.exportProps && this.parent.pdfExportModule.isPdfExport && this.parent.pdfExportModule.helper.exportProps.fitToWidthSettings.isFitToWidth)) { this.checkCurrentZoomingLevel(); } }; /** * To find the current zooming level of the Gantt control. * * @returns {void} * @private */ Timeline.prototype.calculateZoomingLevelsPerDayWidth = function () { var collections = this.parent.zoomingLevels; for (var i = 0; i < collections.length; i++) { var perDayWidth = this.getPerDayWidth(collections[i].timelineUnitSize, collections[i].bottomTier.count, collections[i].bottomTier.unit); collections[i].perDayWidth = perDayWidth; } }; /** * To find the current zooming level of the Gantt control. * * @returns {void} * @private */ Timeline.prototype.checkCurrentZoomingLevel = function () { var count = this.customTimelineSettings.bottomTier.unit !== 'None' ? this.customTimelineSettings.bottomTier.count : this.customTimelineSettings.topTier.count; var unit = this.customTimelineSettings.bottomTier.unit !== 'None' ? this.customTimelineSettings.bottomTier.unit : this.customTimelineSettings.topTier.unit; var tier = this.customTimelineSettings.bottomTier.unit !== 'None' ? 'bottomTier' : 'topTier'; var zoomLevel = this.getCurrentZoomingLevel(unit, count, tier); if (this.parent.toolbarModule) { if (zoomLevel === this.parent.zoomingLevels[this.parent.zoomingLevels.length - 1].level) { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomin'], false); } else if (zoomLevel === this.parent.zoomingLevels[0].level) { this.parent.toolbarModule.enableItems([this.parent.controlId + '_zoomout'], false); } } this.parent.currentZoomingLevel = this.parent.zoomingLevels[zoomLevel]; return zoomLevel; }; /** * @param {string} unit . * @param {number} count . * @param {string} tier . * @returns {number} . * @private */ Timeline.prototype.getCurrentZoomingLevel = function (unit, count, tier) { var level; var currentZoomCollection; var checkSameCountLevels; var secondValue; var firstValue; if (!this.parent.zoomingLevels.length) { this.parent.zoomingLevels = this.parent.getZoomingLevels(); } var sameUnitLevels = this.parent.zoomingLevels.filter(function (tempLevel) { if (tier === 'bottomTier') { return tempLevel.bottomTier.unit === unit; } else { return tempLevel.topTier.unit === unit; } }); if (sameUnitLevels.length === 0) { var closestUnit_1 = this.getClosestUnit(unit, '', false); sameUnitLevels = this.parent.zoomingLevels.filter(function (tempLevel) { if (tier === 'bottomTier') { return tempLevel.bottomTier.unit === closestUnit_1; } else { return tempLevel.topTier.unit === closestUnit_1; } }); } var sortedUnitLevels = sameUnitLevels.sort(function (a, b) { if (tier === 'bottomTier') { return (!a.bottomTier.count || !b.bottomTier.count) ? 0 : ((a.bottomTier.count < b.bottomTier.count) ? 1 : -1); } else { return (!a.topTier.count || !b.topTier.count) ? 0 : ((a.topTier.count < b.topTier.count) ? 1 : -1); } }); for (var i = 0; i < sortedUnitLevels.length; i++) { firstValue = sortedUnitLevels[i]; if (i === sortedUnitLevels.length - 1) { level = sortedUnitLevels[i].level; break; } else { secondValue = sortedUnitLevels[i + 1]; } if (count >= firstValue["" + tier].count) { currentZoomCollection = sortedUnitLevels[i]; checkSameCountLevels = sortedUnitLevels.filter(function (tempLevel) { if (tier === 'bottomTier') { return tempLevel.bottomTier.count === currentZoomCollection.bottomTier.count; } else { return tempLevel.topTier.count === currentZoomCollection.topTier.count; } }); if (checkSameCountLevels.length > 1) { level = this.checkCollectionsWidth(checkSameCountLevels); } else { level = checkSameCountLevels[0].level; } break; } else if (count < firstValue["" + tier].count && count > secondValue["" + tier].count) { currentZoomCollection = sortedUnitLevels[i + 1]; checkSameCountLevels = sortedUnitLevels.filter(function (tempLevel) { if (tier === 'bottomTier') { return tempLevel.bottomTier.count === currentZoomCollection.bottomTier.count; } else { return tempLevel.topTier.count === currentZoomCollection.topTier.count; } }); if (checkSameCountLevels.length > 1) { level = this.checkCollectionsWidth(checkSameCountLevels); } else { level = checkSameCountLevels[0].level; } break; } } return level; }; /** * Getting closest zooimg level. * * @param {string} unit . * @param {string} closetUnit . * @param {boolean} isCont . * @returns {string} . * @private */ Timeline.prototype.getClosestUnit = function (unit, closetUnit, isCont) { var bottomTierUnits = ['Year', 'Month', 'Week', 'Day', 'Hour', 'Minutes']; var index = bottomTierUnits.indexOf(unit); if (index === 0) { isCont = true; } if (this.isZoomIn || isCont) { unit = bottomTierUnits[index + 1]; } else { unit = bottomTierUnits[index - 1]; } var sameUnitLevels = this.parent.zoomingLevels.filter(function (tempLevel) { return tempLevel.bottomTier.unit === unit; }); if (sameUnitLevels.length === 0) { if (unit === 'Year') { isCont = true; } closetUnit = unit; return this.getClosestUnit(unit, closetUnit, isCont); } else { return unit; } }; Timeline.prototype.checkCollectionsWidth = function (checkSameLevels) { var zoomLevels = checkSameLevels; var width = this.customTimelineSettings.timelineUnitSize; var level; var secondValue; var firstValue; var sortedZoomLevels = zoomLevels.sort(function (a, b) { return (a.timelineUnitSize < b.timelineUnitSize) ? 1 : -1; }); for (var i = 0; i < sortedZoomLevels.length; i++) { firstValue = sortedZoomLevels[i]; if (i === sortedZoomLevels.length - 1) { level = sortedZoomLevels[i].level; break; } else { secondValue = sortedZoomLevels[i + 1]; } if (width >= firstValue.timelineUnitSize) { level = sortedZoomLevels[i].level; break; } else if (width < firstValue.timelineUnitSize && width > secondValue.timelineUnitSize) { level = sortedZoomLevels[i + 1].level; break; } } return level; }; /** * To create timeline header template. * * @returns {void} * @private */ Timeline.prototype.updateTimelineHeaderHeight = function () { if (this.parent.timelineModule.isSingleTier) { this.parent.element.classList.add(cls.ganttSingleTimeline); } else { this.parent.element.classList.remove(cls.ganttSingleTimeline); } if (this.previousIsSingleTier !== this.isSingleTier) { var toolbarHeight = 0; if (!isNullOrUndefined(this.parent.toolbarModule) && !isNullOrUndefined(this.parent.toolbarModule.element)) { toolbarHeight = this.parent.toolbarModule.element.offsetHeight; } this.parent.ganttChartModule.scrollObject. setHeight(this.parent.ganttHeight - this.parent.ganttChartModule.chartTimelineContainer.offsetHeight - toolbarHeight); this.parent.treeGrid.height = this.parent.ganttHeight - toolbarHeight - this.parent.ganttChartModule.chartTimelineContainer.offsetHeight; } }; /** * Calculates the corresponding date for a given left pixel value on the timeline. * * @param {number} left - The left position in pixels to be converted to a date. * @param {boolean} isMilestone - (Optional) A boolean indicating whether the date refers to a milestone. * @param {ITaskData} property - (Optional) An object containing task data, used when adjusting for milestones. * @returns {Date} - Returns the calculated date according to the Gantt chart's timeline settings. * * This method converts a pixel-based position on the Gantt timeline to an actual date, * taking into account working days, non-working days, and adjustments for daylight saving * time. If weekends are hidden, it calculates the date based on working weeks. * For milestones, it adjusts the date by determining the accurate end time. */ Timeline.prototype.dateByLeftValue = function (left, isMilestone, property) { var pStartDate = new Date(this.parent.timelineModule.timelineStartDate.toString()); var milliSecondsPerPixel = (24 * 60 * 60 * 1000) / this.parent.perDayWidth; if (!this.parent.timelineSettings.showWeekend) { pStartDate = this.calculateDateExcludingNonWorkingDays(left, pStartDate); } else { pStartDate.setTime(pStartDate.getTime() + (left * milliSecondsPerPixel)); } /* To render the milestone in proper date while editing */ if (isMilestone && !isNullOrUndefined(property.predecessorsName) && property.predecessorsName !== '') { pStartDate.setDate(pStartDate.getDate() - 1); var dayEndTime = this.parent['getCurrentDayEndTime'](property.isAutoSchedule ? property.autoEndDate : property.endDate); this.parent.dateValidationModule.setTime(dayEndTime, pStartDate); pStartDate = this.parent.dateValidationModule.checkStartDate(pStartDate, property, true); } var tierMode = this.parent.timelineModule.bottomTier !== 'None' ? this.parent.timelineModule.topTier : this.parent.timelineModule.bottomTier; if (tierMode !== 'Hour' && tierMode !== 'Minutes') { if (this.parent.isInDst(new Date(this.parent.timelineModule.timelineStartDate.toString())) && !this.parent.isInDst(pStartDate)) { pStartDate.setTime(pStartDate.getTime() + (60 * 60 * 1000)); } else if (!this.parent.isInDst(new Date(this.parent.timelineModule.timelineStartDate.toString())) && this.parent.isInDst(pStartDate)) { pStartDate.setTime(pStartDate.getTime() - (60 * 60 * 1000)); } } return pStartDate; }; /** * Calculates a date by considering a given distance in pixels and excluding non-working days. * * This function takes into account the width of each day in the Gantt chart as well as non-working days to compute the resulting date from a specified pixel position. * It returns the date that corresponds to the pixel distance from `pStartDate`. * * @param {number} left - The distance in pixels from the start date to calculate the date. * @param {Date} pStartDate - The start date from which to calculate the resulting date. * @returns {Date} - Returns the calculated date excluding non-working days. */ Timeline.prototype.calculateDateExcludingNonWorkingDays = function (left, pStartDate) { var milliSecondsPerPixel = (24 * 60 * 60 * 1000) / this.parent.perDayWidth; var milliSecondsPerDay = (24 * 60 * 60 * 1000); var nonWorkingDays = this.parent.nonWorkingDayIndex; var totalDays = Math.ceil(left * milliSecondsPerPixel / milliSecondsPerDay); var totalDaysPerWeek = 7; var workingDaysPerWeek = totalDaysPerWeek - nonWorkingDays.length; // Calculate full weeks and extra days var fullWeeks = Math.floor(totalDays / workingDaysPerWeek); var extraDays = totalDays % workingDaysPerWeek; // Set the calculated date by adding full weeks var calculatedDate = new Date(pStartDate); calculatedDate.setDate(calculatedDate.getDate() + fullWeeks * totalDaysPerWeek); // Process the remaining days var daysAdded = 0; while (daysAdded < extraDays) { calculatedDate.setDate(calculatedDate.getDate() + 1); if (nonWorkingDays.indexOf(calculatedDate.getDay()) === -1) { daysAdded++; } } return calculatedDate; }; /** * To create timeline header template. * * @returns {void} * @private */ Timeline.prototype.createTimelineSeries = function () { var tr; var td; var div; var table; var thead; var virtualTableDiv; var virtualTrackDiv; var loopCount = this.isSingleTier ? 1 : 2; var tier = this.topTier === 'None' ? 'bottomTier' : 'topTier'; this.topTierCollection = []; this.bottomTierCollection = []; if (this.restrictRender === true) { this.updateTimelineHeaderHeight(); this.wholeTimelineWidth = this.calculateWidthBetweenTwoDate(tier, this.parent.timelineModule.timelineStartDate, this.parent.timelineModule.timelineEndDate); } if (this.parent.enableTimelineVirtualization && (this.wholeTimelineWidth > this.parent.element.offsetWidth * 3)) { for (var count = 0; count < loopCount; count++) { table = createElement('table', { className: cls.timelineHeaderTableContainer, styles: 'display: block;' }); table.setAttribute('role', 'none'); thead = createElement('thead', { className: cls.timelineHeaderTableBody, styles: 'display:block; border-collapse:collapse' }); var trTemplate = this.createTimelineTemplate(tier); tr = createElement('tr'); if (this.parent.enableHover) { tr.classList.add('e-timeline-cell-hover'); } Array.from(trTemplate.childNodes).forEach(function (child) { tr.appendChild(child); }); td = createElement('td'); div = createElement('div', { styles: 'width: 20px' }); virtualTableDiv = createElement('div', { className: cls.virtualTable }); virtualTrackDiv = createElement('div', { className: cls.virtualTrack }); td.appendChild(div); tr.appendChild(td); virtualTableDiv.appendChild(tr); thead.appendChild(virtualTableDiv); thead.appendChild(virtualTrackDiv); table.appendChild(thead); this.parent.ganttChartModule.chartTimelineContainer.appendChild(table); tier = 'bottomTier'; tr = null; this.restrictRender = false; } this.timelineVirtualizationStyles(); } else { for (var count = 0; count < loopCount; count++) { table = createElement('table', { className: cls.timelineHeaderTableContainer, styles: 'display: block;' }); table.setAttribute('role', 'none'); thead = createElement('thead', { className: cls.timelineHeaderTableBody, styles: 'display:block; border-collapse:collapse' }); var trTemplate = this.createTimelineTemplate(tier); tr = createElement('tr'); if (this.parent.enableHover) { tr.classList.add('e-timeline-cell-hover'); } Array.from(trTemplate.childNodes).forEach(function (child) { tr.appendChild(child); }); td = createElement('td'); div = createElement('div', { styles: 'width: 20px' }); td.appendChild(div); tr.appendChild(td); thead.appendChild(tr); table.appendChild(thead); this.parent.ganttChartModule.chartTimelineContainer.appendChild(table); tier = 'bottomTier'; tr = null; } this.wholeTimelineWidth = this.totalTimelineWidth; } }; Timeline.prototype.timelineVirtualizationStyles = function () { var translateXValue = 0; var translateYValue = 0; var trackWidth = this.wholeTimelineWidth; if (this.parent.enableTimelineVirtualization) { //e-content styles updating translateXValue = (this.parent.enableTimelineVirtualization && !isNullOrUndefined(this.parent.ganttChartModule.scrollObject.element.scrollLeft) && this.parent.ganttChartModule.scrollObject.element.scrollLeft !== 0) ? this.parent.ganttChartModule.scrollObject.getTimelineLeft() : 0; if (this.parent.enableRtl) { translateXValue = -(translateXValue); } var contentVirtualTable = this.parent.element.querySelectorAll('.e-chart-scroll-container')[0].querySelector('.e-virtualtable'); if (!this.parent.undoRedoModule || (this.parent.undoRedoModule && !this.parent.undoRedoModule['isZoomingUndoRedoProgress'])) { contentVirtualTable.style.transform = "translate(" + translateXValue + "px, " + translateYValue + "px)"; } var contentVirtualTrack = this.parent.element.querySelectorAll('.e-chart-scroll-container')[0].querySelector('.e-virtualtrack'); contentVirtualTrack.style.position = 'relative'; contentVirtualTrack.style.width = trackWidth + 'px'; //timeline styles updating if (this.parent.ganttChartModule.scrollObject['isSetScrollLeft']) { var virtualTableStylesT = this.parent.element.querySelectorAll('.e-timeline-header-table-container')[0].querySelector('.e-virtualtable'); var virtualTableStylesB = void 0; if (!isNullOrUndefined(this.parent.element.querySelectorAll('.e-timeline-header-table-container')[1])) { virtualTableStylesB = this.parent.element.querySelectorAll('.e-timeline-header-table-container')[1].querySelector('.e-virtualtable'); } virtualTableStylesT.style.transform = "translate(" + translateXValue + "px, " + translateYValue + "px)"; if (!isNullOrUndefined(virtualTableStylesB)) { virtualTableStylesB.style.transform = "translate(" + translateXValue + "px, " + translateYValue + "px)"; } } var virtualTrackStylesT = this.parent.element.querySelectorAll('.e-timeline-header-table-container')[0].querySelector('.e-virtualtrack'); var virtualTrackStylesB = void 0; if (!isNullOrUndefined(this.parent.element.querySelectorAll('.e-timeline-header-table-container')[1])) { virtualTrackStylesB = this.parent.element.querySelectorAll('.e-timeline-header-table-container')[1].querySelector('.e-virtualtrack'); } if (!isNullOrUndefined(virtualTrackStylesB)) { virtualTrackStylesB.style.position = 'relative'; virtualTrackStylesB.style.width = trackWidth + 'px'; } virtualTrackStylesT.style.position = 'relative'; virtualTrackStylesT.style.width = trackWidth + 'px'; //dependency viewer styles updating var dependencyViewer = this.parent.connectorLineModule.svgObject; dependencyViewer['style'].width = trackWidth + 'px'; // timeline header container width updating var timelineHeader = this.parent.element.querySelector('.' + cls.timelineHeaderContainer); timelineHeader['style'].width = 'calc(100% - ' + 17 + 'px)'; if (this.parent.timelineModule.isZooming || this.parent.timelineModule.isZoomToFit) { this.parent.ganttChartModule.scrollElement.scrollLeft = 0; this.isZoomingAction = true; this.parent.ganttChartModule.scrollObject.updateChartElementStyles(); } } }; /** * To validate timeline tier count. * * @param {string} mode . * @param {number} count . * @param {string} tier . * @returns {number} . * @private */ Timeline.prototype.validateCount = function (mode, count, tier) { var tierCount = !isNullOrUndefined(count) && parseInt(count.toString(), 10) > 0 ? parseInt(count.toString(), 10) : 1; var timeDifference = Math.abs(this.timelineRoundOffEndDate.getTime() - this.timelineStartDate.getTime()); var difference; switch (mode) { case 'Year': difference = Math.round((timeDifference / (1000 * 3600 * 24)) / (12 * 28)); tierCount = tierCount <= difference ? tierCount : difference > 0 ? difference : 1; if (this.topTier !== 'None' && tier === 'bottomTier') { tierCount = this.validateBottomTierCount(mode, tierCount); } break; case 'Month': difference = Math.round((timeDifference / (1000 * 3600 * 24)) / 28); tierCount = tierCount <= difference ? tierCount : difference > 0 ? (difference + 1) : 1; if (this.topTier !== 'None' && tier === 'bottomTier') { tierCount = this.validateBottomTierCount(mode, tierCount); } break; case 'Week': difference = Math.round((timeDifference / (1000 * 3600 * 24)) / 7); tierCount = tierCount <= difference ? tierCount : difference > 0 ? difference : 1; if (this.topTier !== 'None' && tier === 'bottomTier') { tierCount = this.validateBottomTierCount(mode, tierCount); } break; case