angular2-data-table
Version:
angular2-data-table is a Angular2 component for presenting large and complex data.
140 lines • 5.67 kB
JavaScript
;
/**
* This object contains the cache of the various row heights that are present inside
* the data table. Its based on Fenwick tree data structure that helps with
* querying sums that have time complexity of log n.
*
* Fenwick Tree Credits: http://petr-mitrichev.blogspot.com/2013/05/fenwick-tree-range-updates.html
* https://github.com/mikolalysenko/fenwick-tree
*
*/
var RowHeightCache = (function () {
function RowHeightCache() {
/**
* Tree Array stores the cumulative information of the row heights to perform efficient
* range queries and updates. Currently the tree is initialized to the base row
* height instead of the detail row height.
*/
this.treeArray = [];
}
/**
* Clear the Tree array.
*/
RowHeightCache.prototype.clearCache = function () {
this.treeArray = [];
};
/**
* Initialize the Fenwick tree with row Heights.
*
* @param rows The array of rows which contain the expanded status.
* @param rowHeight The row height.
* @param detailRowHeight The detail row height.
*/
RowHeightCache.prototype.initCache = function (rows, rowHeight, detailRowHeight) {
if (isNaN(rowHeight)) {
throw new Error("Row Height cache initialization failed. Please ensure that 'rowHeight' is a\n valid number value: (" + rowHeight + ") when 'scrollbarV' is enabled.");
}
// Add this additional guard in case detailRowHeight is set to 'auto' as it wont work.
if (isNaN(detailRowHeight)) {
throw new Error("Row Height cache initialization failed. Please ensure that 'detailRowHeight' is a\n valid number value: (" + detailRowHeight + ") when 'scrollbarV' is enabled.");
}
var n = rows.length;
this.treeArray = new Array(n);
for (var i = 0; i < n; ++i) {
this.treeArray[i] = 0;
}
for (var i = 0; i < n; ++i) {
var currentRowHeight = rowHeight;
// Add the detail row height to the already expanded rows.
// This is useful for the table that goes through a filter or sort.
if (rows[i] && rows[i].$$expanded === 1) {
currentRowHeight += detailRowHeight;
}
this.update(i, currentRowHeight);
}
};
/**
* Given the ScrollY position i.e. sum, provide the rowIndex
* that is present in the current view port. Below handles edge cases.
*
* @param scrollY - The scrollY position.
* @returns {number} - Index representing the first row visible in the viewport
*/
RowHeightCache.prototype.getRowIndex = function (scrollY) {
if (scrollY === 0)
return 0;
return this.calcRowIndex(scrollY);
};
/**
* When a row is expanded or rowHeight is changed, update the height. This can
* be utilized in future when Angular Data table supports dynamic row heights.
*
*
* @param atRowIndex Update the data at this index row in the grid.
* @param byRowHeight Update by the rowHeight provided.
*/
RowHeightCache.prototype.update = function (atRowIndex, byRowHeight) {
if (!this.treeArray.length) {
throw new Error("Update at index " + atRowIndex + " with value " + byRowHeight + " failed:\n Row Height cache not initialized.");
}
var n = this.treeArray.length;
atRowIndex |= 0;
while (atRowIndex < n) {
this.treeArray[atRowIndex] += byRowHeight;
atRowIndex |= (atRowIndex + 1);
}
};
/**
* Range Sum query from 1 to the rowIndex
*
* @param atIndex The row index until which the total height needs to be obtained.
* @returns {number} The total height from row 1 to the rowIndex.
*/
RowHeightCache.prototype.query = function (atIndex) {
if (!this.treeArray.length) {
throw new Error("query at index " + atIndex + " failed: Fenwick tree array not initialized.");
}
var sum = 0;
atIndex |= 0;
while (atIndex >= 0) {
sum += this.treeArray[atIndex];
atIndex = (atIndex & (atIndex + 1)) - 1;
}
return sum;
};
/**
* Find the total height between 2 row indexes
* @param atIndexA The row index from
* @param atIndexB The row index to
* @returns {number} total pixel height between 2 row indexes.
*/
RowHeightCache.prototype.queryBetween = function (atIndexA, atIndexB) {
return this.query(atIndexB) - this.query(atIndexA - 1);
};
/**
* Given the ScrollY position i.e. sum, provide the rowIndex
* that is present in the current view port.
*
* @param sum - The scrollY position.
* @returns {number} - Index representing the first row visible in the viewport
*/
RowHeightCache.prototype.calcRowIndex = function (sum) {
if (!this.treeArray.length)
return 0;
var pos = -1;
var dataLength = this.treeArray.length;
// Get the highest bit for the block size.
var highestBit = Math.pow(2, dataLength.toString(2).length - 1);
for (var blockSize = highestBit; blockSize !== 0; blockSize >>= 1) {
var nextPos = pos + blockSize;
if (nextPos < dataLength && sum >= this.treeArray[nextPos]) {
sum -= this.treeArray[nextPos];
pos = nextPos;
}
}
return pos + 1;
};
return RowHeightCache;
}());
exports.RowHeightCache = RowHeightCache;
//# sourceMappingURL=row-height-cache.js.map