Saiku控制页面展示的数据过长自动换行(二十四)
Saiku控制页面展示的数据过长自动换行
目前用到saiku来展示数据,发现数据文本过长也不会自动换行,然而用户那边又需要换行(会好看些),所以就来改一改源码啦
首先我们使用谷歌浏览器 inspect 一下,找到对应的位置数据的 CSS定义
我们会看到对应的css文件为 saiku.table.css
源码中: saiku-ui 项目下 -- 》 saiku-ui\css\saiku\src\saiku.table.css 文件
安装包中: saiku-server\tomcat\webapps\ROOT\css\saiku\src\saiku.table.css 文件
里面有关于数据展示的定义为 不换行 white-space: nowrap; #nowrap就是不换行除非遇到了 <br>
最初的时候我以为将white-space的替换为normal就可以了哟,但是发现替换后部分数据正常显示,但是另外的数据就显示混乱了....
为了不影响其他数据的正常显示,我们还是用js来控制换行吧
思路:
找到定义class为 row 的数据,然后动态的改变对应的值,在里面手动添加<br/>标签去换行,这样子就能在所有页面都正常展示了,然后导出excel时也不会有<br/>标签
(因为之前用的是在数据固定存入数据库时就插入<br/>标签来做到页面换行,但是导出数据也会将<br/>标签带出来,这样影响了数据,所以此方案也不使用了)
实现步骤:
找到Table渲染 js 文件: SaikuTableRenderer.js
文件位置:
源码中:saiku-ui\js\saiku\render\SaikuTableRenderer.js
安装包中:saiku-server\tomcat\webapps\ROOT\js\saiku\render\SaikuTableRenderer.js
在 class="row"的数据中添加<br/>标签,在这里为什么确定 class="row",我们使用浏览器inspect的时候能看到
SaikuTableRenderer.js中添加如下代码段:(大概是源文件的 669行之后)
/*文本过长时:自动换行(超过40个文字就换一行)*/
if(cssclass == "row" && value.length>0){
var startPos = value.indexOf('>'); //找到对应标签的开始位置
var endPos = value.lastIndexOf('<'); //找到对应标签的结束位置
var tmpValue = value.substr( startPos+1 ,endPos-startPos-1); // 取出具体的值
//将value值每隔40个字自动加上换行符
if(tmpValue.length>120){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,40)+"<br/>"+tmpValue.substr(120,tmpValue.length-120);
}else if(tmpValue.length>80){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,tmpValue.length-80);
}else if(tmpValue.length>40){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,tmpValue.length-40);
}
//给value值加上标签信息 与之前的value相比,只是添加了<br/>换行符!
value = value.substr(0,startPos+1) + tmpValue + value.substr(endPos,value.length-endPos);
}
属于此方法: SaikuTableRenderer.prototype.internalRender = function(allData, options)
上下文如下:(文末会提供完整的SaikuTableRenderer.js文件):
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 += "<b>" + safe_tags_replace(key) + "</b> : " + safe_tags_replace(header.metaproperties[key]) + "<br>";
}
}
}
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;
} /*文本过长时:自动换行(超过40个文字就换一行)*/
if(cssclass == "row" && value.length>0){
var startPos = value.indexOf('>'); //找到对应标签的开始位置
var endPos = value.lastIndexOf('<'); //找到对应标签的结束位置
var tmpValue = value.substr( startPos+1 ,endPos-startPos-1); // 取出具体的值
//将value值每隔40个字自动加上换行符
if(tmpValue.length>120){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,40)+"<br/>"+tmpValue.substr(120,tmpValue.length-120);
}else if(tmpValue.length>80){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,tmpValue.length-80);
}else if(tmpValue.length>40){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,tmpValue.length-40);
}
//给value值加上标签信息 与之前的value相比,只是添加了<br/>换行符!
value = value.substr(0,startPos+1) + tmpValue + value.substr(endPos,value.length-endPos);
}
rowContent += '<th class="' + cssclass + '" ' + (colspan > 0 ? ' colspan="' + colspan + '"' : "") + tipsy + '>' + value + '</th>';
}
更改完 SaikuTableRenderer.js 文件后,刷新页面即可直接访问数据啦!!!(会发现数据每40个字就会自动换行)
完整的SaikuTableRenderer.js文件:
function SaikuTableRenderer(data, options) {
this._data = data;
this._options = _.extend({}, SaikuRendererOptions, options);
} function getAxisLevelsName(data, axisName) {
var queryData = data.query.queryModel.axes[axisName].hierarchies;
var len = queryData.length;
var arrLevels = []; for (var i = 0; i < len; i++) {
for (var level in queryData[i].levels) {
if (queryData[i].levels.hasOwnProperty(level)) {
if (Settings.COLUMN_TITLE_TABLE_USE_LEVEL_CAPTION_NAME) {
arrLevels.push(queryData[i].levels[level].caption);
}
else {
arrLevels.push(level);
}
}
}
} return arrLevels;
} function setStyleNegativeNumber(value) {
var className = ''; if (Settings.STYLE_NEGATIVE_NUMBER && parseFloat(value) < 0) {
className = ' style_negative_number ';
} return className;
} function getAxisSize(data, axisName) {
var queryData = data.query.queryModel.axes[axisName].hierarchies;
var len = queryData.length;
var axisSize = 0; for (var i = 0; i < len; i++) {
axisSize += _.size(queryData[i].levels);
} return axisSize;
} function getDomColumnsLevelsName(htmlObject) {
var $htmlObject = $(htmlObject.closest('.workspace')
.find('.workspace_fields')
.find('.columns.axis_fields')
.find('.hierarchy')
.find('.d_level'));
var arrLevels = []; $.each($htmlObject, function(key, level) {
if ($(level).attr('style') === 'display: list-item;') {
if (Settings.COLUMN_TITLE_TABLE_USE_LEVEL_CAPTION_NAME) {
arrLevels.push($(level).find('.level').attr('title'));
}
else {
arrLevels.push($(level).find('.level').attr('level'));
}
}
}); return arrLevels;
} 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;
} this.hideEmpty = this._options.hideEmpty; 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);
// Render the totals summary
$('#totals_summary').remove(); // Remove one previous totals div, if present
$(self._options.htmlObject).after(self.renderSummary(data)); // Render the new summary // $(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 += '<td class="data total">' + currentListNode.cells[m][cellIndex].value + '</td>';
} 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 ? "<span class='i18n'>Grand Total</span>" : "Grand Total");
}
}
contents += '<th class="' + cssClass + '">'
+ (wrapContent ? '<div>' + text + '</div>' : text ) + '</th>';
}
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 += '<td class="' + cssClass + '">' + text + '</td>';
}
scanIndexes[i]++;
if (scanIndexes[i] < lists[i].length)
scanSums[i] += lists[i][scanIndexes[i]].width;
}
}
return contents;
} function isNextTotalsRow(currentIndex, scanSums, scanIndexes, totalsLists, wrapContent) {
var colLists = totalsLists[COLUMNS];
var colScanSums = scanSums[COLUMNS];
var colScanIndexes = scanIndexes[COLUMNS];
var bottom = colLists.length - 2;
var contents = -1;
for (var i = bottom; i >= 0; i--) {
if (currentIndex == colScanSums[i]) {
for (var m = 0; m < colLists[i][colScanIndexes[i]].cells.length; m++) {
contents += '<tr>';
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';
return j;
}
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 ? "<span class='i18n'>Grand Total</span>" : "Grand Total");
}
} }
}
}
}
return -1;
} 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 += '<tr>';
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 ? "<span class='i18n'>Grand Total</span>" : "Grand Total");
}
}
contents += '<th class="' + cssClass + '">'
+ (wrapContent ? '<div>' + text + '</div>' : text ) + '</th>'; } var scanIndexes = {};
var scanSums = {}; if (totalsLists[ROWS]) {
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 += '<td class="data total">' + colLists[i][colScanIndexes[i]].cells[m][k].value + '</td>'; if (totalsLists[ROWS]) {
contents += totalIntersectionCells(k + 1, totalsLists[ROWS].length - 1, scanSums, scanIndexes, totalsLists[ROWS]);
}
} contents += '</tr>';
} 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;
} /**
* This function is intended to traverse the totals arrays and cleanup empty
* totals. This will optimize the query result on screen, displaying just the
* needed cells.
* @param dirs The direction array ['ROWS', 'COLUMNS']
* @param totalsLists The totals from allData.rowTotalsLists and allData.colTotalsLists.
*/
function cleanupTotals(dirs, totalsLists) {
// For each direction (ROWS/COLUMNS)
for (var dirIndex = 0; dirIndex < dirs.length; dirIndex++) {
var dir = dirs[dirIndex]; // If there are defined totals
if (totalsLists[dir]) {
var isEmpty = true; // A flag to indicate if this total is empty
for (var row = 0; row < totalsLists[dir].length; row++) {
var totalsInfoArray = totalsLists[dir][row];
for (var totalIndex = 0; totalIndex < totalsInfoArray.length; totalIndex++) {
var cells = totalsLists[dir][row][totalIndex].cells;
for (var cellIndex = 0; cellIndex < cells.length; cellIndex++) {
var cellArray = cells[cellIndex];
// For each total cell
for (var i = 0; i < cellArray.length; i++) {
var cell = cellArray[i];
// If it contains a value different from empty
if (cell.value !== '-') {
isEmpty = false; // So, this total is not empty
}
}
}
}
} if (isEmpty) { // If this total is empty
totalsLists[dir] = null; // Remove it
}
}
}
} SaikuTableRenderer.prototype.internalRender = function(allData, options) {
var tableContent = "";
var rowContent = "";
var data = allData.cellset; var newRowContent = '';
var arrRowData = [];
var objRowData = []; 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]; var hasMeasures = allData.query && allData.query.queryModel && allData.query.queryModel.details
? allData.query.queryModel.details.measures.length
: 0; if (typeof this._options.htmlObject === 'object' &&
Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE &&
hasMeasures > 0 &&
allData.query.type === 'QUERYMODEL' &&
allData.query.queryModel.details.axis === 'COLUMNS' &&
allData.query.queryModel.details.location === 'BOTTOM') { var arrColumnTitleTable = getAxisLevelsName(allData, COLUMNS);
var arrDomColumnTitleTable = getDomColumnsLevelsName(this._options.htmlObject);
var colspanColumnTitleTable = getAxisSize(allData, ROWS);
var auxColumnTitleTable = 0; if (arrColumnTitleTable.length === arrDomColumnTitleTable.length) {
arrColumnTitleTable = arrDomColumnTitleTable;
}
else {
arrColumnTitleTable = _.intersection(arrDomColumnTitleTable, arrColumnTitleTable);
}
} for (var i = 0; i < dirs.length; i++) {
scanSums[dirs[i]] = new Array();
scanIndexes[dirs[i]] = new Array();
} // Here we cleaup the empty totals
cleanupTotals(dirs, totalsLists); 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;
}
} rowWithOnlyEmptyCells = true;
rowContent = "<tr>";
var header = null; if (row === 0) {
rowContent = "<thead>" + rowContent;
} if (typeof this._options.htmlObject === 'object' &&
Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE &&
hasMeasures > 0 &&
allData.query.type === 'QUERYMODEL' &&
allData.query.queryModel.details.axis === 'COLUMNS' &&
allData.query.queryModel.details.location === 'BOTTOM' &&
auxColumnTitleTable < arrColumnTitleTable.length) { rowContent += '<th class="row_header" style="text-align: right;" colspan="' + colspanColumnTitleTable + '" title="' + arrColumnTitleTable[auxColumnTitleTable] + '">'
+ (wrapContent ? '<div>' + arrColumnTitleTable[auxColumnTitleTable] + '</div>' : arrColumnTitleTable[auxColumnTitleTable])
+ '</th>'; auxColumnTitleTable += 1;
} for (var col = 0, colLen = table[row].length; col < colLen; col++) {
var colShifted = col - allData.leftOffset;
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)) {
if (((!Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE || (Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE && allData.query.queryModel.details.location !== 'BOTTOM')) || hasMeasures === 0) ||
allData.query.type === 'MDX') {
rowContent += '<th class="all_null"> </th>';
}
} // 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 += '<th class="col_null"> </th>';
} else {
if (totalsLists[ROWS])
colSpan = totalsLists[ROWS][row + 1][scanIndexes[ROWS][row + 1]].span;
rowContent += '<th class="col" style="text-align: center;" colspan="' + colSpan + '" title="' + header.value + '">'
+ (wrapContent ? '<div rel="' + row + ":" + col +'">' + header.value + '</div>' : header.value)
+ '</th>';
} } 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 += '<th class="col_null" colspan="' + colSpan + '"> </th>';
} else {
if (totalsLists[ROWS])
colSpan = totalsLists[ROWS][row + 1][scanIndexes[ROWS][row + 1]].span;
rowContent += '<th class="col" style="text-align: center;" colspan="' + (colSpan == 0 ? 1 : colSpan) + '" title="' + header.value + '">'
+ (wrapContent ? '<div rel="' + row + ":" + col +'">' + header.value + '</div>' : header.value)
+ '</th>';
}
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 += '<th class="row_null"> </th>';
} // 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 nextRow = data[row + 1];
var same = !headerSame && !isHeaderLowestLvl && (col == 0 || !topParentsDiffer(data, row, col)) && header.value === previousRow[col].value;
headerSame = !same;
var sameAsPrevValue = false;
if(Settings.ALLOW_TABLE_DATA_COLLAPSE){
if (row > 0 && row < rowLen - 1) {
if (totalsLists[ROWS] == null || (col <= colLen - totalsLists[ROWS].length - 1)) {
var checkOther = true;
if (totalsLists[COLUMNS] && rowShifted >= 0 && col <= isNextTotalsRow(rowShifted + 1, scanSums, scanIndexes, totalsLists, wrapContent)) {
sameAsPrevValue = true;
checkOther = false;
}
if (checkOther && nextRow[col].value == header.value) {
if (col > 0) {
for (var j = 0; j < col; j++) {
if (nextRow[j].value == data[row][j].value) {
sameAsPrevValue = true;
} else {
sameAsPrevValue = false;
break;
}
}
} else {
sameAsPrevValue = true;
}
}
}
} else if(row > 0 && row == rowLen - 1) {
if (totalsLists[COLUMNS] && rowShifted >= 0 && col <= isNextTotalsRow(rowShifted + 1, scanSums, scanIndexes, totalsLists, wrapContent)) {
sameAsPrevValue = true;
}
}
}
var value = (same ? "<div> </div>" : '<div rel="' + row + ":" + col + '">'
+ (sameAsPrevValue && Settings.ALLOW_TABLE_DATA_COLLAPSE ? '<span class="expander expanded" style="cursor: pointer;">▼</span>' : '' ) + header.value + '</div>');
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 += "<b>" + safe_tags_replace(key) + "</b> : " + safe_tags_replace(header.metaproperties[key]) + "<br>";
}
}
}
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;
} /*文本过长时:自动换行(超过40个文字就换一行)*/
if(cssclass == "row" && value.length>0){
var startPos = value.indexOf('>'); //找到对应标签的开始位置
var endPos = value.lastIndexOf('<'); //找到对应标签的结束位置
var tmpValue = value.substr( startPos+1 ,endPos-startPos-1); // 取出具体的值
//将value值每隔40个字自动加上换行符
if(tmpValue.length>120){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,40)+"<br/>"+tmpValue.substr(120,tmpValue.length-120);
}else if(tmpValue.length>80){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,tmpValue.length-80);
}else if(tmpValue.length>40){
tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,tmpValue.length-40);
}
//给value值加上标签信息 与之前的value相比,只是添加了<br/>换行符!
value = value.substr(0,startPos+1) + tmpValue + value.substr(endPos,value.length-endPos);
}
rowContent += '<th class="' + cssclass + '" ' + (colspan > 0 ? ' colspan="' + colspan + '"' : "") + tipsy + '>' + value + '</th>';
}
else if (header.type === "ROW_HEADER_HEADER") {
var hierName = function(data) {
var hier = data.properties.hierarchy;
var name = hier.replace(/[\[\]]/gi, '').split('.')[1]
? hier.replace(/[\[\]]/gi, '').split('.')[1]
: hier.replace(/[\[\]]/gi, '').split('.')[0]; return name;
};
var arrPosRowData = []; if (_.contains(arrRowData, header.value)) {
for (var i = 0; i < arrRowData.length; i++) {
if (arrRowData[i] === header.value) {
arrPosRowData.push(i);
}
} arrPosRowData.push(col);
} rowContent += '<th class="row_header">' + (wrapContent ? '<div>' + header.value + '</div>' : header.value) + '</th>'; arrRowData.push(header.value);
objRowData.push({
name: header.value,
hierName: hierName(header) + '/' + header.value
}); 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 (arrPosRowData.length > 0) {
var aux = 0; rowContent = '<tr>'; if (row === 0) {
rowContent = '<thead>' + rowContent;
} for (var i = 0; i < objRowData.length; i++) {
if (arrPosRowData[aux] === i) {
newRowContent += '<th class="row_header">' + (wrapContent ? '<div>' + objRowData[i].hierName + '</div>' : objRowData[i].hierName) + '</th>';
aux += 1;
}
else {
newRowContent += '<th class="row_header">' + (wrapContent ? '<div>' + objRowData[i].name + '</div>' : objRowData[i].name) + '</th>';
}
} rowContent += newRowContent;
}
} // If the cell is a normal data cell
else if (header.type === "DATA_CELL") {
batchStarted = true;
var color = "";
var val = _.isEmpty(header.value) ? Settings.EMPTY_VALUE_CHARACTER : 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 = "<img " + img_height + " " + img_width + " style='padding-left: 5px' src='" + header.properties.image + "' border='0'>";
} // Just apply formatting to non-empty cells
if (val !== '-' && val !== '' && header.properties.hasOwnProperty('style')) {
color = " style='background-color: " + header.properties.style + "' ";
}
if (header.properties.hasOwnProperty('link')) {
val = "<a target='__blank' href='" + header.properties.link + "'>" + val + "</a>";
}
if (header.properties.hasOwnProperty('arrow')) {
arrow = "<img height='10' width='10' style='padding-left: 5px' src='./images/arrow-" + header.properties.arrow + ".gif' border='0'>";
} if (val !== '-' && val !== '') {
rowWithOnlyEmptyCells = false;
} rowContent += '<td class="data" ' + color + '>'
+ (wrapContent ? '<div class="datadiv '+ setStyleNegativeNumber(header.properties.raw) + '" alt="' + header.properties.raw + '" rel="' + header.properties.position + '">' : "")
+ val + arrow
+ (wrapContent ? '</div>' : '') + '</td>';
if (totalsLists[ROWS])
rowContent += genTotalDataCells(colShifted + 1, rowShifted, scanSums[ROWS], scanIndexes[ROWS], totalsLists, wrapContent);
}
}
rowContent += "</tr>"; // Change it to let hideEmpty true by default
if (options.hideEmpty && header.type === "DATA_CELL" && rowWithOnlyEmptyCells) {
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 += "</thead><tbody>";
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 += "</thead><tbody>";
isColHeaderDone = true;
}
tableContent += rowContent;
if (totals.length > 0) {
tableContent += totals;
}
}
}
if (options) {
options['batchResult'] = resultRows;
options['hasBatchResult'] = resultRows.length > 0;
}
return "<table>" + tableContent + "</tbody></table>";
}; SaikuTableRenderer.prototype.renderSummary = function(data) {
if (data && data.query) {
var hasSomethingToRender = false;
var measures = data.query.queryModel.details
? data.query.queryModel.details.measures
: [];
var summaryData = {}; for (var i = 0; i < measures.length; i++) {
var m = measures[i];
if (m.aggregators) {
for (var j = 0; j < m.aggregators.length; j++) {
var a = m.aggregators[j];
if (a.indexOf('_') > 0) {
var tokens = a.split('_');
var aggregator = tokens[0];
var axis = tokens[1]; if (aggregator !== 'nil' && aggregator !== 'not') {
hasSomethingToRender = true;
aggregator = aggregator.capitalizeFirstLetter();
if (!(axis in summaryData)) summaryData[axis] = [];
summaryData[axis].push(m.name + ": " + aggregator);
}
}
}
}
} if (hasSomethingToRender) {
var summary = "<div id='totals_summary'><br/>"; $.each(summaryData, function(key, aggregators) {
summary += "<h3>" + key.capitalizeFirstLetter();
for (var i = 0; i < aggregators.length; i++) {
summary += "<br/> " + aggregators[i];
}
summary += "</h3>";
}); return summary + "</div>";
}
} return "";
}; String.prototype.capitalizeFirstLetter = function() {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
}
Saiku控制页面展示的数据过长自动换行(二十四)的更多相关文章
- 【FAQ】分析服务导出的事件数据和概览页面展示的数据不一致该如何解决?
华为分析服务面向开发者提供两种数据展现方式:(1)事件数据下载,开发者可以将事件数据下载后导入到自有的分析系统中:(2)直接在AGC概览页面查看用户数和事件数. 问题描述 某开发者想将事件数据导入到自 ...
- Saiku嵌入页面plugin=true效果自定义实现(二十七)
Saiku嵌入页面使用 自定义实现 Plugin=true 效果 saiku嵌入页面plugin=true时数据不显示(plugin=false或者不设定plugin的值时数据显示正常)这个问题困扰了 ...
- [JS前端开发] js/jquery控制页面动态载入数据 滑动滚动栏自己主动载入事件
本人小菜鸟一仅仅.为了自我学习和交流PHP(jquery,linux,lamp,shell,javascript,server)等一系列的知识,小菜鸟创建了一个群.希望光临本博客的人能够进来交流.寻求 ...
- 前端页面展示MySQL数据并实现前后端互动
前端页面使用H-ui框架 后端使用flask框架 数据库使用mysql 连接数据库通过pymysql实现 前端代码如下 <html lang="en"> < ...
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十四):权限控制(Shiro 注解)
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 当前,我们基于导航菜单的显示和操作按钮的禁用状态,实现了页面可见性和 ...
- 数据可视化之powerBI技巧(二十四)Power BI初学者刚见的错误,帮你轻松处理
在学习PowerBI的过程中,尤其是刚接触的时候,不可避免的会遇到各种各样的错误,有时自己怎么检查都没法消除,不解决这个错误又没法进行下一步的工作,经常会搞的自己烦闷无比,不过最后通过自己的苦苦摸索. ...
- Dynamic CRM 2013学习笔记(二十四)页面保存前进行逻辑验证
我们有时要验证下页面上的一些逻辑,比如开始时间不能晚于结束时间,不对时不让保存.我们可以在相关的字段事件上处理,但这如果要判断的字段比较多时,就比较麻烦了. 这时候我们就可以利用Form的OnSave ...
- Android开发(二十四)——数据存储SharePreference、SQLite、File、ContentProvider
Android提供以下四种存储方式: SharePreference SQLite File ContentProvider Android系统中数据基本都是私有的,一般存放在“data/data/程 ...
- Python脚本控制的WebDriver 常用操作 <二十四> 定位frame中的元素
测试用例场景 处理frame需要用到2个方法,分别是switch_to_frame(name_or_id_or_frame_element)和switch_to_default_content() 如 ...
随机推荐
- freeswitch替换默认保持音乐
1.编译vars.xml文件 上面为注释,下面为新增.指定系统音乐文件路径,reloadxml即可!
- iP私网地址
私网地址范围:A类10.0.0.0~255.255.255 B类172.16.0.0~172.31.255.255 C类192.168.0.0~192.168.255.255
- pam密码策略
PAM 的使用历史 PAM 是关注如何为服务验证用户的 API.在使用 PAM 之前,诸如 login(和 rlogin.telnet.rsh)之类的应用程序在 /etc/passwd 中查找用户名, ...
- ORM的概念
- Hadoop之搭建完全分布式运行模式
一.过程分析 1.准备3台客户机(关闭防火墙.修改静态ip.主机名称) 2.安装JDK 3.配置环境变量 4.安装Hadoop 5.配置集群 6.单点启动 7.配置ssh免密登录 8.群起并测试集群 ...
- time to set up Goals
Function Goal Training for new guys, meanings who takes part of QA jobs and make other QA members g ...
- CentOS6.9切换root用户su root输入正确密码后一直提示Incorrect password,如何解决?
su是切换用户命令,su root时,输入正确的root命令,却提示Incorrect password,当前用户为普通用户,遇到此问题该如何解决呢? 如果设置了wheel组,使用su root命令是 ...
- pytest--fixture参数化的实现方式和执行顺序
之前看到fixture函数可以通过添加,params参数来实现参数化,后续看到了悠悠 的博客,可以通过@pytest.mark.parametrize来实现,现在做一个总结 实现方式一 通过param ...
- String、StringBuilder和StringBuffer的区别
1 String.StringBuilder和StringBuffer的区别 String.StringBuilder.StringBuffer都可以用来保存字符串.如果是使用次数比较 ...
- java枚举通俗实例解析
1 枚举 1.1 枚举的作用 我们经常要定义一些常量值,例如日期(MONDAY,TUESDAY……)或者错误码等.可以将常量组织起来,统一进行管理.常量比较只是值 ...