Saiku设置展示table数据不隐藏空的行数据信息
saiku有个 非空的字段 按钮,点击这个后,会自动的把空的行数据信息给隐藏掉,这里我们来设置一下让其行数据不隐藏,为空的就为空。
主要更改两个文件
1. Query.js 文件路径: /saiku-ui/js/saiku/models/Query.js (如果是编译好的saiku,请找到 saiku-server omcatwebappsROOTjssaikumodelsQuery.js )
2. SaikuTableRenderer.js 文件路径: /saiku-ui/js/saiku/render/SaikuTableRenderer.js (如果是编译好的saiku,请找到 saiku-server omcatwebappsROOTjssaiku enderSaikuTableRenderer.js )
这里我们是在做KPI汇总信息的是遇到这样的需求,具体还是看用户需求去改动哦哈哈哈~ 我们这边是要求为空的数据列信息也要展示空的数据信息。
1.首先我们为了保证后台能传回完整的数据,需要在Query.js 的 run 方法中设定参数信息 行数据非空也展示 (ps: 为了避免影响到其他数据的展示,我们将需要行数据为空也展示的数据单独拿出来判断,通过cube名来判断!)
var exModel = this.helper.model(); // 这条是run 方法里面原有的数据哦
主要代码: exModel.queryModel.axes.ROWS.nonEmpty=false;//設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data 这是新加的
//針對Summary數據做出更改 當行數據為空的時候 也需要展示出來 var cubename = exModel.cube.name ; if(cubename == "SummaryKPI_2018_ext" ||cubename == "SummaryKPI_2019_ext" ||cubename == "SummaryKPI_2019_Dynamic" ) { exModel.queryModel.axes.ROWS.nonEmpty=false;//設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data }else{ exModel.queryModel.axes.ROWS.nonEmpty=true; }
2.然后我们再在table渲染页面设定数据项为空也展示就可以啦!!! SaikuTableRenderer.js 的 internalRender 方法
更改rowWithOnlyEmptyCells 的默认值为 false , (ps: 为了避免影响到其他数据的展示,我们将需要行数据为空也展示的数据单独拿出来判断,通过cube名来判断!)
//rowWithOnlyEmptyCells = true; //默认行数据为空时不展展示,如果需要不展示改回来 将此条值置为true即可
主要代码: rowWithOnlyEmptyCells = false; //設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data
rowWithOnlyEmptyCells = true; //默认行数据为空时不展展示,如果改回来 将此条值置为true即可 if(cubename == "SummaryKPI_2018_ext" ||cubename == "SummaryKPI_2019_ext" ||cubename == "SummaryKPI_2019_Dynamic"){ rowWithOnlyEmptyCells = false; //設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data }
这样就可以了哦。
>>> 下面提供完整的js文件
Query.js
/* * Copyright 2012 OSBI Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Workspace query */ var Query = Backbone.Model.extend({ formatter: Settings.CELLSET_FORMATTER, properties: null, /*初始化方法*/ initialize: function(args, options) { if(args != null && args != undefined && args != "" && args.flag == "resultForstatisdate"){ this.get_all_statisdate(args); }else{ // Save cube _.extend(this, options); // Bind `this` _.bindAll(this, "run"); // Generate a unique query id this.uuid = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }).toUpperCase(); this.model = _.extend({ name: this.uuid }, SaikuOlapQueryTemplate); if (args.cube) { this.model.cube = args.cube; } this.helper = new SaikuOlapQueryHelper(this); // Initialize properties, action handler, and result handler this.action = new QueryAction({}, { query: this }); this.result = new Result({ limit: Settings.RESULT_LIMIT }, { query: this }); this.scenario = new QueryScenario({}, { query: this }); // A flag to tell who changed selection members this.updatedSelectionFromModal = false; } }, parse: function(response) { // Assign id so Backbone knows to PUT instead of POST this.id = this.uuid; if (response.name) { this.id = response.name; this.uuid = response.name; } this.model = _.extend(this.model, response); this.model.properties = _.extend({}, Settings.QUERY_PROPERTIES, this.model.properties); }, setProperty: function(key, value) { this.model.properties[key] = value; }, getProperty: function(key) { return this.model.properties[key]; }, syncSelectionsModalAndUpdateParameters: function() { if (this.updatedSelectionFromModal) { var mParameters = this.helper.model().parameters; for (var mKey in mParameters) { var mVal = mParameters[mKey]; var selections = this.helper.getSelectionsForParameter(mKey); mVal = selections.map(function(sel) { return sel.caption; }).join(); mParameters[mKey] = mVal; } } else { var mParameters = this.helper.model().parameters; for (var mKey in mParameters) { var mVal = mParameters[mKey]; var mLevel = this.helper.getLevelForParameter(mKey); var selections = this.helper.getSelectionsForParameter(mKey); if (mVal !== null && mVal !== undefined) { this.helper.setSelectionsForParameter(mKey, _.filter(selections, function(sel) { var containsParam = false; _.each(mVal.split(','), function (v) { if (sel.caption === v) { containsParam = true; return false; } }); return containsParam; })); } } } this.updatedSelectionFromModal = false; }, /*执行查询的方法*/ run: function(force, mdx) { this.syncSelectionsModalAndUpdateParameters(); var self = this; // Check for automatic execution Saiku.ui.unblock(); if (typeof this.model.properties != "undefined" && this.model.properties['saiku.olap.query.automatic_execution'] === false && (force === false || force === undefined || force === null)) { return; } this.workspace.unblock(); $(this.workspace.el).find(".workspace_results_info").empty(); this.workspace.trigger('query:run'); this.result.result = null; var validated = false; var errorMessage = '<span class="i18n">Query Validation failed!</span>'; var exModel = this.helper.model(); //針對Summary數據做出更改 當行數據為空的時候 也需要展示出來 var cubename = exModel.cube.name ; if(cubename == "SummaryKPI_2018_ext" ||cubename == "SummaryKPI_2019_ext" ||cubename == "SummaryKPI_2019_Dynamic" ) { exModel.queryModel.axes.ROWS.nonEmpty=false;//設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data }else{ exModel.queryModel.axes.ROWS.nonEmpty=true; } for(var k in this.attributes) { var att = this.attributes[k]; if(k.substring(0,5)==="PARAM"){ var p = k.substring(5, k.length); exModel.parameters[p] = att; } } if (exModel.queryType == "OLAP") { if (exModel.type == "QUERYMODEL") { var columnsOk = Object.keys(exModel.queryModel.axes.COLUMNS.hierarchies).length > 0; var rowsOk = Object.keys(exModel.queryModel.axes.ROWS.hierarchies).length > 0; var detailsOk = exModel.queryModel.details.axis == 'COLUMNS' && exModel.queryModel.details.measures.length > 0; if (!rowsOk || !columnsOk || !detailsOk) { errorMessage = ""; } if (!columnsOk && !detailsOk) { errorMessage += '<span class="i18n">You need to include at least one measure or a level on columns for a valid query.</span>'; } if(!rowsOk) { errorMessage += '<span class="i18n">You need to include at least one level on rows for a valid query.</span>'; } if ( (columnsOk || detailsOk) && rowsOk) { validated = true; } } else if (exModel.type == "MDX") { validated = (exModel.mdx && exModel.mdx.length > 0); if (!validated) { errorMessage = '<span class="i18n">You need to enter some MDX statement to execute.</span>'; } } } if (!validated) { this.workspace.table.clearOut(); $(this.workspace.processing).html(errorMessage).show(); this.workspace.adjust(); Saiku.i18n.translate(); return; } // Run it this.workspace.table.clearOut(); $(this.workspace.processing).html('<span class="processing_image"> </span> <span class="i18n">Running query...</span> [ <a class="cancel i18n" href="#cancel">Cancel</a> ]').show(); this.workspace.adjust(); this.workspace.trigger('query:fetch'); Saiku.i18n.translate(); var message = '<span class="processing_image"> </span> <span class="i18n">Running query...</span> [ <a class="cancel i18n" href="#cancel">Cancel</a> ]'; this.workspace.block(message); /* TODO: i wonder if we should clean up the model (name and captions etc.) delete this.model.queryModel.axes['FILTER'].name; */ /**根据ROWS中的statisdate字段过滤!*/ //根據用戶輸入的開始日期與結束日期查詢範圍數據 /* var dimensionArr = exModel.queryModel.axes.ROWS.hierarchies; //取出行信息中的所有维度信息 dimension,用一个数组接收 var statisdateFlag = "no"; for(var i=0;i<dimensionArr.length;i++){ //判断维度信息中是否有statisdate这个时间维度(这是固定的) if(dimensionArr[i]!=null && ((dimensionArr[i].dimension == "statisdate")||(dimensionArr[i].levels.statisdate != null)) ){ var paramsURI = Saiku.URLParams.paramsURI(); //get the param from url //判断参数是否为空 if(paramsURI.startdate != null && paramsURI.startdate != undefined && paramsURI.startdate != ""&& paramsURI.enddate != null && paramsURI.enddate != undefined && paramsURI.enddate != ""){ statisdateFlag = "yes"; this.startdateThis=null; this.enddateThis=null; var key="statisdateSpec"; (new SelectionsModal({ key: key, exModel: exModel, result: this.result, workspace: this.workspace })); } } } */ /**根据Fliter中的statisdate字段过滤!*/ var dimensionArr = exModel.queryModel.axes.FILTER.hierarchies; //取出FILTER信息中的所有维度信息 dimension,用一个数组接收 var statisdateFlag = "no"; for(var i=0;i<dimensionArr.length;i++){ //判断维度信息中是否有statisdate这个时间维度(这是固定的) if(dimensionArr[i]!=null && ((dimensionArr[i].dimension == "statisdate")||(dimensionArr[i].levels.statisdate != null)) ){ var paramsURI = Saiku.URLParams.paramsURI(); //get the param from url //判断参数是否为空 if(paramsURI.startdate != null && paramsURI.startdate != undefined && paramsURI.startdate != ""&& paramsURI.enddate != null && paramsURI.enddate != undefined && paramsURI.enddate != ""){ statisdateFlag = "yes"; this.startdateThis=null; this.enddateThis=null; var key="statisdateSpec"; (new SelectionsModal({ key: key, exModel: exModel, result: this.result, workspace: this.workspace })); } } } //根据入参是否有statisdate字段来判断是否执行以下查询 if(statisdateFlag == 'no'){ this.result.save({},{ contentType: "application/json", data: JSON.stringify(exModel), error: function() { Saiku.ui.unblock(); var errorMessage = '<span class="i18n">Error executing query. Please check the server logs or contact your administrator!</span>'; self.workspace.table.clearOut(); $(self.workspace.processing).html(errorMessage).show(); self.workspace.adjust(); Saiku.i18n.translate(); } }); } }, //得到返回的所有statisdate參數信息 get_all_statisdate: function(args){ var response = args.response; this.result = args.result; //var exModel = args.exModel; var statisdateArr= new Array(); for(var i=0;i<response.length;i++){ statisdateArr[i]=response[i].name; } //this.helper = new SaikuOlapQueryHelper(this); var exModel = args.exModel; var paramsURI = Saiku.URLParams.paramsURI(); //get the param from url var startdate=null; var enddate=null; if(this.startdateThis != null){ startdate=this.dateToStr(this.startdateThis); //获取修正后的开始日期 }else{ startdate=paramsURI.startdate;//开始日期(参数中的) } if(this.enddateThis != null){ enddate=this.dateToStr(this.enddateThis); //获取修正后的结束日期 }else{ enddate=paramsURI.enddate;//结束日期(参数中的) } //startdate = this.dateToStr(startdate); // 日期格式化 //enddate = this.dateToStr(enddate); // 日期格式化 if(statisdateArr.indexOf(startdate) > -1){// 这里是判断开始日期是否属于statisdateArr if(statisdateArr.indexOf(enddate) > -1){// 这里是判断结束日期是否属于statisdateArr //var dimensionArr = exModel.queryModel.axes.ROWS.hierarchies; //根据ROWS var dimensionArr = exModel.queryModel.axes.FILTER.hierarchies; //根据Filter for(var i=0;i<dimensionArr.length;i++){ if(dimensionArr[i]!=null && (dimensionArr[i].dimension == "statisdate" || dimensionArr[i].levels.statisdate != null ) ){ //更改level下的mdx表达式(使用開始日期與結束日期來控制過濾數據) dimensionArr[i].levels.statisdate.mdx="[statisdate].[statisdate].[statisdate].["+startdate+"]:[statisdate].[statisdate].[statisdate].["+enddate+"]"; //需要清除之前默認展示本週數據的過濾腳本信息 //exModel.queryModel.axes.ROWS.filters=[];//在ROWS中定义了过滤表达式时,清除此表达式 exModel.queryModel.axes.FILTER.filters=[];//在Filter中定义了过滤表达式时,清除此表达式 } } this.result.save({},{ contentType: "application/json", data: JSON.stringify(exModel), error: function() { Saiku.ui.unblock(); var errorMessage = '<span class="i18n">Error executing query. Please check the server logs or contact your administrator!</span>'; self.workspace.table.clearOut(); $(self.workspace.processing).html(errorMessage).show(); self.workspace.adjust(); Saiku.i18n.translate(); } }); }else{//结束日期不存在时:如果结束日期大于开始日期,将结束日期往前减一天 var tmpStartdate = this.strToDate(startdate);//StringToDate方法不存在 var tmpEnddate = this.strToDate(enddate); if(tmpEnddate>=tmpStartdate){ tmpEnddate = tmpEnddate.valueOf(); tmpEnddate = tmpEnddate - 1*24*60*60*1000; tmpEnddate = new Date(tmpEnddate); //这里改变paramURL中的结束日期参数值,然后回调当前函数 get_all_statisdate this.enddateThis=tmpEnddate; this.get_all_statisdate(args); }else{ //否则的话直接执行查询,直接无数据返回 var dimensionArr = exModel.queryModel.axes.FILTER.hierarchies; for(var i=0;i<dimensionArr.length;i++){ if(dimensionArr[i]!=null && (dimensionArr[i].dimension == "statisdate" || dimensionArr[i].levels.statisdate != null ) ){ enddate = this.dateToStr(tmpStartdate) //更改level下的mdx表达式(使用開始日期與結束日期來控制過濾數據) dimensionArr[i].levels.statisdate.mdx="[statisdate].[statisdate].[statisdate].["+enddate+"]:[statisdate].[statisdate].[statisdate].["+enddate+"]"; //需要清除之前默認展示本週數據的過濾腳本信息 //exModel.queryModel.axes.ROWS.filters=[];//在ROWS中定义了过滤表达式时,清除此表达式 exModel.queryModel.axes.FILTER.filters=[];//在Filter中定义了过滤表达式时,清除此表达式 } } this.result.save({},{ contentType: "application/json", data: JSON.stringify(exModel), error: function() { Saiku.ui.unblock(); var errorMessage = '<span class="i18n">Error executing query. Please check the server logs or contact your administrator!</span>'; self.workspace.table.clearOut(); $(self.workspace.processing).html(errorMessage).show(); self.workspace.adjust(); Saiku.i18n.translate(); } }); } } }else{ //开始日期不存在时: 如果开始日期小于结束日期,将开始日期往后加一天 var tmpStartdate = this.strToDate(startdate); var tmpEnddate = this.strToDate(enddate); if(tmpStartdate<=tmpEnddate){ tmpStartdate = tmpStartdate.valueOf(); tmpStartdate = tmpStartdate + 1*24*60*60*1000; tmpStartdate = new Date(tmpStartdate); //这里改变paramURL中的结束日期参数值,然后回调当前函数get_all_statisdate this.startdateThis=tmpStartdate; this.get_all_statisdate(args); }else{ //否则的话直接执行查询,直接无数据返回 var dimensionArr = exModel.queryModel.axes.FILTER.hierarchies; for(var i=0;i<dimensionArr.length;i++){ if(dimensionArr[i]!=null && (dimensionArr[i].dimension == "statisdate" || dimensionArr[i].levels.statisdate != null ) ){ startdate = this.dateToStr(tmpEnddate) //更改level下的mdx表达式(使用開始日期與結束日期來控制過濾數據) dimensionArr[i].levels.statisdate.mdx="[statisdate].[statisdate].[statisdate].["+startdate+"]:[statisdate].[statisdate].[statisdate].["+startdate+"]"; //需要清除之前默認展示本週數據的過濾腳本信息 //exModel.queryModel.axes.ROWS.filters=[];//在ROWS中定义了过滤表达式时,清除此表达式 exModel.queryModel.axes.FILTER.filters=[];//在Filter中定义了过滤表达式时,清除此表达式 } } this.result.save({},{ contentType: "application/json", data: JSON.stringify(exModel), error: function() { Saiku.ui.unblock(); var errorMessage = '<span class="i18n">Error executing query. Please check the server logs or contact your administrator!</span>'; self.workspace.table.clearOut(); $(self.workspace.processing).html(errorMessage).show(); self.workspace.adjust(); Saiku.i18n.translate(); } }); } } }, /*將string類型的數據轉換為date類型*/ strToDate: function(strDate){ strDate = strDate.toLocaleString(); strDate = strDate.substring(-1,10); var convert = Date.parse(strDate); var tmpdate = new Date(convert); return tmpdate; }, /*将Date类型转换为String类型 格式为:2019-03-03*/ dateToStr: function(dateStr){ //dateStr = this.strToDate(dateStr); var tmpYear= dateStr.getFullYear(); var tmpMonth = dateStr.getMonth()+1; var tmpDay = dateStr.getDate(); if(tmpMonth < 10){ tmpMonth = "0"+tmpMonth;} if(tmpDay < 10){ tmpDay = "0"+tmpDay;} var tmpdate = tmpYear+"-"+tmpMonth+"-"+tmpDay; return tmpdate; }, enrich: function() { var self = this; this.workspace.query.action.post("/../enrich", { contentType: "application/json", data: JSON.stringify(self.model), async: false, success: function(response, model) { self.model = model; } }); }, url: function() { return "api/query/" + encodeURI(this.uuid); } /** get_statisdate_members: function() { var path = "/result/metadata/hierarchies/%5Bstatisdate%5D.%5Bstatisdate%5D/levels/statisdate"; * gett isn't a typo, although someone should probably rename that method to avoid confusion. this.workspace.query.action.gett(path, { success: this.fetch_statisdate_members, error: function() { alert("error"); }, data: {result: true, searchlimit: 30000 }}); }, 得到獲取statisdate字段的結果信息然後處理 fetch_statisdate_members: function(model, response) { if (response && response.length > 0) { alert("Fetch_statisdate_member++++++++++++"+response); } }, */ });
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; } /*table render method*/ 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; } // the key method to render data by table form. 20190423 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 } } } } /*the main method to render data by table form. 20190423*/ 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; } } var headerFlag=true;// add this flag to solve the bug when same data to merge。 20190423 var cubename = allData.query.cube.name; 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; //默认行数据为空时不展展示,如果改回来 将此条值置为true即可 if(cubename == "SummaryKPI_2018_ext" ||cubename == "SummaryKPI_2019_ext" ||cubename == "SummaryKPI_2019_Dynamic"){ rowWithOnlyEmptyCells = false; //設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data } 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]; // when same set fixed value is false ,It means the same data will not merge。table data will show row by row.20190423 //var same=false; /*judge the current value and previousRow value, if equals ,all set comeback,set the headerFlag is true, we can judge the data as usual. 20190423*/ if(header.value !== previousRow[col].value){ headerFlag =true; } /*judge the tableContent include value or not, if include , set the headerFlag value is true to avoid repeat datas showed in table.20190423*/ if(tableContent.indexOf(header.value) > -1 ){ headerFlag =true; } /*add headerFlag to judge the data is same ,then control the data merge wheather or not.20190423 */ var same = !headerSame && !isHeaderLowestLvl && (col == 0 || !topParentsDiffer(data, row, col)) && header.value === previousRow[col].value && headerFlag; 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; } /*when the content is to long ,we will set new line to show it.*/ // eg value: <div rel="3:0">新業務及保單行政部</div> if(cssclass == "row" && value.length>0){ var startPos = value.indexOf('>'); //find start position of the tag. eg: <div rel="3:0"> var endPos = value.lastIndexOf('<'); //find end position of the tag. eg: </div> var tmpValue = value.substr( startPos+1 ,endPos-startPos-1); // get the content value. eg: 新業務及保單行政部 //将value值每隔40个字自动加上换行符 //each 40 character add one <br> tag to get new line. 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); } // compared with old value, this value only add <br> tag for show data in table more beautiful. 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) { /*when data_cell is null,set the headerFlag is false , to fix the problem data merge inccrrect. */ headerFlag=false; 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(); }
=====================二次更新=显示空的行数据========start================
最近又遇到了需要不隐藏的空的行数据的报表,笔者想了想用参数去处理此类问题会更好些吧
所以我们就在请求上URL添加参数 showEmptyRows=yes
之前判断具体cubename的部分 用参数来判定!!!
var paramsURI = Saiku.URLParams.paramsURI(); if( paramsURI .showEmptyRows=='yes') { exModel.queryModel.axes.ROWS.nonEmpty=false;//設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data }
视图渲染也根据入参如判断即可
var paramsURI = Saiku.URLParams.paramsURI(); if( paramsURI .showEmptyRows=='yes') {
rowWithOnlyEmptyCells = false; //設置行數據為空的時候也顯示數據! 20190425 for summaryKPI Data
}
ps: 请求url上记得添加参数 showEmptyRows=yes
感觉用参数会更加方便些,以后有添加其它报表的时候添加参数即可!!!(建议不直接判断cubename哦,哈哈哈哈哈哈 用此方式会更好些~)
=====================二次更新=显示空的行数据=======end=================