diff --git a/gulpfile.js b/gulpfile.js index 3b98207..0429c8f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -36,8 +36,8 @@ gulp.task("gatherScripts", ["clean"], function () { .pipe(uglify({ output: { ascii_only: true, - width: 30000, - max_line_len: 30000 + width: 25000, + max_line_len: 25000 } })) .pipe(header(banner, { pkg: pkg })) diff --git a/package.json b/package.json index 6d5d433..19ede7e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "LightPivotTable", "author": "ZitRo", - "version": "1.3.3", + "version": "1.4.2", "description": "A lightweight pivot table for MDX2JSON source for InterSystems Cache", "main": "test/testServer.js", "repository": { diff --git a/source/js/DataController.js b/source/js/DataController.js index 5826ec2..db724b2 100644 --- a/source/js/DataController.js +++ b/source/js/DataController.js @@ -97,6 +97,7 @@ DataController.prototype.setData = function (data) { this._dataStack[this._dataStack.length - 1].data = data; //this.data = data; + this.setLeftHeaderColumnsNumber(data); // required in resetDimensionProps() this.resetDimensionProps(); this.resetConditionalFormatting(); this.resetRawData(); @@ -130,13 +131,16 @@ DataController.prototype.setDrillThroughHandler = function (handler) { */ DataController.prototype.resetDimensionProps = function () { - var data, columnProps = []; + var data, columnProps; if (!(data = this._dataStack[this._dataStack.length - 1].data)) { console.error("Unable to get dimension props for given data set."); return; } + columnProps = new Array(data.info.leftHeaderColumnsNumber || 0); // fill left headers as empty + for (var i = 0; i < columnProps.length; i++) { columnProps[i] = {}; } + var cloneObj = function (obj) { var i, newObj = {}; for (i in obj) newObj[i] = obj[i]; @@ -153,12 +157,14 @@ DataController.prototype.resetDimensionProps = function () { if (tObj["style"]) clonedProps["style"] = (clonedProps["style"] || "") + tObj["style"]; if (tObj["summary"]) clonedProps["summary"] = tObj["summary"]; + // somehow "summary" were changed to "total" - reapplying + if (tObj["total"]) clonedProps["summary"] + = (tObj["total"] || "").toLowerCase().replace(/:.*/, ""); // what is "max:Days"? if (tObj["type"]) clonedProps["type"] = tObj["type"]; parse(tObj, clonedProps); } } else { - clonedProps = cloneObj(props); - columnProps.push(clonedProps); + columnProps.push(cloneObj(props)); } }; @@ -270,11 +276,16 @@ DataController.prototype.resetConditionalFormatting = function () { * @see getTotalFunction */ DataController.prototype.TOTAL_FUNCTIONS = { + + isNumber: function (a) { + if (a == "") return false; + return isFinite(a); + }, totalSUM: function (array, iStart, iEnd, column) { var sum = 0; for (var i = iStart; i < iEnd; i++) { - if (isFinite(array[i][column]["value"])) { + if (this.isNumber(array[i][column]["value"])) { sum += parseFloat(array[i][column]["value"]) || 0; } } @@ -284,7 +295,7 @@ DataController.prototype.TOTAL_FUNCTIONS = { totalAVG: function (array, iStart, iEnd, column) { var sum = 0; for (var i = iStart; i < iEnd; i++) { - if (!isFinite(array[i][column]["value"])) { + if (!this.isNumber(array[i][column]["value"])) { sum = 0; break; } @@ -300,7 +311,7 @@ DataController.prototype.TOTAL_FUNCTIONS = { totalMIN: function (array, iStart, iEnd, column) { var min = Infinity; for (var i = iStart; i < iEnd; i++) { - if (isFinite(array[i][column]["value"]) && array[i][column]["value"] < min) { + if (this.isNumber(array[i][column]["value"]) && array[i][column]["value"] < min) { min = array[i][column]["value"]; } } @@ -310,7 +321,7 @@ DataController.prototype.TOTAL_FUNCTIONS = { totalMAX: function (array, iStart, iEnd, column) { var max = -Infinity; for (var i = iStart; i < iEnd; i++) { - if (isFinite(array[i][column]["value"]) && array[i][column]["value"] > max) { + if (this.isNumber(array[i][column]["value"]) && array[i][column]["value"] > max) { max = array[i][column]["value"]; } } @@ -332,6 +343,21 @@ DataController.prototype.TOTAL_FUNCTIONS = { }; +DataController.prototype.setLeftHeaderColumnsNumber = function (data) { + + function getLev (o, lev) { + if (!(o.children instanceof Array)) return lev; + var nextLev = lev + 1; + for (var i = 0; i < o.children.length; i++) { + lev = Math.max(getLev(o.children[i], nextLev), lev); + } + return lev; + } + + data.info.leftHeaderColumnsNumber = getLev({ children: data.dimensions[1] || [] }, 0); + +}; + /** * Renders table data (pseudo-table object) from data retrieved from MDX2JSON source. * @@ -540,7 +566,7 @@ DataController.prototype.resetRawData = function () { var pivotDefault = _.controller.getPivotProperty(["rowTotalAgg"]); if (!data["columnProps"][columnIndex] && !pivotDefault) return _.TOTAL_FUNCTIONS.totalSUM; - switch (data["columnProps"][columnIndex].summary || pivotDefault) { + switch ((data["columnProps"][columnIndex] || {}).summary || pivotDefault) { case "count": return _.TOTAL_FUNCTIONS.totalCOUNT; case "avg": return _.TOTAL_FUNCTIONS.totalAVG; case "min": return _.TOTAL_FUNCTIONS.totalMIN; @@ -570,7 +596,7 @@ DataController.prototype.resetRawData = function () { applyHeaderStyle(summary[i], false); } else { summary[i] = { - value: getTotalFunction(parseInt(i) - data.info.leftHeaderColumnsNumber).call( + value: getTotalFunction(parseInt(i)).call( this.TOTAL_FUNCTIONS, rawData, xh, rawData.length, i, data.info.leftHeaderColumnsNumber ), diff --git a/source/js/PivotView.js b/source/js/PivotView.js index 7ed8d40..2583382 100644 --- a/source/js/PivotView.js +++ b/source/js/PivotView.js @@ -834,6 +834,63 @@ PivotView.prototype.recalculateSizes = function (container) { }; +/** + * Converts retrieved from mdx2json date to JS date format. + * @param {string} s Date as string + * @returns {number} Date as number + * @author Anton Gnibeda (https://github.com/gnibeda) + */ +PivotView.prototype.getUnixDateFromCacheFormat = function (s) { + function addDays(date, days) { + var result = new Date(date); + result.setDate(date.getDate() + days); + return result; + } + function getDate(str) { + var months = [ + "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" + ]; + + var d = Date.parse(str); + if (!isNaN(d)) return d; + if (str.split("-").length == 2) { + var parts = str.split("-"); + var idx = months.indexOf(parts[0].toLowerCase()); + if (idx != -1) { + return Date.parse((idx+1).toString() + "/01/" + parts[1]); + } + } else + if (str.split(" ").length == 2) { + //like 2015-01-07 05 + var timeParts = str.split(" ")[1].split(":").length; + if (timeParts === 0) str += ":00"; + d = Date.parse(str.replace(/-/g, "/")); + if (!isNaN(d)) return d; + } + return 0; + } + if (s === "" && s === undefined || s === null) return null; + var str = s.toString(); + if (str.length == 4) return getDate(s); + if (str.indexOf("-") != -1) return getDate(s); + if (str.indexOf(" ") != -1) return getDate(s); + if (str.length == 6) { + var y = str.substr(0, 4); + var m = str.substr(4, 2); + return Date.parse(new Date(parseInt(y), parseInt(m)-1, 1)); + } + if (str.length == 5 && !isNaN(parseInt(str))) { + var base = new Date(1840, 11, 31); + var p = str.toString().split(","); + var d = parseInt(p[0]); + var t = null; + if (p.length > 1) t = parseInt(p[1]); + base = addDays(base, parseInt(d)); + if (t) base.setSeconds(t); + return Date.parse(base); + } else return getDate(s); +}; + /** * Raw data - plain 2-dimensional array of data to render. * @@ -924,7 +981,12 @@ PivotView.prototype.renderRawData = function (data) { + p + ""; }); } else if (!LISTING) { // number - if (format) { // set format + if (format === "%date%") { // Cach? internal date + var d = new Date(_.getUnixDateFromCacheFormat(value)); + if (isNaN(d.getTime())) { element.textContent = value; return; } + element.textContent = d.getHours() + d.getMinutes() + d.getSeconds() === 0 + ? d.toLocaleDateString() : d.toLocaleString(); + } else if (format) { // set format element.textContent = value ? _.numeral(value).format(format) : ""; } else if (value) { element.textContent = _.numeral(value).format( @@ -1074,7 +1136,7 @@ PivotView.prototype.renderRawData = function (data) { if (!rawData[y][x].isCaption) formatContent( rawData[y][x].value, th, - columnProps[x - info.leftHeaderColumnsNumber].format + columnProps[x].format ); } @@ -1169,7 +1231,7 @@ PivotView.prototype.renderRawData = function (data) { formatContent( rawData[y][x].value, div, - columnProps[x - info.leftHeaderColumnsNumber].format + columnProps[x].format ); if ( colorScale