@syncfusion/ej2-gantt
Version:
Essential JS 2 Gantt Component
1,018 lines • 98 kB
JavaScript
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.