function SaikuTableRenderer(data, options) {
this._data = data;
this._options = _.extend({}, SaikuRendererOptions, options);
}
SaikuTableRenderer.prototype.render = function(data, options) {
var self = this;
if (data) {
this._data = data;
}
if (options) {
this._options = _.extend({}, SaikuRendererOptions, options);
}
if (typeof this._data == "undefined") {
return;
}
if (this._data != null && this._data.error != null) {
return;
}
if (this._data == null || (this._data.cellset && this._data.cellset.length === 0)) {
return;
}
if (this._options.htmlObject) {
// $(this._options.htmlObject).stickyTableHeaders("destroy");
// in case we have some left over scrollers
if (self._options.hasOwnProperty('batch')) {
$(self._options.htmlObject).parent().parent().unbind('scroll');
}
_.defer(function(that) {
if (self._options.hasOwnProperty('batch') && !self._options.hasOwnProperty('batchSize')) {
self._options['batchSize'] = 1000;
}
var html = self.internalRender(self._data, self._options);
$(self._options.htmlObject).html(html);
// $(self._options.htmlObject).stickyTableHeaders( { container: self._options.htmlObject.parent().parent(), fixedOffset: self._options.htmlObject.parent().parent().offset().top });
_.defer(function(that) {
if (self._options.hasOwnProperty('batch') && self._options.hasBatchResult) {
var batchRow = 0;
var batchIsRunning = false;
var batchIntervalSize = self._options.hasOwnProperty('batchIntervalSize') ? self._options.batchIntervalSize : 20;
var batchIntervalTime = self._options.hasOwnProperty('batchIntervalTime') ? self._options.batchIntervalTime : 20;
var len = self._options.batchResult.length;
var batchInsert = function() {
// maybe add check for reach table bottom - ($('.workspace_results').scrollTop() , $('.workspace_results table').height()
if (!batchIsRunning && len > 0 && batchRow < len) {
batchIsRunning = true;
var batchContent = "";
var startb = batchRow;
for (var i = 0; batchRow < len && i < batchIntervalSize ; i++, batchRow++) {
batchContent += self._options.batchResult[batchRow];
}
if (batchRow > startb) {
$(self._options.htmlObject).append( $(batchContent));
}
batchIsRunning = false;
}
if (batchRow >= len) {
$(self._options.htmlObject).parent().parent().unbind('scroll');
}
};
var lazyBatchInsert = _.debounce(batchInsert, batchIntervalTime);
$(self._options.htmlObject).parent().parent().scroll(function () {
lazyBatchInsert();
});
}
});
return html;
});
} else {
var html = this.internalRender(this._data, self._options);
return html;
}
};
SaikuTableRenderer.prototype.clear = function(data, options) {
var self = this;
if (this._options && this._options.htmlObject && this._options.hasOwnProperty('batch')) {
$(self._options.htmlObject).parent().parent().unbind('scroll');
}
};
SaikuTableRenderer.prototype.processData = function(data, options) {
this._hasProcessed = true;
};
function genTotalDataCells(currentIndex, cellIndex, scanSums, scanIndexes, lists) {
var contents = '';
var lists = lists[ROWS];
for (var i = scanSums.length - 1; i >= 0; i--) {
if (currentIndex == scanSums[i]) {
var currentListNode = lists[i][scanIndexes[i]];
for (var m = 0; m < currentListNode.cells.length; m++)
contents += '
' + currentListNode.cells[m][cellIndex].value + ' | ';
scanIndexes[i]++;
if (scanIndexes[i] < lists[i].length)
scanSums[i] += lists[i][scanIndexes[i]].width;
}
}
return contents;
}
function genTotalHeaderCells(currentIndex, bottom, scanSums, scanIndexes, lists, wrapContent) {
var contents = '';
for (var i = bottom; i >= 0; i--) {
if (currentIndex == scanSums[i]) {
var currentListNode = lists[i][scanIndexes[i]];
var cssClass;
if (i == 0 && bottom == 1)
cssClass = "col";
else if (i == bottom)
cssClass = "col_total_corner";
else if (i == bottom - 1 && currentListNode.captions)
cssClass = "col_total_first";
else cssClass = "col_null";
for (var m = 0; m < currentListNode.cells.length; m++) {
var text = ' ';
if (bottom == lists.length - 1) {
if (currentListNode.captions) {
text = lists[i][scanIndexes[i]].captions[m];
}
if (i == 0 && scanIndexes[i] == 0) {
if (currentListNode.captions)
text += " ";
else text = "";
text += (wrapContent ? "Grand Total" : "Grand Total");
}
}
contents += ''
+ (wrapContent ? ' ' + text + ' ' : text ) + ' | ';
}
scanIndexes[i]++;
if (scanIndexes[i] < lists[i].length)
scanSums[i] += lists[i][scanIndexes[i]].width;
}
}
return contents;
}
function totalIntersectionCells(currentIndex, bottom, scanSums, scanIndexes, lists) {
var contents = '';
for (var i = bottom; i >= 0; i--) {
if (currentIndex == scanSums[i]) {
var currentListNode = lists[i][scanIndexes[i]];
var cssClass = "data total";
for (var m = 0; m < currentListNode.cells.length; m++) {
var text = ' ';
contents += '' + text + ' | ';
}
scanIndexes[i]++;
if (scanIndexes[i] < lists[i].length)
scanSums[i] += lists[i][scanIndexes[i]].width;
}
}
return contents;
}
function genTotalHeaderRowCells(currentIndex, scanSums, scanIndexes, totalsLists, wrapContent) {
var colLists = totalsLists[COLUMNS];
var colScanSums = scanSums[COLUMNS];
var colScanIndexes = scanIndexes[COLUMNS];
var bottom = colLists.length - 2;
var contents = '';
for (var i = bottom; i >= 0; i--) {
if (currentIndex == colScanSums[i]) {
for (var m = 0; m < colLists[i][colScanIndexes[i]].cells.length; m++) {
contents += '';
for (var j = 0; j <= bottom; j++) {
var cssClass;
var text = ' ';
if (i == 0 && j == 0)
cssClass = 'row';
else if (i == j + 1)
cssClass = 'row_total_corner';
else if (i == j && colLists[i][colScanIndexes[i]].captions) {
cssClass = 'row_total_first';
} else if (i < j + 1)
cssClass = 'row_total';
else
cssClass = 'row_null';
if (j == bottom ) {
if (colLists[i][colScanIndexes[i]].captions) {
text = colLists[i][colScanIndexes[i]].captions[m];
}
if (i == 0 && colScanIndexes[i] == 0) {
if (colLists[i][colScanIndexes[i]].captions)
text += " ";
else text = "";
text += (wrapContent ? "Grand Total" : "Grand Total");
}
}
contents += '| '
+ (wrapContent ? ' ' + text + ' ' : text ) + ' | ';
}
var scanIndexes = {};
var scanSums = {};
for (var z = 0; z < totalsLists[ROWS].length; z++) {
scanIndexes[z] = 0;
scanSums[z] = totalsLists[ROWS][z][scanIndexes[z]].width;
}
for (var k = 0; k < colLists[i][colScanIndexes[i]].cells[m].length; k++) {
contents += '' + colLists[i][colScanIndexes[i]].cells[m][k].value + ' | ';
contents += totalIntersectionCells(k + 1, totalsLists[ROWS].length - 1, scanSums, scanIndexes, totalsLists[ROWS]);
}
contents += '
';
}
colScanIndexes[i]++;
if (colScanIndexes[i] < colLists[i].length)
colScanSums[i] += colLists[i][colScanIndexes[i]].width;
}
}
return contents;
}
var ROWS = "ROWS";
var COLUMNS = "COLUMNS";
function nextParentsDiffer(data, row, col) {
while (row-- > 0) {
if (data[row][col].properties.uniquename != data[row][col + 1].properties.uniquename)
return true;
}
return false;
}
function topParentsDiffer(data, row, col) {
while (col-- > 0)
if (data[row][col].properties.uniquename != data[row - 1][col].properties.uniquename)
return true;
return false;
}
SaikuTableRenderer.prototype.internalRender = function(allData, options) {
var tableContent = "";
var rowContent = "";
var data = allData.cellset;
var table = data ? data : [];
var colSpan;
var colValue;
var isHeaderLowestLvl;
var isBody = false;
var firstColumn;
var isLastColumn, isLastRow;
var nextHeader;
var processedRowHeader = false;
var lowestRowLvl = 0;
var rowGroups = [];
var batchSize = null;
var batchStarted = false;
var isColHeader = false, isColHeaderDone = false;
var resultRows = [];
var wrapContent = true;
if (options) {
batchSize = options.hasOwnProperty('batchSize') ? options.batchSize : null;
wrapContent = options.hasOwnProperty('wrapContent') ? options.wrapContent : true;
}
var totalsLists = {};
totalsLists[COLUMNS] = allData.rowTotalsLists;
totalsLists[ROWS] = allData.colTotalsLists;
var scanSums = {};
var scanIndexes = {};
var dirs = [ROWS, COLUMNS];
for (var i = 0; i < dirs.length; i++) {
scanSums[dirs[i]] = new Array();
scanIndexes[dirs[i]] = new Array();
}
if (totalsLists[COLUMNS])
for (var i = 0; i < totalsLists[COLUMNS].length; i++) {
scanIndexes[COLUMNS][i] = 0;
scanSums[COLUMNS][i] = totalsLists[COLUMNS][i][scanIndexes[COLUMNS][i]].width;
}
for (var row = 0, rowLen = table.length; row < rowLen; row++) {
var rowShifted = row - allData.topOffset;
colSpan = 1;
colValue = "";
isHeaderLowestLvl = false;
isLastColumn = false;
isLastRow = false;
isColHeader = false;
var headerSame = false;
if (totalsLists[ROWS])
for (var i = 0; i < totalsLists[ROWS].length; i++) {
scanIndexes[ROWS][i] = 0;
scanSums[ROWS][i] = totalsLists[ROWS][i][scanIndexes[ROWS][i]].width;
}
rowContent = "";
if ( row === 0) {
rowContent = "" + rowContent;
}
for (var col = 0, colLen = table[row].length; col < colLen; col++) {
var colShifted = col - allData.leftOffset;
var header = data[row][col];
if (header.type === "COLUMN_HEADER") {
isColHeader = true;
}
// If the cell is a column header and is null (top left of table)
if (header.type === "COLUMN_HEADER" && header.value === "null" && (firstColumn == null || col < firstColumn)) {
rowContent += '| | ';
} // If the cell is a column header and isn't null (column header of table)
else if (header.type === "COLUMN_HEADER") {
if (firstColumn == null) {
firstColumn = col;
}
if (table[row].length == col+1)
isLastColumn = true;
else
nextHeader = data[row][col+1];
if (isLastColumn) {
// Last column in a row...
if (header.value == "null") {
rowContent += ' | ';
} else {
if (totalsLists[ROWS])
colSpan = totalsLists[ROWS][row + 1][scanIndexes[ROWS][row + 1]].span;
rowContent += ''
+ (wrapContent ? ' ' + header.value + ' ' : header.value)
+ ' | ';
}
} else {
// All the rest...
var groupChange = (col > 1 && row > 1 && !isHeaderLowestLvl && col > firstColumn) ?
data[row-1][col+1].value != data[row-1][col].value || data[row-1][col+1].properties.uniquename != data[row-1][col].properties.uniquename
: false;
var maxColspan = colSpan > 999 ? true : false;
if (header.value != nextHeader.value || nextParentsDiffer(data, row, col) || isHeaderLowestLvl || groupChange || maxColspan) {
if (header.value == "null") {
rowContent += ' | ';
} else {
if (totalsLists[ROWS])
colSpan = totalsLists[ROWS][row + 1][scanIndexes[ROWS][row + 1]].span;
rowContent += ''
+ (wrapContent ? ' ' + header.value + ' ' : header.value)
+ ' | ';
}
colSpan = 1;
} else {
colSpan++;
}
}
if (totalsLists[ROWS])
rowContent += genTotalHeaderCells(col - allData.leftOffset + 1, row + 1, scanSums[ROWS], scanIndexes[ROWS], totalsLists[ROWS], wrapContent);
} // If the cell is a row header and is null (grouped row header)
else if (header.type === "ROW_HEADER" && header.value === "null") {
rowContent += ' | ';
} // If the cell is a row header and isn't null (last row header)
else if (header.type === "ROW_HEADER") {
if (lowestRowLvl == col)
isHeaderLowestLvl = true;
else
nextHeader = data[row][col+1];
var previousRow = data[row - 1];
var same = !headerSame && !isHeaderLowestLvl && (col == 0 || !topParentsDiffer(data, row, col)) && header.value === previousRow[col].value;
headerSame = !same;
var value = (same ? "
" : '' + header.value + '
');
if (!wrapContent) {
value = (same ? " " : header.value );
}
var tipsy = "";
/* var tipsy = ' original-title="';
if (!same && header.metaproperties) {
for (key in header.metaproperties) {
if (key.substring(0,1) != "$" && key.substring(1,2).toUpperCase() != key.substring(1,2)) {
tipsy += "" + safe_tags_replace(key) + " : " + safe_tags_replace(header.metaproperties[key]) + "
";
}
}
}
tipsy += '"';
*/
var cssclass = (same ? "row_null" : "row");
var colspan = 0;
if (!isHeaderLowestLvl && (typeof nextHeader == "undefined" || nextHeader.value === "null")) {
colspan = 1;
var group = header.properties.dimension;
var level = header.properties.level;
var groupWidth = (group in rowGroups ? rowGroups[group].length - rowGroups[group].indexOf(level) : 1);
for (var k = col + 1; colspan < groupWidth && k <= (lowestRowLvl+1) && data[row][k] !== "null"; k++) {
colspan = k - col;
}
col = col + colspan -1;
}
rowContent += ' 0 ? ' colspan="' + colspan + '"' : "") + tipsy + '>' + value + ' | ';
}
else if (header.type === "ROW_HEADER_HEADER") {
rowContent += '';
isHeaderLowestLvl = true;
processedRowHeader = true;
lowestRowLvl = col;
if (header.properties.hasOwnProperty("dimension")) {
var group = header.properties.dimension;
if (!(group in rowGroups)) {
rowGroups[group] = [];
}
rowGroups[group].push(header.properties.level);
}
} // If the cell is a normal data cell
else if (header.type === "DATA_CELL") {
batchStarted = true;
var color = "";
var val = header.value;
var arrow = "";
if (header.properties.hasOwnProperty('image')) {
var img_height = header.properties.hasOwnProperty('image_height') ? " height='" + header.properties.image_height + "'" : "";
var img_width = header.properties.hasOwnProperty('image_width') ? " width='" + header.properties.image_width + "'" : "";
val = "
";
}
if (header.properties.hasOwnProperty('style')) {
color = " style='background-color: " + header.properties.style + "' ";
}
if (header.properties.hasOwnProperty('link')) {
val = "" + val + "";
}
if (header.properties.hasOwnProperty('arrow')) {
arrow = "
";
}
rowContent += ''
+ (wrapContent ? ' ' : "")
+ val + arrow
+ (wrapContent ? ' ' : '') + ' | ';
if (totalsLists[ROWS])
rowContent += genTotalDataCells(colShifted + 1, rowShifted, scanSums[ROWS], scanIndexes[ROWS], totalsLists, wrapContent);
}
}
rowContent += "";
var totals = "";
if (totalsLists[COLUMNS] && rowShifted >= 0) {
totals += genTotalHeaderRowCells(rowShifted + 1, scanSums, scanIndexes, totalsLists, wrapContent);
}
if (batchStarted && batchSize) {
if (row <= batchSize) {
if (!isColHeader && !isColHeaderDone) {
tableContent += "
";
isColHeaderDone = true;
}
tableContent += rowContent;
if (totals.length > 0) {
tableContent += totals;
}
} else {
resultRows.push(rowContent);
if (totals.length > 0) {
resultRows.push(totals);
}
}
} else {
if (!isColHeader && !isColHeaderDone) {
tableContent += "";
isColHeaderDone = true;
}
tableContent += rowContent;
if (totals.length > 0) {
tableContent += totals;
}
}
}
if (options) {
options['batchResult'] = resultRows;
options['hasBatchResult'] = resultRows.length > 0;
}
return "";
};