UNPKG

@syncfusion/ej2-gantt

Version:
1,018 lines 98 kB
import { createElement, formatUnit, EventHandler, Browser } from '@syncfusion/ej2-base'; import { isNullOrUndefined, closest, addClass, removeClass, getValue, setValue } from '@syncfusion/ej2-base'; import * as cls from '../base/css-constants'; import { ChartScroll } from '../actions/chart-scroll'; import { click } from '@syncfusion/ej2-grids'; import { VirtualContentRenderer } from '../renderer/virtual-content-render'; /** * module to render gantt chart - project view */ var GanttChart = /** @class */ (function () { function GanttChart(parent) { this.isExpandCollapseFromChart = false; this.isExpandAll = false; this.isCollapseAll = false; this.debounceTimeoutNext = 0; this.debounceTimeout = 0; this.isGanttElement = false; this.previousPinchDistance = 0; this.currentToolbarIndex = -1; this.isPinching = false; this.preventScrollIntoView = false; this.parent = parent; this.chartTimelineContainer = null; this.rangeViewContainer = createElement('div', { className: cls.rangeContainer }); this.rangeViewContainer.setAttribute('role', 'button'); this.rangeViewContainer.setAttribute('aria-label', 'RangeContainer'); this.virtualRender = new VirtualContentRenderer(this.parent); this.addEventListener(); } GanttChart.prototype.addEventListener = function () { this.parent.on('renderPanels', this.renderChartContainer, this); this.parent.on('recordsUpdated', this.renderChartElements, this); this.parent.on('dataReady', this.renderInitialContents, this); this.parent.on('tree-grid-created', this.renderChartContents, this); this.parent.on('destroy', this.destroy, this); }; GanttChart.prototype.renderChartContents = function () { this.parent.notify('refreshDayMarkers', {}); this.wireEvents(); }; /** * Method to render top level containers in Gantt chart * * @returns {void} . * @private */ GanttChart.prototype.renderChartContainer = function () { this.chartElement = createElement('div', { id: this.parent.element.id + 'GanttChart', className: cls.ganttChart }); this.parent.chartPane.appendChild(this.chartElement); this.renderTimelineContainer(); this.renderBodyContainers(); // render top level div header and content // Get timeline header from timeline class file and append to header div // render content div // Render scroll able div // Render container for all element like, table, weekend and holidays // Get rows element from rows renderer class // Get label related info label renderer class // Get baseline from baseline renderer class // Get weekend elements from weekend-holidays renderer class }; /** * method to render timeline, holidays, weekends at load time * * @returns {void} . */ GanttChart.prototype.renderInitialContents = function () { this.parent.timelineModule.createTimelineSeries(); }; /** * @returns {void} . * @private */ GanttChart.prototype.renderOverAllocationContainer = function () { for (var i = 0; i < this.parent.flatData.length; i++) { var data = this.parent.flatData[i]; if (data.childRecords.length > 0) { this.parent.dataOperation.updateOverlappingValues(data); } } var rangeContainer = this.parent.element.querySelector('.' + cls.rangeContainer); if (rangeContainer) { rangeContainer.innerHTML = ''; } if (this.parent.treeGrid.grid.filterSettings.columns.length === 0) { this.renderRangeContainer(this.parent.currentViewData); } }; GanttChart.prototype.renderChartElements = function () { if (this.parent.isFromOnPropertyChange) { this.rangeViewContainer.innerHTML = ''; this.parent.updateProjectDates(this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate, this.parent.isTimelineRoundOff); this.parent.isFromOnPropertyChange = false; } else { this.parent.chartRowsModule.renderChartRows(); if (this.parent.predecessorModule && this.parent.taskFields.dependency) { this.parent.connectorLineIds = []; this.parent.updatedConnectorLineCollection = []; this.parent.predecessorModule.createConnectorLinesCollection(); } this.parent.connectorLineModule.renderConnectorLines(this.parent.updatedConnectorLineCollection); for (var i = 0; i < this.parent.chartRowsModule.ganttChartTableBody.children.length; i++) { if (this.parent.chartRowsModule.ganttChartTableBody.children[i].children[0].children[1].children[4]) { this.parent.chartRowsModule.ganttChartTableBody.children[i].children[0].children[1].children[1].setAttribute('tabindex', '-1'); this.parent.chartRowsModule.ganttChartTableBody.children[i].children[0].children[1].children[2].setAttribute('tabindex', '-1'); this.parent.chartRowsModule.ganttChartTableBody.children[i].children[0].children[1].children[4].setAttribute('tabindex', '-1'); } else { if (this.parent.viewType === 'ProjectView') { var node = this.parent.chartRowsModule.ganttChartTableBody. children[parseInt(i.toString(), 10)].children[0].children[1].children[1]; if (!isNullOrUndefined(node)) { this.parent.chartRowsModule.ganttChartTableBody.children[i].children[0].children[1].children[1].setAttribute('tabindex', '-1'); } } else if (this.parent.chartRowsModule.ganttChartTableBody.children[parseInt(i.toString(), 10)].children[0]. children[1].children[0]) { this.parent.chartRowsModule.ganttChartTableBody.children[i].children[0].children[1].children[0].setAttribute('tabindex', '-1'); } } } var criticalModule = this.parent.criticalPathModule; if (this.parent.enableCriticalPath && criticalModule && criticalModule.criticalPathCollection) { this.parent.criticalPathModule.criticalConnectorLine(criticalModule.criticalPathCollection, criticalModule.detailPredecessorCollection, this.parent.enableCriticalPath, criticalModule.predecessorCollectionTaskIds); } if (this.parent.showOverAllocation) { this.renderOverAllocationContainer(); } } this.updateWidthAndHeight(); var isUpdateRowIndex = this.parent.loadChildOnDemand && (this.parent['isExpandPerformed'] || (!isNullOrUndefined(this.parent['isVirtualScroll']) && this.parent['isVirtualScroll'])); if (this.parent.isLoad && !isUpdateRowIndex) { this.parent.notify('selectRowByIndex', {}); } if (this.parent.timelineModule.isZoomedToFit) { this.parent.timelineModule.processZoomToFit(); } }; /** * @param {IGanttData[]} records . * @returns {void} . * @private */ GanttChart.prototype.renderRangeContainer = function (records) { var recordLength = records.length; var count; var ganttRecord; var rangeCollection; if (this.parent.treeGrid.grid.filterSettings.columns.length === 0) { for (count = 0; count < recordLength; count++) { ganttRecord = records[count]; rangeCollection = ganttRecord.ganttProperties.workTimelineRanges; if (rangeCollection) { this.renderRange(rangeCollection, ganttRecord); } } } }; GanttChart.prototype.getTopValue = function (currentRecord) { var updatedRecords = this.parent.expandedRecords; var recordIndex = updatedRecords.indexOf(currentRecord); if (currentRecord.parentItem && recordIndex === -1) { var nestedParent = this.parent.getRecordByID(currentRecord.parentItem.taskId); recordIndex = updatedRecords.indexOf(nestedParent); } if (!currentRecord.expanded) { return (recordIndex * this.parent.rowHeight); } return ((recordIndex + 1) * this.parent.rowHeight); }; // Recursively collects all child records in a hierarchy. GanttChart.prototype.getHierarchyChildRecords = function (records) { var hierarchyChildRecords = []; for (var _i = 0, records_1 = records; _i < records_1.length; _i++) { var record = records_1[_i]; if (record.childRecords && record.childRecords.length > 0) { hierarchyChildRecords.push(record); // Include the current record this.collectHierarchyChildren(record.childRecords, hierarchyChildRecords); } } return hierarchyChildRecords; }; // Helper function to append children records to the list. GanttChart.prototype.collectHierarchyChildren = function (records, accumulator) { for (var _i = 0, records_2 = records; _i < records_2.length; _i++) { var record = records_2[_i]; if (record.childRecords && record.childRecords.length > 0) { accumulator.push(record); this.collectHierarchyChildren(record.childRecords, accumulator); } } }; // Get height for range bar, considering hierarchy child records. GanttChart.prototype.getRangeHeight = function (data) { var heightDifference = Math.floor(this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight); if (!data.expanded && data.hasChildRecords) { return this.calculateCollapsedRowHeight(heightDifference); } var hierarchyChildLength = this.calculateHierarchyChildLength(data); return this.calculateExpandedRowHeight(data.childRecords.length, hierarchyChildLength, heightDifference); }; // Calculates height when the row is collapsed. GanttChart.prototype.calculateCollapsedRowHeight = function (heightDifference) { return this.parent.rowHeight - heightDifference; }; // Calculates the total length from hierarchy children. GanttChart.prototype.calculateHierarchyChildLength = function (data) { if (!data.childRecords || data.childRecords.length === 0) { return 0; } var hierarchyChildRecords = this.getHierarchyChildRecords(data.childRecords); var hierarchyChildDataLength = 0; for (var _i = 0, hierarchyChildRecords_1 = hierarchyChildRecords; _i < hierarchyChildRecords_1.length; _i++) { var item = hierarchyChildRecords_1[_i]; if (item.childRecords.length !== 0 && item.expanded) { hierarchyChildDataLength += item.childRecords.length; } } return hierarchyChildDataLength; }; // Calculates height when the row is expanded and incorporates child records. GanttChart.prototype.calculateExpandedRowHeight = function (childLength, hierarchyChildLength, heightDifference) { return ((childLength + hierarchyChildLength) * this.parent.rowHeight) - heightDifference; }; GanttChart.prototype.renderRange = function (rangeCollection, currentRecord) { var topValue = 0; var rowIndex = this.parent.currentViewData.indexOf(currentRecord); if (!this.parent.allowTaskbarOverlap && this.parent.enableMultiTaskbar) { // Handling overallocation lines for multiple hierarchy-level record collapse actions - Task:887301 var parentRecord = currentRecord.parentItem ? this.parent.getParentTask(currentRecord.parentItem) : null; if (currentRecord.parentItem && parentRecord && !parentRecord.expanded && currentRecord.hasChildRecords && !currentRecord.expanded) { topValue = this.parent.getRowByIndex(this.parent.getRootParent(currentRecord, 0).index).offsetTop; } else { var rowOffset = this.parent.getRowByIndex(rowIndex).offsetTop; topValue = !currentRecord.expanded ? rowOffset : rowOffset + this.parent.rowHeight; } } else { topValue = this.getTopValue(currentRecord); } var sameIDElement = this.rangeViewContainer.querySelector('.' + 'rangeContainer' + currentRecord.ganttProperties.rowUniqueID); if (sameIDElement) { sameIDElement.remove(); } var parentDiv = createElement('div', { className: 'rangeContainer' + currentRecord.ganttProperties.rowUniqueID, styles: "top:" + topValue + "px; position: absolute;" }); if (currentRecord.level === 0 && !currentRecord.expanded && isNullOrUndefined(currentRecord.parentItem) && !this.parent.enableMultiTaskbar) { return; } if (currentRecord.level > 0 && currentRecord.expanded && !this.parent.getRecordByID(currentRecord.parentItem.taskId).expanded) { return; } for (var i = 0; i < rangeCollection.length; i++) { var height = void 0; var node = this.parent.chartRowsModule.ganttChartTableBody.childNodes; if (!this.parent.allowTaskbarOverlap && !currentRecord.expanded && this.parent.enableMultiTaskbar) { // Render proper overallocation line height during collapseall actions - Task:872518 var parentRecord = this.parent.getRootParent(currentRecord, 0); rowIndex = parentRecord.expanded ? rowIndex : this.parent.currentViewData.indexOf(parentRecord); height = parseInt(node[rowIndex].style.height, 10) - (this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight); } else { height = this.getRangeHeight(currentRecord); } var leftDiv = createElement('div', { className: cls.rangeChildContainer + ' ' + 'e-leftarc', styles: (this.parent.enableRtl ? 'right:' : 'left:') + ((this.parent.enableRtl ? rangeCollection[i].left + rangeCollection[i].width - 5 : rangeCollection[i].left) + "px;\n top: " + Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight) / 2) + "px;\n height: " + (height + 1) + "px; border-right: 0px;\n z-index: " + ((this.parent.viewType === 'ProjectView') ? currentRecord.childRecords.length > 1 ? currentRecord.childRecords.length + 1 : currentRecord.childRecords.length : 6)) }); var rightDiv = createElement('div', { className: cls.rangeChildContainer + ' ' + 'e-rightarc', styles: (this.parent.enableRtl ? 'right:' : 'left:') + ((this.parent.enableRtl ? rangeCollection[i].left : rangeCollection[i].left + rangeCollection[i].width - 5) + "px;\n top: " + Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight) / 2) + "px; height: " + (height + 1) + "px;\n border-left: 0px;\n z-index: " + ((this.parent.viewType === 'ProjectView') ? currentRecord.childRecords.length > 1 ? currentRecord.childRecords.length + 1 : currentRecord.childRecords.length : 6)) }); parentDiv.appendChild(leftDiv); parentDiv.appendChild(rightDiv); this.rangeViewContainer.appendChild(parentDiv); } this.parent.ganttChartModule.chartBodyContent.appendChild(this.rangeViewContainer); }; /** * @returns {void} . * @private */ GanttChart.prototype.renderTimelineContainer = function () { this.chartTimelineContainer = createElement('div', { className: cls.timelineHeaderContainer }); if (this.parent.enableRtl) { this.chartTimelineContainer.style.borderLeftWidth = '1px'; this.chartTimelineContainer.style.borderRightWidth = '0px'; } this.chartTimelineContainer.setAttribute('role', 'presentation'); this.chartElement.appendChild(this.chartTimelineContainer); }; /** * initiate chart container * * @returns {void} . */ GanttChart.prototype.renderBodyContainers = function () { this.chartBodyContainer = createElement('div', { className: cls.chartBodyContainer }); if (this.parent.enableHover) { this.chartBodyContainer.classList.add('e-chart-row-hover'); } this.chartElement.appendChild(this.chartBodyContainer); this.scrollElement = createElement('div', { className: cls.chartScrollElement + ' ' + cls.scrollContent, styles: 'position:relative;' }); this.chartBodyContainer.appendChild(this.scrollElement); this.chartBodyContent = createElement('div', { className: cls.chartBodyContent, styles: 'position:relative; overflow:hidden ' }); if (this.parent.virtualScrollModule && this.parent.enableVirtualization || this.parent.enableTimelineVirtualization) { this.parent.ganttChartModule.virtualRender.renderWrapper(); } else { this.scrollElement.appendChild(this.chartBodyContent); } // this.parent.chartRowsModule.createChartTable(); this.scrollObject = new ChartScroll(this.parent); //this.scrollObject.setWidth(this.chartProperties.width); var toolbarHeight = 0; if (!isNullOrUndefined(this.parent.toolbarModule) && !isNullOrUndefined(this.parent.toolbarModule.element)) { toolbarHeight = this.parent.toolbarModule.element.offsetHeight; } this.scrollObject. setHeight(this.parent.ganttHeight - this.chartTimelineContainer.offsetHeight - toolbarHeight); }; /** * @returns {void} . * @private */ GanttChart.prototype.updateWidthAndHeight = function () { //empty row height var emptydivHeight = 36; var emptyHeight = this.parent.contentHeight === 0 ? this.parent.flatData.length > 1 ? emptydivHeight : 0 : this.parent.contentHeight; var contentElement = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0]; if (emptyHeight >= contentElement['offsetHeight'] || this.parent.height === 'auto' || (contentElement['offsetHeight'] - emptyHeight) < emptydivHeight) { this.chartBodyContent.style.height = formatUnit(emptyHeight); } else { var scrollHeight = this.parent.element.getElementsByClassName('e-chart-rows-container')[0]['offsetHeight']; if (contentElement['offsetHeight'] >= scrollHeight) { this.chartBodyContent.style.height = contentElement['offsetHeight'] - 17 + 'px'; } else { this.chartBodyContent.style.height = contentElement['offsetHeight'] + 'px'; } } //let element: HTMLElement = this.chartTimelineContainer.querySelector('.' + cls.timelineHeaderTableContainer); // Handled zoomtofit horizontal scrollbar hide while performing different zooming levels in browser at virtualtimeline mode-Task(919516) if (this.parent.timelineModule.isZoomToFit && this.parent.enableTimelineVirtualization) { this.chartBodyContent.style.width = (this.parent.enableTimelineVirtualization && (this.parent.timelineModule.totalTimelineWidth > this.parent.element.offsetWidth * 3)) ? formatUnit(this.parent.element.offsetWidth * 3) : formatUnit(this.parent.timelineModule.totalTimelineWidth - this.parent.timelineModule['clientWidthDifference']); } else { this.chartBodyContent.style.width = (this.parent.enableTimelineVirtualization && (this.parent.timelineModule.totalTimelineWidth > this.parent.element.offsetWidth * 3)) ? formatUnit(this.parent.element.offsetWidth * 3) : formatUnit(this.parent.timelineModule.totalTimelineWidth); } // To handle the width of chartbody element after zoomtofit action followed by vertical scroll actions if (this.parent.timelineModule.isZoomedToFit && this.parent.enableVirtualization) { var clientWidth = Math.abs(this.parent.timelineModule.totalTimelineWidth - this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0].clientWidth); this.parent.ganttChartModule.chartBodyContent.style.width = formatUnit(this.parent.timelineModule.totalTimelineWidth - clientWidth); } this.setVirtualHeight(); this.parent.notify('updateHeight', {}); this.parent.updateGridLineContainerHeight(); this.updateLastRowBottomWidth(); }; GanttChart.prototype.setVirtualHeight = function () { if (this.parent.virtualScrollModule && this.parent.enableVirtualization) { var wrapper = getValue('virtualTrack', this.parent.ganttChartModule.virtualRender); wrapper.style.height = this.parent.treeGrid.element.getElementsByClassName('e-virtualtrack')[0].style.height; var wrapper1 = getValue('wrapper', this.parent.ganttChartModule.virtualRender); var treegridVirtualHeight = this.parent.treeGrid.element.getElementsByClassName('e-virtualtable')[0].style.transform; var virtualTable = document.getElementsByClassName('e-virtualtable')[1].style.transform; if (this.parent.enableTimelineVirtualization) { var translateXValue = void 0; // Firefox whitespace issue, Firefox omit y axis value if both axis values are 0 and returns translate(0px)-Task(888356) if (treegridVirtualHeight === 'translate(0px)' && navigator.userAgent.includes('Firefox')) { treegridVirtualHeight = 'translate(0px, 0px)'; } if (virtualTable !== '') { translateXValue = virtualTable.match(/translate.*\((.+)\)/)[1].split(', ')[0]; } else { var chartTransform = this.parent.ganttChartModule.scrollElement.getElementsByClassName('e-virtualtable')[0].style.transform; translateXValue = chartTransform.match(/translate.*\((.+)\)/)[1].split(', ')[0]; } var translateYValue = treegridVirtualHeight.match(/translate.*\((.+)\)/)[1].split(', ')[1]; wrapper1.style.transform = "translate(" + translateXValue + ", " + translateYValue + ")"; } else { wrapper1.style.transform = treegridVirtualHeight; } } }; /** * Method to update bottom border for chart rows * * @returns {void} . */ GanttChart.prototype.updateLastRowBottomWidth = function () { if (this.parent.currentViewData.length > 0 && this.parent.height !== 'auto') { var expandedRecords = this.parent.virtualScrollModule && this.parent.enableVirtualization ? this.parent.currentViewData : this.parent.expandedRecords; var lastExpandedRow = expandedRecords[expandedRecords.length - 1]; var lastExpandedRowIndex = this.parent.currentViewData.indexOf(lastExpandedRow); var lastRow = this.parent.getRowByIndex(lastExpandedRowIndex); var table = this.parent.chartRowsModule.ganttChartTableBody; if (table.querySelectorAll('.e-chart-row-cell.e-chart-row-border.e-lastrow')) { removeClass(table.querySelectorAll('.e-chart-row-cell.e-chart-row-border.e-lastrow'), 'e-lastrow'); } if (this.chartBodyContent.clientHeight < this.chartBodyContainer.clientHeight) { if (lastRow) { addClass(lastRow.querySelectorAll('td'), 'e-lastrow'); var emptydivHeight = 36; var emptyHeight = this.parent.contentHeight === 0 ? this.parent.flatData.length > 1 ? emptydivHeight : 0 : this.parent.contentHeight; var contentElement = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0]; if (emptyHeight >= contentElement['offsetHeight'] || (contentElement['offsetHeight'] - emptyHeight) < emptydivHeight) { this.chartBodyContent.style.height = formatUnit(emptyHeight); } else { var scrollHeight = this.parent.element.getElementsByClassName('e-chart-rows-container')[0]['offsetHeight']; if (contentElement['offsetHeight'] >= scrollHeight) { this.chartBodyContent.style.height = contentElement['offsetHeight'] - 17 + 'px'; } else { this.chartBodyContent.style.height = contentElement['offsetHeight'] + 'px'; } } } } } }; GanttChart.prototype.removeEventListener = function () { if (this.parent.isDestroyed) { return; } this.parent.off('renderPanels', this.renderChartContainer); this.parent.off('recordsUpdated', this.renderChartElements); this.parent.off('dataReady', this.renderInitialContents); this.parent.off('tree-grid-created', this.renderChartContents); this.parent.off('destroy', this.destroy); }; /** * Click event handler in chart side * * @param {PointerEvent} e . * @returns {void} . */ GanttChart.prototype.ganttChartMouseDown = function (e) { var cancel = false; if (e.type === 'touchstart' && e instanceof TouchEvent && e.touches && e.touches.length === 2) { // Calculate initial distance between two Pinch touch points this.initPinchDistance = this.calculatePinchDistance(e.touches[0], e.touches[1]); this.isPinching = true; } if (this.parent.allowTaskbarDragAndDrop && this.parent.editModule && this.parent.editSettings.allowTaskbarEditing && !this.isPinching) { var editAction = this.parent.editModule.taskbarEditModule['getTaskBarAction'](e); if (editAction === 'ChildDrag' || editAction === 'ParentDrag' || editAction === 'MilestoneDrag' || editAction === 'ManualParentDrag') { var args = { cancel: cancel, data: this.getRecordByTaskBar(e.target), target: e.target, chartRow: closest(e.target, 'tr') }; this.parent.trigger('rowDragStartHelper', args); cancel = args['cancel']; } } if (!cancel && !this.isPinching) { if (e.which !== 3 && this.parent.editSettings.allowTaskbarEditing) { this.parent.notify('chartMouseDown', e); this.parent.element.tabIndex = 0; } var isTaskbarEdited = false; if (this.parent.editSettings.allowTaskbarEditing && (this.parent.element.querySelector('.e-left-resize-gripper') || this.parent.element.querySelector('.e-left-connectorpoint-outer-div'))) { isTaskbarEdited = true; } if (!isTaskbarEdited || e.button === 2) { if (this.parent.editSettings.allowEditing && this.parent.treeGrid.element.getElementsByClassName('e-editedbatchcell').length > 0) { this.parent.treeGrid.endEdit(); } } } }; GanttChart.prototype.calculatePinchDistance = function (touch1, touch2) { var dx = touch2.clientX - touch1.clientX; var dy = touch2.clientY - touch1.clientY; return Math.sqrt(dx * dx + dy * dy); }; GanttChart.prototype.ganttChartMouseClick = function (e) { if (this.parent.autoFocusTasks) { this.scrollToTarget(e); /** Scroll to task */ } this.parent.notify('chartMouseClick', e); }; GanttChart.prototype.ganttChartMouseUp = function (e) { if (e.type === 'touchend') { this.initPinchDistance = null; this.isPinching = false; var resizeCheck = this.parent.ganttChartModule.chartBodyContainer.querySelector('.e-taskbar-resize-div'); if (!isNullOrUndefined(resizeCheck)) { resizeCheck.remove(); } var Check = this.parent.ganttChartModule.chartBodyContainer.querySelector('.e-clone-taskbar') || this.parent.chartPane.querySelector('.e-clone-taskbar'); if (!isNullOrUndefined(Check)) { var clonetbody = Check.parentElement; var cloneTable = clonetbody.parentElement; cloneTable.remove(); } var falseline = this.parent.ganttChartModule.chartBodyContainer.querySelector('.e-gantt-false-line'); if (!isNullOrUndefined(falseline)) { this.parent.editModule.taskbarEditModule.removeFalseLine(true); } } if (this.parent.editSettings.allowTaskbarEditing) { this.parent.notify('chartMouseUp', e); } if (!this.parent.editSettings.allowEditing) { var isTaskbarEdited = false; if (this.parent.editSettings.allowTaskbarEditing && getValue('editModule.taskbarEditModule.isMouseDragged', this.parent) && getValue('editModule.taskbarEditModule.taskBarEditAction', this.parent)) { isTaskbarEdited = true; } if (!isTaskbarEdited) { /** Expand/collapse action */ var target = e.target; var isOnTaskbarElement = e.target.classList.contains(cls.taskBarMainContainer) || closest(e.target, '.' + cls.taskBarMainContainer); if (closest(target, '.e-gantt-parent-taskbar') && !this.parent.editSettings.allowEditing && !this.parent.isAdaptive) { this.chartExpandCollapseRequest(e); } else if (!isOnTaskbarElement && this.parent.autoFocusTasks) { this.scrollToTarget(e); /** Scroll to task */ } } } }; /** * * @param {PointerEvent} e . * @returns {void} . */ GanttChart.prototype.scrollToTarget = function (e) { var row = closest(e.target, 'tr'); if (row && this.parent.element.contains(row) && (this.parent.element.querySelectorAll('.e-chart-rows-container')[0].contains(e.target) || this.parent.element.querySelectorAll('.e-gridcontent')[0].contains(e.target)) && this.parent.currentViewData.length > 0) { var rowIndex = getValue('rowIndex', closest(e.target, 'tr')); var dateObject = this.parent.currentViewData[rowIndex].ganttProperties.startDate; var dateObjLeft = this.parent.currentViewData[rowIndex].ganttProperties.left; if (!isNullOrUndefined(dateObject)) { var left = !this.parent.enableTimelineVirtualization ? this.parent.dataOperation.getTaskLeft(dateObject, false) : {}; if (this.parent.autoFocusTasks) { if (this.parent.enableTimelineVirtualization) { this.updateScrollLeft(dateObjLeft); } else { this.updateScrollLeft(left); } } } } }; /** * To focus selected task in chart side * * @param {number} scrollLeft . * @returns {void} . * @private */ GanttChart.prototype.updateScrollLeft = function (scrollLeft) { scrollLeft = scrollLeft > 0 ? scrollLeft : 0; scrollLeft = this.scrollElement.scrollWidth <= scrollLeft ? this.scrollElement.scrollWidth : scrollLeft; if ((this.scrollElement.offsetWidth + this.parent.ganttChartModule.scrollElement.scrollLeft) < scrollLeft || (this.scrollElement.scrollLeft > scrollLeft)) { this.scrollObject.setScrollLeft(scrollLeft - 50, this.parent.enableRtl ? -1 : 0); } // this.parent.ganttChartModule.scrollObject.updateLeftPosition(); }; /** * Method trigger while perform mouse up action. * * @param {PointerEvent} e . * @returns {void} * @private */ GanttChart.prototype.mouseUp = function (e) { if (e.type === 'touchend') { this.initPinchDistance = null; this.isPinching = false; } if (!isNullOrUndefined(this.parent.editModule) && !isNullOrUndefined(this.parent.editModule.taskbarEditModule)) { this.parent.editModule.taskbarEditModule.removeFalseLine(false); } var resizeCheck = this.parent.element.querySelector('.e-taskbar-resize-div'); if (!isNullOrUndefined(resizeCheck)) { resizeCheck.remove(); } if (this.parent.allowTaskbarDragAndDrop && this.parent.editModule && this.parent.editModule.taskbarEditModule) { this.parent.editModule.taskbarEditModule['previousLeftValue'] = 0; } if (this.parent.allowRowDragAndDrop) { var ganttDragElemet = this.parent.element.querySelector('.e-ganttdrag'); if (ganttDragElemet) { ganttDragElemet.remove(); } } if (!this.isGanttElement) { this.parent.notify('chartMouseUp', e); } this.isGanttElement = false; }; /** * Method trigger while perform mouse up action. * * @param {PointerEvent} e . * @returns {void} . * @private */ GanttChart.prototype.documentMouseUp = function (e) { if (e.type === 'touchend') { this.initPinchDistance = null; this.isPinching = false; this.previousPinchDistance = 0; } this.isGanttElement = true; if (e.target.classList.contains('e-treegridexpand') || e.target.classList.contains('e-treegridcollapse')) { if (getValue('isEditCollapse', this.parent.treeGrid) === true) { setValue('isEditCollapse', false, this.parent.treeGrid); } } if (this.parent.allowRowDragAndDrop) { var ganttDragElemet = this.parent.element.querySelector('.e-ganttdrag'); if (ganttDragElemet) { ganttDragElemet.remove(); } } if (this.parent.isDestroyed || e.which === 3) { return; } var resizeCheck = this.parent.ganttChartModule.chartBodyContainer.querySelector('.e-taskbar-resize-div'); if (!isNullOrUndefined(resizeCheck)) { resizeCheck.remove(); } var Check = this.parent.element.getElementsByClassName('e-clone-taskbar')[0]; if (!isNullOrUndefined(Check)) { var clonetbody = Check.parentElement; var cloneTable = clonetbody.parentElement; cloneTable.remove(); } var isTaskbarEdited = false; if (this.parent.editSettings.allowTaskbarEditing && getValue('editModule.taskbarEditModule.isMouseDragged', this.parent) && getValue('editModule.taskbarEditModule.taskBarEditAction', this.parent)) { isTaskbarEdited = true; } this.parent.notify('chartMouseUp', e); if (this.parent.showActiveElement) { this.parent.showIndicator = true; if (this.focusedElement && !e.target.classList.contains('e-split-bar')) { this.focusedElement.tabIndex = this.focusedElement.tabIndex === 0 ? -1 : this.focusedElement.tabIndex; removeClass([this.focusedElement], 'e-active-container'); } } if (!isTaskbarEdited) { /** Expand/collapse action */ var target = e.target; var isOnTaskbarElement = e.target.classList.contains(cls.taskBarMainContainer) || closest(e.target, '.' + cls.taskBarMainContainer); if (closest(target, '.e-gantt-parent-taskbar') && !this.parent.editSettings.allowEditing) { this.chartExpandCollapseRequest(e); } else if (!isOnTaskbarElement && this.parent.autoFocusTasks) { this.scrollToTarget(e); /** Scroll to task */ } } if (this.parent.editModule && this.parent.editModule.taskbarEditModule) { this.parent.editModule.taskbarEditModule.removeFalseLine(true); } if (!isTaskbarEdited && !isNullOrUndefined(this.parent.onTaskbarClick)) { var target = e.target; var taskbarElement = closest(target, '.e-gantt-parent-taskbar,.e-gantt-child-taskbar,.e-gantt-milestone'); if (taskbarElement) { this.onTaskbarClick(e, target, taskbarElement); } } }; /** * This event triggered when click on taskbar element * * @param {PointerEvent | KeyboardEventArgs} e . * @param {EventTarget} target . * @param {Element} taskbarElement . * @returns {void} */ GanttChart.prototype.onTaskbarClick = function (e, target, taskbarElement) { var rowIndex; var chartRow = closest(target, 'tr'); if (!isNullOrUndefined(chartRow)) { rowIndex = getValue('rowIndex', chartRow); } var data = this.getRecordByTarget(e); var args = { data: data, taskbarElement: taskbarElement, rowIndex: rowIndex, target: target }; this.parent.trigger('onTaskbarClick', args); }; /** * Method trigger while perform mouse leave action. * * @param {PointerEvent} e . * @returns {void} . * @private */ GanttChart.prototype.ganttChartLeave = function (e) { if (this.parent.editSettings.allowTaskbarEditing) { this.parent.notify('chartMouseLeave', e); } }; /** * Method trigger while perform mouse move action. * * @param {PointerEvent} e . * @returns {void} . * @private */ GanttChart.prototype.ganttChartMove = function (e) { if (e.type === 'touchmove' && this.isPinching === true && e instanceof TouchEvent && e.touches && e.touches.length === 2) { // Calculate current distance between two touch points var currentPinchDistance = this.calculatePinchDistance(e.touches[0], e.touches[1]); if (Math.abs(this.previousPinchDistance - currentPinchDistance) > 15) { if (currentPinchDistance > this.previousPinchDistance) { // Pinch out detected - Perform Zoom in this.parent.timelineModule.processZooming(true); } else if (currentPinchDistance < this.previousPinchDistance) { // Pinch in detected - Perform Zoom out this.parent.timelineModule.processZooming(false); } this.previousPinchDistance = currentPinchDistance; } } if (this.parent.editSettings.allowTaskbarEditing && this.isPinching === false) { if (!this.parent.enableRtl && this.parent.element.getElementsByClassName('e-clone-taskbar').length > 0) { var xValue = void 0; if (e.type === 'touchmove' || e.type === 'touchstart' || e.type === 'touchend') { xValue = e['changedTouches'][0].pageX; } else { xValue = e.pageX; } if (xValue <= this.parent.getOffsetRect(this.parent.ganttChartModule.chartElement).left) { return; } } this.parent.notify('chartMouseMove', e); if (!isNullOrUndefined(this.parent.taskFields.dependency) && this.parent.connectorLineEditModule) { this.parent.connectorLineEditModule.updateConnectorLineEditElement(e); } } }; /** * Method trigger while perform right click action. * * @param {PointerEvent} e . * @returns {void} . * @private */ GanttChart.prototype.contextClick = function (e) { if (this.parent.allowFiltering && this.parent.filterModule) { this.parent.filterModule.closeFilterOnContextClick(e.srcElement); } if (this.parent.element.querySelectorAll('.e-focused').length > 0) { this.parent.element.querySelectorAll('.e-focused').forEach(function (el) { el.classList.remove('e-focused'); }); } if (this.parent.allowTaskbarDragAndDrop) { var Check = this.parent.chartPane.querySelector('.e-clone-taskbar'); if (!isNullOrUndefined(Check)) { var clonetbody = Check.parentElement; var cloneTable = clonetbody.parentElement; cloneTable.remove(); } } }; /** * Method to trigger while perform mouse move on Gantt. * * @param {PointerEvent} e . * @returns {void} . * @private */ GanttChart.prototype.mouseMoveHandler = function (e) { if ((this.parent.flatData.length || e.target.classList.contains('e-header-cell-label') || e.target.classList.contains('e-headercell')) && !isNullOrUndefined(this.parent.onMouseMove)) { var target = e.target; var args = { originalEvent: e }; var element = closest(target, '.e-chart-row-cell,.e-connector-line-container,' + '.e-event-markers,.e-header-cell-label,.e-rowcell,.e-headercell,.e-indicator-span'); if (element) { var rowData = void 0; var rowElement = closest(target, '.e-rowcell,.e-chart-row-cell'); var columnElement = closest(target, '.e-rowcell,.e-headercell'); if (rowElement) { rowData = this.parent.ganttChartModule.getRecordByTarget(e); args.data = rowData; } if (columnElement) { var cellIndex = getValue('cellIndex', columnElement); args.column = this.parent.treeGrid.columns[cellIndex]; } if (closest(target, '.e-indicator-span')) { var index = 0; var indicators = rowData.ganttProperties.indicators; if (indicators.length > 1) { for (index = 0; index < indicators.length; index++) { if (indicators[index].name === (element.innerText).trim()) { break; } } } args.indicator = indicators[index]; } if (closest(target, '.e-connector-line-container')) { var obj = {}; obj.target = element; args.predecessor = this.parent.tooltipModule.getPredecessorTooltipData(obj); } if (closest(target, '.e-event-markers')) { var obj = {}; obj.target = element; args.eventMarkers = this.parent.tooltipModule.getMarkerTooltipData(obj); } if (target.classList.contains('e-header-cell-label')) { args.date = new Date(target.dataset.content); } } this.parent.trigger('onMouseMove', args); } }; /** * Double click handler for chart * * @param {PointerEvent} e . * @returns {void} . */ GanttChart.prototype.doubleClickHandler = function (e) { var target = e.target; var row = closest(target, 'tr'); var rowIndex = getValue('rowIndex', row); var rowData = this.parent.ganttChartModule.getRecordByTarget(e); if (this.parent.editSettings.allowEditing && this.parent.treeGrid.element.getElementsByClassName('e-editedbatchcell').length > 0) { this.parent.treeGrid.endEdit(); } this.parent.notify('chartDblClick', e); var args = { row: row, rowData: rowData, rowIndex: rowIndex, target: target }; this.recordDoubleClick(args); }; /** * To trigger record double click event. * * @param {RecordDoubleClickEventArgs} args . * @returns {void} . * @private */ GanttChart.prototype.recordDoubleClick = function (args) { this.parent.trigger('recordDoubleClick', args); }; /** * @param {PointerEvent | KeyboardEventArgs} e . * @returns {IGanttData} . * @private */ GanttChart.prototype.getRecordByTarget = function (e) { var ganttData; var row = closest(e.target, 'div.' + cls.taskBarMainContainer); if (!isNullOrUndefined(row)) { var id = row.getAttribute('rowUniqueId'); ganttData = this.parent.getRecordByID(id); } else { row = closest(e.target, 'tr'); if (row) { var rowIndex = getValue('rowIndex', closest(e.target, 'tr')); ganttData = this.parent.currentViewData[rowIndex]; } } return ganttData; }; /** * To get gantt chart row elements * * @returns {NodeListOf<Element>} . * @private */ GanttChart.prototype.getChartRows = function () { if (document.getElementById(this.parent.element.id + 'GanttTaskTableBody') !== null) { return document.getElementById(this.parent.element.id + 'GanttTaskTableBody').querySelectorAll('.e-chart-row'); } else { return null; } }; /** * Expand Collapse operations from gantt chart side * * @param {PointerEvent} e . * @returns {void} . * @private */ GanttChart.prototype.chartExpandCollapseRequest = function (e) { if (this.parent.enableMultiTaskbar) { return; } var target = e.target; var parentElement = closest(target, '.e-gantt-parent-taskbar'); var record = this.getRecordByTarget(e); var chartRow = closest(target, 'tr'); var rowIndex = getValue('rowIndex', chartRow); var gridRow = this.parent.treeGrid.getRows()[rowIndex]; var args = { data: record, gridRow: gridRow, chartRow: chartRow, cancel: false }; this.isExpandCollapseFromChart = true; if (parentElement.classList.contains('e-row-expand')) { this.collapseGanttRow(args); } else if (parentElement.classList.contains('e-row-collapse')) { this.expandGanttRow(args); } }; /** * @returns {void} . * @private */ GanttChart.prototype.reRenderConnectorLines = function () { this.parent.connectorLineModule.dependencyViewContainer.innerHTML = ''; this.parent.connectorLineIds = []; this.parent.updatedConnectorLineCollection = []; this.parent.predecessorModule.createConnectorLinesCollection(); this.parent.connectorLineModule.renderConnectorLines(this.parent.updatedConnectorLineCollection); var criticalModule = this.parent.criticalPathModule; if (this.parent.enableCriticalPath && criticalModule && criticalModule.criticalPathCollection) { criticalModule.criticalConnectorLine(criticalModule.criticalPathCollection, criticalModule.detailPredecessorCollection, true, criticalModule.predecessorCollectionTaskIds); } }; /** * To collapse gantt rows * * @param {object} args . * @param {boolean} isCancel . * @returns {void} . * @private */ GanttChart.prototype.collapseGanttRow = function (args) { var _this = this; this.parent.trigger('collapsing', args, function (arg) { if (_this.isExpandCollapseFromChart && !getValue('cancel', arg)) { _this.collapsedGanttRow(arg); } _this.isExpandCollapseFromChart = false; }); }; /** * @returns {void} . * @param {object} args . * @private */ GanttChart.prototype.collapsedGanttRow = function (args) { var _this = this; var record; if (this.parent.loadChildOnDemand && this.parent.taskFields.hasChildMapping) { record = this.parent.currentViewData.filter(function (item) { return item.ganttProperties[_this.parent.taskFields.id] === args['data'][_this.parent.taskFields.id]; })[0]; } else { record = getValue('data', args); } if ((isNullOrUndefined(args['gridRow']) && this.parent.enableVirtualization) || isNullOrUndefined(args['chartRow'])) { if (record) { record.expanded = false; } return; } if (this.isExpandCollapseFromChart) { this.expandCollapseChartRows('collapse', getValue('chartRow', args), record, null); var idField_1 = this.parent.taskFields.id; if (this.parent.