------------------------------------------------------------ revno: 20953 committer: Jan Henrik Overland <janhenrik.overl...@gmail.com> branch nick: dhis2 timestamp: Wed 2015-11-04 16:10:58 +0100 message: PT noext. modified: dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/index2.html dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core2.js
-- lp:dhis2 https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk Your team DHIS 2 developers is subscribed to branch lp:dhis2. To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/index2.html' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/index2.html 2015-10-27 15:20:53 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/index2.html 2015-11-04 15:10:58 +0000 @@ -17,9 +17,11 @@ <div class="spinner"></div> </div> +<!-- <script type="text/javascript" src="../dhis-web-commons/javascripts/ext/ext-all.js"></script> <script type="text/javascript" src="../dhis-web-commons/javascripts/ext-ux/layout/component/form/MultiSelect.js"></script> <script type="text/javascript" src="../dhis-web-commons/javascripts/ext-ux/form/MultiSelect.js"></script> +--> <script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.min.js"></script> <script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/calendars/jquery.calendars.min.js"></script> === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core2.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core2.js 2015-11-04 11:01:11 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core2.js 2015-11-04 15:10:58 +0000 @@ -11,21 +11,24 @@ isObject, isEmpty, isDefined, + isIE, + numberConstrain, arrayFrom, arrayClean, arrayPluck, - arrayIndexOf, arrayUnique, arrayContains, clone, - enumerables = ['valueOf', 'toLocaleString', 'toString', 'constructor']; - - // enumerables - (function() { - for (i in { toString: 1 }) { - enumerables = null; - } - })(); + uuid, + enumerables = function() { + var enu = ['valueOf', 'toLocaleString', 'toString', 'constructor']; + + for (var i in { toString: 1 }) { + enu = null; + } + + return enu; + }(); isString = function(param) { return typeof param === 'string'; @@ -53,6 +56,7 @@ return typeof param === 'boolean'; }; + // dep: isArray isEmpty = function(array, allowEmptyString) { return (array == null) || (!allowEmptyString ? array === '' : false) || (isArray(array) && array.length === 0); }; @@ -66,23 +70,94 @@ return type === 'string' || type === 'number' || type === 'boolean'; }; + isIE = function() { + var ua = window.navigator.userAgent; + + // test values + // IE 10: ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'; + // IE 11: ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'; + // IE 12 / Spartan: ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0'; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // IE 12 => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; + }; + + numberConstrain = function(number, min, max) { + number = parseFloat(number); + + if (!isNaN(min)) { + number = Math.max(number, min); + } + if (!isNaN(max)) { + number = Math.min(number, max); + } + return number; + }; + + // dep: isArray arrayFrom = function(param, isNewRef) { + var toArray = function(iterable, start, end) { + if (!iterable || !iterable.length) { + return []; + } + + if (typeof iterable === 'string') { + iterable = iterable.split(''); + } + + if (supportsSliceOnNodeList) { + return slice.call(iterable, start || 0, end || iterable.length); + } + + var array = [], + i; + + start = start || 0; + end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length; + + for (i = start; i < end; i++) { + array.push(iterable[i]); + } + + return array; + }; + if (param === undefined || param === null) { return []; } - if (Ext.isArray(param)) { + if (isArray(param)) { return (isNewRef) ? slice.call(param) : param; } var type = typeof param; if (param && param.length !== undefined && type !== 'string' && (type !== 'function' || !param.apply)) { - return ExtArray.toArray(param); + return toArray(param); } return [param]; }; + // dep: isEmpty arrayClean = function(array) { var results = [], i = 0, @@ -113,21 +188,6 @@ return newArray; }; - arrayIndexOf = ('indexOf' in Array.prototype) ? function(array, item, from) { - return Array.prototype.indexOf.call(array, item, from); - } : function(array, item, from) { - var i, len = array.length; - - for (i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) { - if (array[i] === item) { - return i; - } - } - - return -1; - }; - - // dep: arrayIndexOf arrayUnique = function(array) { var newArray = [], i = 0, @@ -137,7 +197,7 @@ for (; i < len; i++) { item = array[i]; - if (arrayIndexOf(newArray, item) === -1) { + if (newArray.indexOf(item) === -1) { newArray.push(item); } } @@ -145,19 +205,8 @@ return newArray; }; - // dep: arrayIndexOf - arrayContains = ('indexOf' in Array.prototype) ? function(array, item) { + arrayContains = function(array, item) { return Array.prototype.indexOf.call(array, item) !== -1; - } : function(array, item) { - var i, len; - - for (i = 0, len = array.length; i < len; i++) { - if (array[i] === item) { - return true; - } - } - - return false; }; clone = function(item) { @@ -182,14 +231,14 @@ clone = []; while (i--) { - clone[i] = Ext.clone(item[i]); + clone[i] = clone(item[i]); } } else if (type === '[object Object]' && item.constructor === Object) { clone = {}; for (key in item) { - clone[key] = Ext.clone(item[key]); + clone[key] = clone(item[key]); } if (enumerables) { @@ -205,6 +254,14 @@ return clone || item; }; + uuid = function () { + var s4 = function() { + return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); + }; + + return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); + }; + NS.isString = isString; NS.isNumber = isNumber; NS.isNumeric = isNumeric; @@ -213,13 +270,15 @@ NS.isObject = isObject; NS.isEmpty = isEmpty; NS.isDefined = isDefined; + NS.isIE = isIE; + NS.numberConstrain = numberConstrain; NS.arrayFrom = arrayFrom; NS.arrayClean = arrayClean; NS.arrayPluck = arrayPluck; - NS.arrayIndexOf = arrayIndexOf; NS.arrayUnique = arrayUnique; NS.arrayContains = arrayContains; NS.clone = clone; + NS.uuid = uuid; })(); // date manager TODO import @@ -642,6 +701,16 @@ }); }; + t.getDimensionNames = function() { + var names = []; + + this.forEach(function(dimension) { + names.push(dimension.dimension); + }); + + return names; + }; + t.sorted = function() { return NS.clone(this).sort(function(a, b) { return a.dimension > b.dimension;}); }; @@ -682,7 +751,7 @@ t.parentGraphMap = NS.isObject(config.parentGraphMap) ? config.parentGraphMap : null; - if (Ext.isObject(config.program)) { + if (NS.isObject(config.program)) { t.program = config.program; } @@ -731,7 +800,7 @@ $.extend(t, forceApplyConfig); // uninitialized - t.dimensionNameIdsMap; + t.dimensionNameRecordIdsMap; }; Layout.prototype.log = function(text, noError) { @@ -774,9 +843,9 @@ return isSorted ? dimensions.sort(function(a, b) {return a.dimension > b.dimension;}) : dimensions; }; - Layout.prototype.getDimensionNameIdsMap = function() { - if (this.dimensionNameIdsMap) { - return this.dimensionNameIdsMap; + Layout.prototype.getDimensionNameRecordIdsMap = function() { + if (this.dimensionNameRecordIdsMap) { + return this.dimensionNameRecordIdsMap; } var map = {}; @@ -785,7 +854,7 @@ map[dimension.dimension] = dimension.getRecordIds(); }); - return this.dimensionNameIdsMap = map; + return this.dimensionNameRecordIdsMap = map; }; // dep 2 @@ -918,7 +987,7 @@ text; if (NS.arrayContains([413, 414], statusCode)) { - if (NS.isIE) { + if (NS.isIE()) { text = 'Too many items selected (url has ' + url.length + ' characters). Internet Explorer accepts maximum 2048 characters.'; } else { @@ -1031,8 +1100,28 @@ return this.metaData.names[id]; }; + Response.prototype.getHierarchyNameById = function(id, isHierarchy, isHtml) { + var metaData = response.metaData, + name = ''; + + if (isHierarchy) { + var a = NS.arrayClean(metaData.ouHierarchy[id].split('/')); + a.shift(); + + for (var i = 0; i < a.length; i++) { + name += (isHtml ? '<span class="text-weak">' : '') + metaData.names[a[i]] + (isHtml ? '</span>' : '') + ' / '; + } + } + + return name; + }; + // dep 1 + Response.prototype.getItemName = function(id, isHierarchy, isHtml) { + return this.getHierarchyNameById(id, isHierarchy) + this.getNameById(id); + }; + Response.prototype.getValueHeader = function() { return this.getHeaderByName('value'); }; @@ -1043,10 +1132,1131 @@ return this.getValueHeader().getIndex(); }; })(); + + //todo TableAxis + (function() { + var TableAxis = NS.Api.TableAxis = function(layout, type) { + var dimensionNames, + spanType, + aDimensions = [], + nAxisWidth = 1, + nAxisHeight, + aaUniqueFloorIds, + aUniqueFloorWidth = [], + aAccFloorWidth = [], + aFloorSpan = [], + aaGuiFloorIds = [], + aaAllFloorIds = [], + aCondoId = [], + aaAllFloorObjects = [], + uuidObjectMap = {}; + + if (type === 'col') { + dimensionNames = layout.columns.getDimensionNames(); + spanType = 'colSpan'; + } + else if (type === 'row') { + dimensionNames = layout.rows.getDimensionNames(); + spanType = 'rowSpan'; + } + + if (!(NS.isArray(dimensionNames) && dimensionNames.length)) { + return; + } + //dimensionNames = ['pe', 'ou']; + + // aDimensions: array of dimension objects with dimensionName property + dimensionNames.forEach(function(name) { + aDimensions.push({ + dimensionName: name + }); + }); + //aDimensions = [{ + //dimensionName: 'pe' + //}] + + // aaUniqueFloorIds: array of arrays with unique ids for each dimension floor + aaUniqueFloorIds = function() { + var a = []; + + aDimensions.forEach(function(dimension) { + a.push(layout.getDimensionNameRecordIdsMap()[dimension.dimensionName]); + }); + + return a; + }(); + //aaUniqueFloorIds = [ [de-id1, de-id2, de-id3], + // [pe-id1], + // [ou-id1, ou-id2, ou-id3, ou-id4] ] + + // nAxisHeight + nAxisHeight = aaUniqueFloorIds.length; + //nAxisHeight = 3 + + + // aUniqueFloorWidth, nAxisWidth, aAccFloorWidth + for (var i = 0, nUniqueFloorWidth; i < nAxisHeight; i++) { + nUniqueFloorWidth = aaUniqueFloorIds[i].length; + + aUniqueFloorWidth.push(nUniqueFloorWidth); + nAxisWidth = nAxisWidth * nUniqueFloorWidth; + aAccFloorWidth.push(nAxisWidth); + } + //aUniqueFloorWidth = [3, 1, 4] + //nAxisWidth = 12 (3 * 1 * 4) + //aAccFloorWidth = [3, 3, 12] + + // aFloorSpan + for (var i = 0; i < nAxisHeight; i++) { + if (aUniqueFloorWidth[i] === 1) { + if (i === 0) { // if top floor, set maximum span + aFloorSpan.push(nAxisWidth); + } + else { + if (layout.hideEmptyRows && type === 'row') { + aFloorSpan.push(nAxisWidth / aAccFloorWidth[i]); + } + else { //if just one item and not top level, use same span as top level + aFloorSpan.push(aFloorSpan[0]); + } + } + } + else { + aFloorSpan.push(nAxisWidth / aAccFloorWidth[i]); + } + } + //aFloorSpan = [4, 12, 1] + + + // aaGuiFloorIds + aaGuiFloorIds.push(aaUniqueFloorIds[0]); + + if (nAxisHeight.length > 1) { + for (var i = 1, a, n; i < nAxisHeight; i++) { + a = []; + n = aUniqueFloorWidth[i] === 1 ? aUniqueFloorWidth[0] : aAccFloorWidth[i-1]; + + for (var j = 0; j < n; j++) { + a = a.concat(aaUniqueFloorIds[i]); + } + + aaGuiFloorIds.push(a); + } + } + //aaGuiFloorIds = [ [d1, d2, d3], (3) + // [p1, p2, p3, p4, p5, p1, p2, p3, p4, p5, p1, p2, p3, p4, p5], (15) + // [o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2...] (30) + // ] + + // aaAllFloorIds + for (var i = 0, aAllFloorIds, aUniqueFloorIds, span, factor; i < nAxisHeight; i++) { + aAllFloorIds = []; + aUniqueFloorIds = aaUniqueFloorIds[i]; + span = aFloorSpan[i]; + factor = nAxisWidth / (span * aUniqueFloorIds.length); + + for (var j = 0; j < factor; j++) { + for (var k = 0; k < aUniqueFloorIds.length; k++) { + for (var l = 0; l < span; l++) { + aAllFloorIds.push(aUniqueFloorIds[k]); + } + } + } + + aaAllFloorIds.push(aAllFloorIds); + } + //aaAllFloorIds = [ [d1, d1, d1, d1, d1, d1, d1, d1, d1, d1, d2, d2, d2, d2, d2, d2, d2, d2, d2, d2, d3, d3, d3, d3, d3, d3, d3, d3, d3, d3], (30) + // [p1, p2, p3, p4, p5, p1, p2, p3, p4, p5, p1, p2, p3, p4, p5, p1, p2, p3, p4, p5, p1, p2, p3, p4, p5, p1, p2, p3, p4, p5], (30) + // [o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2] (30) + // ] + + // aCondoId + for (var i = 0, id; i < nAxisWidth; i++) { + id = ''; + + for (var j = 0; j < nAxisHeight; j++) { + id += aaAllFloorIds[j][i]; + } + + if (id) { + aCondoId.push(id); + } + } + //aCondoId = [ id11+id21+id31, id12+id22+id32, ... ] + + + // allObjects + for (var i = 0, allFloor; i < aaAllFloorIds.length; i++) { + allFloor = []; + + for (var j = 0, obj; j < aaAllFloorIds[i].length; j++) { + obj = { + id: aaAllFloorIds[i][j], + uuid: NS.uuid(), + dim: i, + axis: type + }; + + // leaf? + if (i === aaAllFloorIds.length - 1) { + obj.leaf = true; + } + + allFloor.push(obj); + } + + aaAllFloorObjects.push(allFloor); + } + + // add span and children + for (var i = 0, aAboveFloorObjects, doorIds, uniqueDoorIds; i < aaAllFloorObjects.length; i++) { + doorIds = []; + + for (var j = 0, obj, doorCount = 0, oldestObj; j < aaAllFloorObjects[i].length; j++) { + + obj = aaAllFloorObjects[i][j]; + doorIds.push(obj.id); + + if (doorCount === 0) { + + // span + obj[spanType] = aFloorSpan[i]; + + // children + if (obj.leaf) { + obj.children = 0; + } + + // first sibling + obj.oldest = true; + + // root? + if (i === 0) { + obj.root = true; + } + + // tmp oldest uuid + oldestObj = obj; + } + + obj.oldestSibling = oldestObj; + + if (++doorCount === aFloorSpan[i]) { + doorCount = 0; + } + } + + // set above floor door children to number of unique door ids on this floor + if (i > 0) { + aAboveFloorObjects = aaAllFloorObjects[i-1]; + uniqueDoorIds = NS.arrayUnique(doorIds); + + for (var j = 0; j < aAboveFloorObjects.length; j++) { + aAboveFloorObjects[j].children = uniqueDoorIds.length; + } + } + } + + // add parents if more than 1 floor + if (nAxisHeight > 1) { + for (var i = 1, aAllFloor; i < nAxisHeight; i++) { + aAllFloor = aaAllFloorObjects[i]; + + //for (var j = 0, obj, doorCount = 0, span = aFloorSpan[i - 1], parentObj = aaAllFloorObjects[i - 1][0]; j < aAllFloor.length; j++) { + for (var j = 0, doorCount = 0, span = aFloorSpan[i - 1]; j < aAllFloor.length; j++) { + aAllFloor[j].parent = aaAllFloorObjects[i - 1][j]; + + //doorCount++; + + //if (doorCount === span) { + //parentObj = aaAllFloorObjects[i - 1][j + 1]; + //doorCount = 0; + //} + } + } + } + + // add uuids array to leaves + if (aaAllFloorObjects.length) { + + // set span to second lowest span number: if aFloorSpan == [15,3,15,1], set span to 3 + var nSpan = nAxisHeight > 1 ? support.prototype.array.sort(NS.clone(aFloorSpan))[1] : nAxisWidth, + aAllFloorObjectsLast = aaAllFloorObjects[aaAllFloorObjects.length - 1]; + + for (var i = 0, leaf, parentUuids, obj, leafUuids = []; i < aAllFloorObjectsLast.length; i++) { + leaf = aAllFloorObjectsLast[i]; + leafUuids.push(leaf.uuid); + parentUuids = []; + obj = leaf; + + // get the uuid of the oldest sibling + while (obj.parent) { + obj = obj.parent; + parentUuids.push(obj.oldestSibling.uuid); + } + + // add parent uuids to leaf + leaf.uuids = NS.clone(parentUuids); + + // add uuid for all leaves + if (leafUuids.length === nSpan) { + for (var j = (i - nSpan) + 1, leaf; j <= i; j++) { + leaf = aAllFloorObjectsLast[j]; + leaf.uuids = leaf.uuids.concat(leafUuids); + } + + leafUuids = []; + } + } + } + + // populate uuidObject map + for (var i = 0; i < aaAllFloorObjects.length; i++) { + for (var j = 0, object; j < aaAllFloorObjects[i].length; j++) { + object = aaAllFloorObjects[i][j]; + + uuidObjectMap[object.uuid] = object; + } + } + + return { + type: type, + items: aDimensions, + xItems: { + unique: aaUniqueFloorIds, + gui: aaGuiFloorIds, + all: aaAllFloorIds + }, + objects: { + all: aaAllFloorObjects + }, + ids: aCondoId, + span: aFloorSpan, + dims: nAxisHeight, + size: nAxisWidth, + uuidObjectMap: uuidObjectMap + }; + }; + })(); + + //todo Table + (function() { + var Table = NS.Api.Table = function(layout, response, colAxis, rowAxis) { + var getRoundedHtmlValue, + getTdHtml, + doSubTotals, + doRowTotals, + doColTotals, + doSortableColumnHeaders, + getColAxisHtmlArray, + getRowHtmlArray, + rowAxisHtmlArray, + getColTotalHtmlArray, + getGrandTotalHtmlArray, + getTotalHtmlArray, + getHtml, + getUniqueFactor = function(xAxis) { + var unique; + + if (!xAxis) { + return null; + } + + unique = xAxis.xItems.unique; + + if (unique) { + return unique.length < 2 ? 1 : (xAxis.size / unique[0].length); + } + + return null; + }, + colUniqueFactor = getUniqueFactor(colAxis), + rowUniqueFactor = getUniqueFactor(rowAxis), + valueItems = [], + valueObjects = [], + totalColObjects = [], + uuidDimUuidsMap = {}, + //isLegendSet = NS.isObject(xLayout.legendSet) && NS.isArray(xLayout.legendSet.legends) && xLayout.legendSet.legends.length, + isLegendSet = false, + tdCount = 0, + htmlArray; + + xResponse.sortableIdObjects = []; + + getRoundedHtmlValue = function(value, dec) { + dec = dec || 2; + return parseFloat(support.prototype.number.roundIf(value, 2)).toString(); + }; + + getTdHtml = function(config, metaDataId) { + var bgColor, + legends, + colSpan, + rowSpan, + htmlValue, + displayDensity, + fontSize, + isNumeric = NS.isObject(config) && NS.isString(config.type) && config.type.substr(0,5) === 'value' && !config.empty, + isValue = isNumeric && config.type === 'value', + cls = '', + html = '', + getHtmlValue; + + getHtmlValue = function(config) { + var str = config.htmlValue, + n = parseFloat(config.htmlValue); + + if (config.collapsed) { + return ''; + } + + if (isValue) { + if (NS.isBoolean(str)) { + return str; + } + + //if (!NS.isNumber(n) || n != str || new Date(str).toString() !== 'Invalid Date') { + if (!NS.isNumber(n) || n != str) { + return str; + } + + return n; + } + + return str || ''; + } + + if (!NS.isObject(config)) { + return ''; + } + + if (config.hidden || config.collapsed) { + return ''; + } + + // number of cells + tdCount = tdCount + 1; + + // background color from legend set + if (isValue && layout.legendSet) { + var value = parseFloat(config.value); + legends = layout.legendSet.legends; + + for (var i = 0; i < legends.length; i++) { + if (NS.numberConstrain(value, legends[i].startValue, legends[i].endValue) === value) { + bgColor = legends[i].color; + } + } + } + + colSpan = config.colSpan ? 'colspan="' + config.colSpan + '" ' : ''; + rowSpan = config.rowSpan ? 'rowspan="' + config.rowSpan + '" ' : ''; + htmlValue = getHtmlValue(config); + htmlValue = config.type !== 'dimension' ? support.prototype.number.prettyPrint(htmlValue, layout.digitGroupSeparator) : htmlValue; + + cls += config.hidden ? ' td-hidden' : ''; + cls += config.collapsed ? ' td-collapsed' : ''; + cls += isValue ? ' pointer' : ''; + //cls += bgColor ? ' legend' : (config.cls ? ' ' + config.cls : ''); + cls += config.cls ? ' ' + config.cls : ''; + + // if sorting + if (NS.isString(metaDataId)) { + cls += ' td-sortable'; + + xResponse.sortableIdObjects.push({ + id: metaDataId, + uuid: config.uuid + }); + } + + html += '<td ' + (config.uuid ? ('id="' + config.uuid + '" ') : ''); + html += ' class="' + cls + '" ' + colSpan + rowSpan; + + //if (bgColor && isValue) { + //html += 'style="color:' + bgColor + ';padding:' + displayDensity + '; font-size:' + fontSize + ';"' + '>' + htmlValue + '</td>'; + //html += '>'; + //html += '<div class="legendCt">'; + //html += '<div class="number ' + config.cls + '" style="padding:' + displayDensity + '; padding-right:3px; font-size:' + fontSize + '">' + htmlValue + '</div>'; + //html += '<div class="arrowCt ' + config.cls + '">'; + //html += '<div class="arrow" style="border-bottom:8px solid transparent; border-right:8px solid ' + bgColor + '"> </div>'; + //html += '</div></div></div></td>'; + //} + //else { + html += 'style="' + (bgColor && isValue ? 'color:' + bgColor + '; ' : '') + '">' + htmlValue + '</td>'; + //} + + return html; + }; + + doColTotals = function() { + return !!layout.showColTotals; + }; + + doRowTotals = function() { + return !!layout.showRowTotals; + }; + + doColSubTotals = function() { + return !!layout.showColSubTotals && rowAxis && rowAxis.dims > 1; + }; + + doRowSubTotals = function() { + return !!layout.showRowSubTotals && colAxis && colAxis.dims > 1; + }; + + doSortableColumnHeaders = function() { + return (rowAxis && rowAxis.dims === 1); + }; + + getColAxisHtmlArray = function() { + var a = [], + columnDimensionNames = colAxis ? layout.columns.getDimensionNames() : [], + rowDimensionNames = rowAxis ? layout.rows.getDimensionNames() : [], + getEmptyHtmlArray; + + getEmptyNameTdConfig = function(config) { + config = config || {}; + + return getTdHtml({ + cls: config.cls ? ' ' + config.cls : 'pivot-empty', + colSpan: config.colSpan ? config.colSpan : 1, + rowSpan: config.rowSpan ? config.rowSpan : 1, + htmlValue: config.htmlValue ? config.htmlValue : ' ' + }); + }; + + getEmptyHtmlArray = function(i) { + var a = []; + + // if not the intersection cell + if (i < colAxis.dims - 1) { + if (rowAxis && rowAxis.dims) { + for (var j = 0; j < rowAxis.dims - 1; j++) { + a.push(getEmptyNameTdConfig({ + cls: 'pivot-dim-label' + })); + } + } + + a.push(getEmptyNameTdConfig({ + cls: 'pivot-dim-label', + htmlValue: dimConf.objectNameMap[columnDimensionNames[i]].name + })); + } + else { + if (rowAxis && rowAxis.dims) { + for (var j = 0; j < rowAxis.dims - 1; j++) { + a.push(getEmptyNameTdConfig({ + cls: 'pivot-dim-label', + htmlValue: dimConf.objectNameMap[rowDimensionNames[j]].name + })); + } + } + + a.push(getEmptyNameTdConfig({ + cls: 'pivot-dim-label', + htmlValue: (rowAxis ? dimConf.objectNameMap[rowDimensionNames[j]].name : '') + (colAxis && rowAxis ? ' / ' : '') + (colAxis ? dimConf.objectNameMap[columnDimensionNames[i]].name : '') + })); + } + + return a; + }; + + if (!colAxis) { + + // show row dimension labels + if (rowAxis && layout.showDimensionLabels) { + var dimLabelHtml = []; + + // labels from row object names + for (var i = 0; i < rowDimensionNames.length; i++) { + dimLabelHtml.push(getEmptyNameTdConfig({ + cls: 'pivot-dim-label', + htmlValue: dimConf.objectNameMap[rowDimensionNames[i]].name + })); + } + + // pivot-transparent-column unnecessary + + a.push(dimLabelHtml); + } + + return a; + } + + // for each col dimension + for (var i = 0, dimHtml; i < colAxis.dims; i++) { + dimHtml = []; + + if (layout.showDimensionLabels) { + dimHtml = dimHtml.concat(getEmptyHtmlArray(i)); + } + else if (i === 0) { + dimHtml.push(colAxis && rowAxis ? getEmptyNameTdConfig({ + colSpan: rowAxis.dims, + rowSpan: colAxis.dims + }) : ''); + } + + for (var j = 0, obj, spanCount = 0, condoId, totalId; j < colAxis.size; j++) { + spanCount++; + condoId = null; + totalId = null; + + obj = colAxis.objects.all[i][j]; + obj.type = 'dimension'; + obj.cls = 'pivot-dim'; + obj.noBreak = false; + obj.hidden = !(obj.rowSpan || obj.colSpan); + obj.htmlValue = response.getItemName(obj.id, layout.showHierarchy, true); + + // sortable column headers. last dim only. + if (i === colAxis.dims - 1 && doSortableColumnHeaders()) { + + //condoId = colAxis.ids[j].split('-').join(''); + condoId = colAxis.ids[j]; + } + + dimHtml.push(getTdHtml(obj, condoId)); + + if (i === 0 && spanCount === colAxis.span[i] && doRowSubTotals() ) { + dimHtml.push(getTdHtml({ + type: 'dimensionSubtotal', + cls: 'pivot-dim-subtotal cursor-default', + rowSpan: colAxis.dims, + htmlValue: ' ' + })); + + spanCount = 0; + } + + if (i === 0 && (j === colAxis.size - 1) && doRowTotals()) { + totalId = doSortableColumnHeaders() ? 'total_' : null; + + dimHtml.push(getTdHtml({ + uuid: NS.uuid(), + type: 'dimensionTotal', + cls: 'pivot-dim-total', + rowSpan: colAxis.dims, + htmlValue: 'Total' + }, totalId)); + } + } + + a.push(dimHtml); + } + + return a; + }; + + getRowHtmlArray = function() { + var a = [], + axisAllObjects = [], + xValueObjects, + totalValueObjects = [], + mergedObjects = [], + valueItemsCopy, + colAxisSize = colAxis ? colAxis.size : 1, + rowAxisSize = rowAxis ? rowAxis.size : 1, + recursiveReduce; + + recursiveReduce = function(obj) { + if (!obj.children) { + obj.collapsed = true; + + if (obj.parent) { + obj.parent.oldestSibling.children--; + } + } + + if (obj.parent) { + recursiveReduce(obj.parent.oldestSibling); + } + }; + + // dimension + if (rowAxis) { + for (var i = 0, row; i < rowAxis.size; i++) { + row = []; + + for (var j = 0, obj, newObj; j < rowAxis.dims; j++) { + obj = rowAxis.objects.all[j][i]; + obj.type = 'dimension'; + obj.cls = 'pivot-dim td-nobreak' + (layout.showHierarchy ? ' align-left' : ''); + obj.noBreak = true; + obj.hidden = !(obj.rowSpan || obj.colSpan); + obj.htmlValue = response.getItemName(obj.id, layout.showHierarchy, true); + + row.push(obj); + } + + axisAllObjects.push(row); + } + } + else { + if (layout.showDimensionLabels) { + axisAllObjects.push([{ + type: 'transparent', + cls: 'pivot-transparent-row' + }]); + } + } + + + //axisAllObjects = [ [ dim, dim ] + // [ dim, dim ] + // [ dim, dim ] + // [ dim, dim ] ]; + + // value + for (var i = 0, valueItemsRow, valueObjectsRow, idValueMap = xResponse.idValueMap; i < rowAxisSize; i++) { + valueItemsRow = []; + valueObjectsRow = []; + + for (var j = 0, id, value, responseValue, htmlValue, empty, uuid, uuids; j < colAxisSize; j++) { + empty = false; + uuids = []; + + // meta data uid + id = ((colAxis ? colAxis.ids[j] : '') + (rowAxis ? rowAxis.ids[i] : '')); + + // value html element id + uuid = NS.uuid(); + + // get uuids array from colaxis/rowaxis leaf + if (colAxis) { + uuids = uuids.concat(colAxis.objects.all[colAxis.dims - 1][j].uuids); + } + if (rowAxis) { + uuids = uuids.concat(rowAxis.objects.all[rowAxis.dims - 1][i].uuids); + } + + // value, htmlValue + responseValue = idValueMap[id]; + + if (NS.isDefined(responseValue)) { + value = service.response.getValue(responseValue); + htmlValue = responseValue; + } + else { + value = 0; + htmlValue = ' '; + empty = true; + } + + valueItemsRow.push(value); + valueObjectsRow.push({ + uuid: uuid, + type: 'value', + cls: 'pivot-value' + (empty ? ' cursor-default' : ''), + value: value, + htmlValue: htmlValue, + empty: empty, + uuids: uuids + }); + + // map element id to dim element ids + uuidDimUuidsMap[uuid] = uuids; + } + + valueItems.push(valueItemsRow); + valueObjects.push(valueObjectsRow); + } + + // totals + if (colAxis && doRowTotals()) { + for (var i = 0, empty = [], total = 0; i < valueObjects.length; i++) { + for (j = 0, obj; j < valueObjects[i].length; j++) { + obj = valueObjects[i][j]; + + empty.push(obj.empty); + total += obj.value; + } + + // row totals + totalValueObjects.push({ + type: 'valueTotal', + cls: 'pivot-value-total', + value: total, + htmlValue: NS.arrayContains(empty, false) ? getRoundedHtmlValue(total) : '', + empty: !NS.arrayContains(empty, false) + }); + + // add row totals to idValueMap to make sorting on totals possible + if (doSortableColumnHeaders()) { + var totalId = 'total_' + rowAxis.ids[i], + isEmpty = !NS.arrayContains(empty, false); + + xResponse.idValueMap[totalId] = isEmpty ? null : total; + } + + empty = []; + total = 0; + } + } + + // hide empty rows (dims/values/totals) + if (colAxis && rowAxis) { + if (layout.hideEmptyRows) { + for (var i = 0, valueRow, isValueRowEmpty, dimLeaf; i < valueObjects.length; i++) { + valueRow = valueObjects[i]; + isValueRowEmpty = !NS.arrayContains(NS.arrayPluck(valueRow, 'empty'), false); + + // if value row is empty + if (isValueRowEmpty) { + + // hide values by adding collapsed = true to all items + for (var j = 0; j < valueRow.length; j++) { + valueRow[j].collapsed = true; + } + + // hide totals by adding collapsed = true to all items + if (doRowTotals()) { + totalValueObjects[i].collapsed = true; + } + + // hide/reduce parent dim span + dimLeaf = axisAllObjects[i][rowAxis.dims-1]; + recursiveReduce(dimLeaf); + } + } + } + } + + xValueObjects = valueObjects; + + // col subtotals + if (doRowSubTotals()) { + var tmpValueObjects = []; + + for (var i = 0, row, rowSubTotal, colCount; i < xValueObjects.length; i++) { + row = []; + rowSubTotal = 0; + colCount = 0; + + for (var j = 0, item, collapsed = [], empty = []; j < xValueObjects[i].length; j++) { + item = xValueObjects[i][j]; + rowSubTotal += item.value; + empty.push(!!item.empty); + collapsed.push(!!item.collapsed); + colCount++; + + row.push(item); + + if (colCount === colUniqueFactor) { + var isEmpty = !NS.arrayContains(empty, false); + row.push({ + type: 'valueSubtotal', + cls: 'pivot-value-subtotal' + (isEmpty ? ' cursor-default' : ''), + value: rowSubTotal, + htmlValue: isEmpty ? ' ' : getRoundedHtmlValue(rowSubTotal), + empty: isEmpty, + collapsed: !NS.arrayContains(collapsed, false) + }); + + colCount = 0; + rowSubTotal = 0; + empty = []; + collapsed = []; + } + } + + tmpValueObjects.push(row); + } + + xValueObjects = tmpValueObjects; + } + + // row subtotals + if (doColSubTotals()) { + var tmpAxisAllObjects = [], + tmpValueObjects = [], + tmpTotalValueObjects = [], + getAxisSubTotalRow; + + getAxisSubTotalRow = function(collapsed) { + var row = []; + + for (var i = 0, obj; i < rowAxis.dims; i++) { + obj = {}; + obj.type = 'dimensionSubtotal'; + obj.cls = 'pivot-dim-subtotal cursor-default'; + obj.collapsed = NS.arrayContains(collapsed, true); + + if (i === 0) { + obj.htmlValue = ' '; + obj.colSpan = rowAxis.dims; + } + else { + obj.hidden = true; + } + + row.push(obj); + } + + return row; + }; + + // tmpAxisAllObjects + for (var i = 0, row, collapsed = []; i < axisAllObjects.length; i++) { + tmpAxisAllObjects.push(axisAllObjects[i]); + collapsed.push(!!axisAllObjects[i][0].collapsed); + + // insert subtotal after last objects + if (!NS.isArray(axisAllObjects[i+1]) || !!axisAllObjects[i+1][0].root) { + tmpAxisAllObjects.push(getAxisSubTotalRow(collapsed)); + + collapsed = []; + } + } + + // tmpValueObjects + for (var i = 0; i < tmpAxisAllObjects.length; i++) { + tmpValueObjects.push([]); + } + + for (var i = 0; i < xValueObjects[0].length; i++) { + for (var j = 0, rowCount = 0, tmpCount = 0, subTotal = 0, empty = [], collapsed, item; j < xValueObjects.length; j++) { + item = xValueObjects[j][i]; + tmpValueObjects[tmpCount++].push(item); + subTotal += item.value; + empty.push(!!item.empty); + rowCount++; + + if (axisAllObjects[j][0].root) { + collapsed = !!axisAllObjects[j][0].collapsed; + } + + if (!NS.isArray(axisAllObjects[j+1]) || axisAllObjects[j+1][0].root) { + var isEmpty = !NS.arrayContains(empty, false); + + tmpValueObjects[tmpCount++].push({ + type: item.type === 'value' ? 'valueSubtotal' : 'valueSubtotalTotal', + value: subTotal, + htmlValue: isEmpty ? ' ' : getRoundedHtmlValue(subTotal), + collapsed: collapsed, + cls: (item.type === 'value' ? 'pivot-value-subtotal' : 'pivot-value-subtotal-total') + (isEmpty ? ' cursor-default' : '') + }); + rowCount = 0; + subTotal = 0; + empty = []; + } + } + } + + // tmpTotalValueObjects + for (var i = 0, obj, collapsed = [], empty = [], subTotal = 0, count = 0; i < totalValueObjects.length; i++) { + obj = totalValueObjects[i]; + tmpTotalValueObjects.push(obj); + + collapsed.push(!!obj.collapsed); + empty.push(!!obj.empty); + subTotal += obj.value; + count++; + + if (count === rowAxis.span[0]) { + var isEmpty = !NS.arrayContains(empty, false); + + tmpTotalValueObjects.push({ + type: 'valueTotalSubgrandtotal', + cls: 'pivot-value-total-subgrandtotal' + (isEmpty ? ' cursor-default' : ''), + value: subTotal, + htmlValue: isEmpty ? ' ' : getRoundedHtmlValue(subTotal), + empty: isEmpty, + collapsed: !NS.arrayContains(collapsed, false) + }); + + collapsed = []; + empty = []; + subTotal = 0; + count = 0; + } + } + + axisAllObjects = tmpAxisAllObjects; + xValueObjects = tmpValueObjects; + totalValueObjects = tmpTotalValueObjects; + } + + // merge dim, value, total + for (var i = 0, row; i < xValueObjects.length; i++) { + row = []; + + //if (rowAxis) { + row = row.concat(axisAllObjects[i]); + //} + + row = row.concat(xValueObjects[i]); + + if (colAxis) { + row = row.concat(totalValueObjects[i]); + } + + mergedObjects.push(row); + } + + // create html items + for (var i = 0, row; i < mergedObjects.length; i++) { + row = []; + + for (var j = 0; j < mergedObjects[i].length; j++) { + row.push(getTdHtml(mergedObjects[i][j])); + } + + a.push(row); + } + + return a; + }; + + getColTotalHtmlArray = function() { + var a = []; + + if (rowAxis && doColTotals()) { + var xTotalColObjects; + + // total col items + for (var i = 0, total = 0, empty = []; i < valueObjects[0].length; i++) { + for (var j = 0, obj; j < valueObjects.length; j++) { + obj = valueObjects[j][i]; + + total += obj.value; + empty.push(!!obj.empty); + } + + // col total + totalColObjects.push({ + type: 'valueTotal', + value: total, + htmlValue: NS.arrayContains(empty, false) ? getRoundedHtmlValue(total) : '', + empty: !NS.arrayContains(empty, false), + cls: 'pivot-value-total' + }); + + total = 0; + empty = []; + } + + xTotalColObjects = totalColObjects; + + if (colAxis && doRowSubTotals()) { + var tmp = []; + + for (var i = 0, item, subTotal = 0, empty = [], colCount = 0; i < xTotalColObjects.length; i++) { + item = xTotalColObjects[i]; + tmp.push(item); + subTotal += item.value; + empty.push(!!item.empty); + colCount++; + + if (colCount === colUniqueFactor) { + tmp.push({ + type: 'valueTotalSubgrandtotal', + value: subTotal, + htmlValue: NS.arrayContains(empty, false) ? getRoundedHtmlValue(subTotal) : '', + empty: !NS.arrayContains(empty, false), + cls: 'pivot-value-total-subgrandtotal' + }); + + subTotal = 0; + colCount = 0; + } + } + + xTotalColObjects = tmp; + } + + // total col html items + for (var i = 0; i < xTotalColObjects.length; i++) { + a.push(getTdHtml(xTotalColObjects[i])); + } + } + + return a; + }; + + getGrandTotalHtmlArray = function() { + var total = 0, + empty = [], + a = []; + + if (doRowTotals() && doColTotals()) { + for (var i = 0, obj; i < totalColObjects.length; i++) { + obj = totalColObjects[i]; + + total += obj.value; + empty.push(obj.empty); + } + + if (colAxis && rowAxis) { + a.push(getTdHtml({ + type: 'valueGrandTotal', + cls: 'pivot-value-grandtotal', + value: total, + htmlValue: NS.arrayContains(empty, false) ? getRoundedHtmlValue(total) : '', + empty: !NS.arrayContains(empty, false) + })); + } + } + + return a; + }; + + getTotalHtmlArray = function() { + var dimTotalArray, + colTotal = getColTotalHtmlArray(), + grandTotal = getGrandTotalHtmlArray(), + row, + a = []; + + if (doColTotals()) { + if (rowAxis) { + dimTotalArray = [getTdHtml({ + type: 'dimensionSubtotal', + cls: 'pivot-dim-total', + colSpan: rowAxis.dims, + htmlValue: 'Total' + })]; + } + + row = [].concat(dimTotalArray || [], colTotal || [], grandTotal || []); + + a.push(row); + } + + return a; + }; + + getHtml = function() { + var cls = 'pivot', + table; + + cls += layout.displayDensity && layout.displayDensity !== conf.finals.style.normal ? ' displaydensity-' + layout.displayDensity : ''; + cls += layout.fontSize && layout.fontSize !== conf.finals.style.normal ? ' fontsize-' + layout.fontSize : ''; + + table = '<table class="' + cls + '">'; + + for (var i = 0; i < htmlArray.length; i++) { + table += '<tr>' + htmlArray[i].join('') + '</tr>'; + } + + return table += '</table>'; + }; + + // get html + return function() { + htmlArray = NS.arrayClean([].concat(getColAxisHtmlArray() || [], getRowHtmlArray() || [], getTotalHtmlArray() || [])); + + return { + html: getHtml(htmlArray), + uuidDimUuidsMap: uuidDimUuidsMap, + colAxis: colAxis, + rowAxis: rowAxis, + tdCount: tdCount + }; + }(); + }; + })(); })(); - - - - - });
_______________________________________________ Mailing list: https://launchpad.net/~dhis2-devs Post to : dhis2-devs@lists.launchpad.net Unsubscribe : https://launchpad.net/~dhis2-devs More help : https://help.launchpad.net/ListHelp