angular-gantt
Version:
Gantt chart component for AngularJS
284 lines (231 loc) • 9.68 kB
JavaScript
(function(){
'use strict';
angular.module('gantt.tree').controller('GanttTreeController', ['$scope', '$filter', 'GanttHierarchy', function($scope, $filter, Hierarchy) {
$scope.rootRows = [];
$scope.getHeader = function() {
return $scope.pluginScope.header;
};
var hierarchy = new Hierarchy();
$scope.pluginScope.$watchGroup(['keepAncestorOnFilterRow', 'enabled'], function(value) {
var keepAncestor = value[0] && value[1];
if (keepAncestor) {
var filterImpl = function(sortedRows, filterRow, filterRowComparator) {
hierarchy.refresh(sortedRows);
var leaves = [];
angular.forEach(sortedRows, function(row) {
var children = hierarchy.children(row);
if (!children || children.length === 0) {
leaves.push(row);
}
});
var filteredLeaves = $filter('filter')(leaves, filterRow, filterRowComparator);
var filterRowKeepAncestor = function(row) {
if (filteredLeaves.indexOf(row) > -1) {
return true;
}
var descendants = hierarchy.descendants(row);
for (var i=0; i < descendants.length; i++) {
if (filteredLeaves.indexOf(descendants[i]) > -1) {
return true;
}
}
return false;
};
return $filter('filter')(sortedRows, filterRowKeepAncestor, filterRowComparator);
};
$scope.gantt.rowsManager.setFilterImpl(filterImpl);
} else {
$scope.gantt.rowsManager.setFilterImpl(false);
}
});
var isVisible = function(row) {
var parentRow = $scope.parent(row);
while (parentRow !== undefined) {
if (parentRow !== undefined && parentRow._collapsed) {
return false;
}
parentRow = $scope.parent(parentRow);
}
return true;
};
var filterRowsFunction = function(rows) {
return rows.filter(function(row) {
return isVisible(row);
});
};
var sortRowsFunction = function(rows) {
var sortedRows = [];
var rootRows = [];
var hasParent = false;
angular.forEach(rows, function(row) {
var rowParent = $scope.parent(row);
if (rowParent === undefined) {
rootRows.push(row);
} else {
hasParent = true;
}
});
var handleChildren = function(row) {
sortedRows.push(row);
var children = $scope.children(row);
if (children !== undefined && children.length > 0) {
var sortedChildren = children.sort(function(a, b) {
return rows.indexOf(a) - rows.indexOf(b);
});
angular.forEach(sortedChildren, function(child) {
handleChildren(child);
});
}
};
angular.forEach(rootRows, function(row) {
handleChildren(row);
});
return sortedRows;
};
$scope.gantt.api.rows.addRowSorter(sortRowsFunction);
$scope.gantt.api.rows.addRowFilter(filterRowsFunction);
$scope.$on('$destroy', function() {
$scope.gantt.api.rows.removeRowSorter(sortRowsFunction);
$scope.gantt.api.rows.removeRowFilter(filterRowsFunction);
});
var refresh = function() {
$scope.rootRows = hierarchy.refresh($scope.gantt.rowsManager.filteredRows);
if ($scope.gantt.rowsManager.filteredRows.length > 0) {
$scope.gantt.api.rows.sort();
$scope.gantt.api.rows.refresh();
}
};
$scope.gantt.api.rows.on.remove($scope, refresh);
$scope.gantt.api.rows.on.add($scope, refresh);
var isRowCollapsed = function(rowId) {
var row;
if (typeof rowId === 'string') {
row = $scope.gantt.rowsManager.rowsMap[rowId];
} else {
row = rowId;
}
if (row === undefined) {
return undefined;
}
if (row._collapsed === undefined) {
return false;
}
return row._collapsed;
};
var expandRow = function(rowId) {
var row;
if (typeof rowId === 'string') {
row = $scope.gantt.rowsManager.rowsMap[rowId];
} else {
row = rowId;
}
if (row === undefined) {
return;
}
var rowScope = $scope.nodeScopes[row.model.id];
if (rowScope.collapsed) {
rowScope.toggle();
}
};
var collapseRow = function(rowId) {
var row;
if (typeof rowId === 'string') {
row = $scope.gantt.rowsManager.rowsMap[rowId];
} else {
row = rowId;
}
if (row === undefined) {
return;
}
var rowScope = $scope.nodeScopes[row.model.id];
if (!rowScope.collapsed) {
rowScope.toggle();
}
};
var getHierarchy = function() {
return hierarchy;
};
$scope.getHeaderContent = function() {
return $scope.pluginScope.headerContent;
};
$scope.gantt.api.registerMethod('tree', 'refresh', refresh, this);
$scope.gantt.api.registerMethod('tree', 'isCollapsed', isRowCollapsed, this);
$scope.gantt.api.registerMethod('tree', 'expand', expandRow, this);
$scope.gantt.api.registerMethod('tree', 'collapse', collapseRow, this);
$scope.gantt.api.registerEvent('tree', 'collapsed');
$scope.gantt.api.registerMethod('tree', 'getHierarchy', getHierarchy, this);
$scope.$watchCollection('gantt.rowsManager.filteredRows', function() {
refresh();
});
$scope.children = function(row) {
if (row === undefined) {
return $scope.rootRows;
}
return hierarchy.children(row);
};
$scope.parent = function(row) {
return hierarchy.parent(row);
};
$scope.nodeScopes = {};
}]).controller('GanttUiTreeController', ['$scope', function($scope) {
var collapseAll = function() {
$scope.collapseAll();
};
var expandAll = function() {
$scope.expandAll();
};
$scope.gantt.api.registerMethod('tree', 'collapseAll', collapseAll, $scope);
$scope.gantt.api.registerMethod('tree', 'expandAll', expandAll, $scope);
}]).controller('GanttTreeNodeController', ['$scope', function($scope) {
$scope.$parent.nodeScopes[$scope.row.model.id] = $scope;
$scope.$on('$destroy', function() {
delete $scope.$parent.nodeScopes[$scope.row.model.id];
});
$scope.$watch('children(row)', function(newValue) {
if (newValue) {
// Children rows may have been filtered out
// So we need to filter the raw hierarchy before displaying children in tree.
var visibleRows = $scope.row.rowsManager.filteredRows;
var filteredChildrenRows = [];
for (var i=0; i < newValue.length; i++) {
var childRow = newValue[i];
if (visibleRows.indexOf(childRow) > -1) {
filteredChildrenRows.push(childRow);
}
}
$scope.$parent.childrenRows = filteredChildrenRows;
} else {
$scope.$parent.childrenRows = newValue;
}
});
$scope.isCollapseDisabled = function(){
return !$scope.$parent.childrenRows || $scope.$parent.childrenRows.length === 0;
};
$scope.getValue = function() {
return $scope.row.model.name;
};
$scope.getRowContent = function() {
if ($scope.row.model.content !== undefined) {
return $scope.row.model.content;
}
if ($scope.pluginScope.content !== undefined) {
return $scope.pluginScope.content;
}
var content = $scope.row.rowsManager.gantt.options.value('rowContent');
if (content === undefined) {
content = '{{row.model.name}}';
}
return content;
};
$scope.$watch('collapsed', function(newValue) {
if ($scope.$modelValue._collapsed !== newValue) {
var oldValue = $scope.$modelValue._collapsed;
$scope.$modelValue._collapsed = newValue; // $modelValue contains the Row object
if (oldValue !== undefined && newValue !== oldValue) {
$scope.gantt.api.tree.raise.collapsed($scope, $scope.$modelValue, newValue);
$scope.gantt.api.rows.refresh();
}
}
});
}]);
}());