diff --git a/extensions/js/c3ext.js b/extensions/js/c3ext.js index 1284c8c..8ff301f 100644 --- a/extensions/js/c3ext.js +++ b/extensions/js/c3ext.js @@ -35,7 +35,7 @@ c3ext.generate = function (options) { refresh(); } - var zoom2 = ZoomBehavior.create({ changed: onZoomChanged, bindto:options.bindto }); + var zoom2 = c3ext.ZoomBehavior({ changed: onZoomChanged, bindto: options.bindto }); zoom2.enhance = function () { _zoom2_maxItems *= 2; @@ -57,12 +57,14 @@ c3ext.generate = function (options) { var list3 = list2; if (list3.length > maxItems) { var chunkSize = Math.ceil(list2.length / maxItems); - list3 = list3.splitIntoChunksOf(chunkSize).select(func); + list3 = list3.splitIntoChunksOf(chunkSize).map(func); } //console.log("x" + getCurrentZoomLevel() + ", maxItems=" + maxItems + " chunkSize=" + chunkSize + " totalBefore=" + list2.length + ", totalAfter=" + list3.length); return list3; } + function first(t) { return t[0]; } + var getDataForZoom = function (data) { if (data.columns == null || data.columns.length == 0) return; @@ -72,9 +74,9 @@ c3ext.generate = function (options) { zoom2.setOptions({ totalItems: data.columns[0].length - 1 }); zoomInfo = zoom2.getZoom(); } - data.columns = originalData.columns.select(function (column) { + data.columns = originalData.columns.map(function (column) { var name = column[0]; - var reducer = zoom2_reducers[name] || "t=>t[0]".toLambda(); //by default take the first + var reducer = zoom2_reducers[name] || first; //by default take the first var values = column.slice(1); var newValues = zoomAndReduceData(values, zoomInfo.currentZoom, reducer, _zoom2_maxItems); @@ -115,9 +117,7 @@ c3ext.generate = function (options) { return chart; } - -var ZoomBehavior = {}; -ZoomBehavior.create = function (options) { +c3ext.ZoomBehavior = function (options) { var zoom = { __type: "ZoomBehavior" }; var _zoom2_factor; @@ -185,7 +185,7 @@ ZoomBehavior.create = function (options) { zoom.getZoom = function () { - return { totalItems: totalItems, currentZoom: currentZoom.toArray() }; + return { totalItems: totalItems, currentZoom: currentZoom.slice() }; } zoom.factor = function (factor, skipDraw) { @@ -252,8 +252,6 @@ ZoomBehavior.create = function (options) { applyZoomAndPan(); } - - function doZoom() { if (deltaY != 0) { var maxDelta = 10; @@ -284,4 +282,99 @@ ZoomBehavior.create = function (options) { return zoom; +} + +if (typeof (Q) == "undefined") { + var Q = function () { + }; + + Q.copy = function (src, target, options, depth) { + ///Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists + /// + /// + ///{ overwrite:false } + ///The copied object + if (depth == null) + depth = 0; + if (depth == 100) { + console.warn("Q.copy is in depth of 100 - possible circular reference") + } + options = options || { overwrite: false }; + if (src == target || src == null) + return target; + if (typeof (src) != "object") { + if (options.overwrite || target == null) + return src; + return target; + } + if (typeof (src.clone) == "function") { + if (options.overwrite || target == null) + return src.clone(); + return target; + } + if (target == null) { + if (src instanceof Array) + target = []; + else + target = {}; + } + + if (src instanceof Array) { + for (var i = 0; i < src.length; i++) { + var item = src[i]; + var item2 = target[i]; + item2 = Q.copy(item, item2, options, depth + 1); + target[i] = item2; + } + target.splice(src.length, target.length - src.length); + return target; + } + for (var p in src) { + var value = src[p]; + var value2 = target[p]; + value2 = Q.copy(value, value2, options, depth + 1); + target[p] = value2; + } + return target; + } +} +if (typeof (Timer) == "undefined") { + var Timer = function (action, ms) { + this.action = action; + if (ms != null) + this.set(ms); + } + + Timer.prototype.set = function (ms) { + if (ms == null) + ms = this._ms; + else + this._ms = ms; + this.clear(); + if (ms == null) + return; + this.timeout = window.setTimeout(this.onTick.bind(this), ms); + } + + Timer.prototype.onTick = function () { + this.clear(); + this.action(); + } + + Timer.prototype.clear = function (ms) { + if (this.timeout == null) + return; + window.clearTimeout(this.timeout); + this.timeout = null; + } +} +if (typeof(Array.prototype.splitIntoChunksOf)=="undefined") { + Array.prototype.splitIntoChunksOf = function (countInEachChunk) { + var chunks = Math.ceil(this.length / countInEachChunk); + var list = []; + for (var i = 0; i < this.length; i += countInEachChunk) { + list.push(this.slice(i, i + countInEachChunk)); + } + return list; + } } \ No newline at end of file diff --git a/extensions/js/utils.js b/extensions/js/utils.js deleted file mode 100644 index cb728f6..0000000 --- a/extensions/js/utils.js +++ /dev/null @@ -1,1504 +0,0 @@ -var Q = function () { -}; - -Q.copy = function (src, target, options, depth) { - if(depth==null) - depth = 0; - if(depth==100){ - console.warn("Q.copy is in depth of 100 - possible circular reference") - } - ///Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists - /// - /// - ///{ overwrite:false } - ///The copied object - options = options || { overwrite: false }; - if (src == target || src == null) - return target; - if (typeof (src) != "object") { - if (options.overwrite || target == null) - return src; - return target; - } - if (typeof(src.clone)=="function") { - if (options.overwrite || target == null) - return src.clone(); - return target; - } - if (target == null) { - if (src instanceof Array) - target = []; - else - target = {}; - } - - if (src instanceof Array) { - for (var i = 0; i < src.length; i++) { - var item = src[i]; - var item2 = target[i]; - item2 = Q.copy(item, item2, options, depth+1); - target[i] = item2; - } - target.splice(src.length, target.length - src.length); - return target; - } - for (var p in src) { - var value = src[p]; - var value2 = target[p]; - value2 = Q.copy(value, value2, options, depth+1); - target[p] = value2; - } - return target; -} - -Object.reversePairs = function (obj) { - var list = []; - for (var i = 0; i < obj.length; i++) { - list.push([obj[i][1],obj[i][0]]); - } - return list; -} -Q.objectToNameValueArray = function () { - var list = []; - for (var p in this.obj) { - list.push({ name: p, value: this.obj[p] }); - } - return list; -} - - -Array.prototype.forEachJoin = function (action, actionBetweenItems) { - var first = true; - for (var i = 0; i < this.length; i++) { - if (first) - first = false; - else - actionBetweenItems(); - action(this[i]); - } -} -Array.prototype.first = function (predicate) { - if (predicate == null) - return this[0]; - for (var i = 0; i < this.length; i++) { - if (predicate(this[i])) - return this[i]; - } - return null; -} -Array.prototype.toArray = function () { - return this.slice(0, this.length); -} - -Array.prototype.insert = function (index, item) { - this.splice(index, 0, item); -} -Array.prototype.last = function (predicate) { - if (this.length == 0) - return null; - if (predicate == null) - return this[this.length - 1]; - for (var i = this.length; i >= 0; i--) { - if (predicate(this[i])) - return this[i]; - } - return null; -} -Q.objectValuesToArray = function (obj) { - var list = []; - for (var p in obj) { - list.push(obj[p]); - } - return list; -} -Object.values = Q.objectValuesToArray; -Object.toArray = function (obj) { - var list = []; - for (var p in obj) { - list.push(p, obj[p]); - } - return list; -} -Object.allKeys = function (obj) { - var list = []; - for (var p in obj) { - list.push(p); - } - return list; -} -Object.keysValues = function (obj) { - var list = []; - for (var p in obj) { - list.push({ key: p, value: obj[p] }); - } - return list; -} - -Object.pairs = function (obj) { - var list = []; - list.isArrayOfPairs = true; - for (var p in obj) { - list.push([p, obj[p]]); - } - return list; -} -Object.fromPairs = function (keysValues) { - var obj = {}; - keysValues.forEach(function (pair) { - obj[pair[0]] = pair[1]; - }); - return obj; -} -Q.cloneJson = function (obj) { - if (obj == null) - return null; - return JSON.parse(JSON.stringify(obj)); -}; -Q.forEachValueInObject = function (obj, func, thisArg) { - for (var p in obj) { - func.call(thisArg, obj[p]); - } -}; -Array.prototype.toObject = function (selector) { - if (selector == null) { - return this.copyPairsToObject(); - } - var obj = {}; - for (var i = 0; i < this.length; i++) { - var obj2 = selector(this[i]); - if (obj2 instanceof Array) - obj2.copyPairsToObject(obj); - else { - for (var p in obj2) - obj[p] = obj2[p]; - } - } - return obj; -}; -Array.prototype.copyPairsToObject = function (obj) { - if (obj == null) - obj = {}; - for (var i = 0; i < this.length; i += 2) { - obj[this[i]] = this[i + 1]; - } - return obj; -}; -//Object.keys = Q.keys; -Object.toSortedByKey = function (obj) { - var sortedKeys = Object.keys(obj).sort(); - return sortedKeys.toObject(function (key) { return [key, obj[key]]; }) -} -Q.mapKeyValueInArrayOrObject = function (objOrList, func, thisArg) { - var list = []; - if (objOrList instanceof Array) { - for (var i = 0; i < objOrList.length; i++) { - list.push(func.call(thisArg, i, objOrList[i])); - } - } - else { - for (var p in objOrList) { - list.push(func.call(thisArg, p, objOrList[p])); - } - } - return list; -}; -//Alternative to $.map of jquery - which has array reducers overhead, and sometimes causes stackOverflow -Q.jMap = function (objOrList, func, thisArg) { - var list = []; - if (objOrList instanceof Array) { - for (var i = 0; i < objOrList.length; i++) { - list.push(func.call(thisArg, objOrList[i], i)); - } - } - else { - for (var p in objOrList) { - list.push(func.call(thisArg, objOrList[p], p)); - } - } - return list; -}; -///Returns if the parameter is null, or an empty json object -Q.isEmptyObject = function (obj) { - if (obj == null) - return true; - if (typeof (obj) != "object") - return false; - for (var p in obj) - return false; - return true; -}; - -Q.min = function (list) { - return Math.min.apply(null, list); -}; -Q.max = function (list) { - return Math.max.apply(null, list); -}; - -function toStringOrEmpty(val) { - return val == null ? "" : val.toString(); -} - -Object.getCreateArray = function (obj, p) { - var value = obj[p]; - if (value == null) { - value = []; - obj[p] = value; - } - return value; -} - -Array.prototype.removeLast = Array.prototype.pop; -Array.prototype.removeFirst = function () { - return this.splice(0, 1)[0]; -} - -Array.prototype.remove = function (item) { - for (var i = 0; i < this.length; i++) { - if (this[i] === item) { - this.removeAt(i); - return true; - } - } - return false; -} -Array.prototype.removeRange = function (items) { - items.forEach(function (t) { this.remove(t); }); -} -String.prototype.contains = function (s) { - return this.indexOf(s) >= 0; -} -Array.prototype.contains = function (s) { - return this.indexOf(s) >= 0; -} -Array.prototype.containsAny = function (items) { - return items.any(function (t) { return this.contains(t); }.bind(this)); -} -Array.prototype.any = function (predicate) { - return this.some(Q.createSelectorFunction(predicate)); -} -Array.prototype.distinct = function (keyGen) { - if (keyGen == null) - keyGen = Object.getHashKey; - var list = []; - var set = {}; - this.forEach(function (t) { - var key = keyGen(t); - if (set[key]) - return; - set[key] = true; - list.push(t); - }); - return list; -} - - -Array.prototype.removeAll = function (predicate) { - var toRemove = []; - for (var i = 0; i < this.length; i++) { - if (predicate(this[i])) { - toRemove.push(i); - } - } - while (toRemove.length > 0) { - var index = toRemove.pop(); - this.removeAt(index); - } -} - - -Array.prototype.removeAt = function (index) { - this.splice(index, 1); -} - -Q.stringifyFormatted = function (obj) { - var sb = []; - sb.indent = ""; - sb.indentSize = " "; - sb.startBlock = function (s) { - this.indent += sb.indentSize; - this.push(s); - this.newLine(); - }; - sb.endBlock = function (s) { - this.indent = this.indent.substr(0, this.indent.length - this.indentSize.length); - this.newLine(); - this.push(s); - }; - sb.newLine = function (s) { - this.push("\n"); - this.push(this.indent); - }; - Q.stringifyFormatted2(obj, sb); - return sb.join(""); -} -Q.stringifyFormatted2 = function (obj, sb) { - var type = typeof (obj); - if (type == "object") { - if (obj instanceof Array) { - var list = obj; - if (list.length == 0 || ["string", "number"].contains(typeof (list[0]))) { - sb.push("["); - list.forEach(function (t, i) { - Q.stringifyFormatted2(t, sb); - if (i < list.length - 1) - sb.push(","); - }); - sb.push("]"); - } - else { - sb.startBlock("["); - for (var i = 0; i < list.length; i++) { - Q.stringifyFormatted2(list[i], sb); - if (i < list.length - 1) { - sb.push(","); - sb.newLine(); - } - } - sb.endBlock("]"); - } - } - else { - sb.startBlock("{"); - var first = true; - for (var p in obj) { - if (first) - first = false; - else { - sb.push(","); - sb.newLine(); - } - sb.push(p + ": "); - Q.stringifyFormatted2(obj[p], sb); - } - sb.endBlock("}"); - } - } - else { - sb.push(JSON.stringify(obj)); - } -} - -///Iterates over the array, performing an async function for each item, going to the next one only when the previous one has finished (called his callback) -Array.prototype.forEachAsyncProgressive = function (actionWithCallback, finalCallback) { - this._forEachAsyncProgressive(actionWithCallback, finalCallback, 0); -} - -Array.prototype.where = function (predicate) { - return this.filter(Q.createSelectorFunction(predicate)); -} -Array.prototype.addRange = function (items) { - this.push.apply(this, items); -} - -Array.prototype.add = Array.prototype.push; -Array.prototype.diff = function (target) { - var source = this; - var res = { - added: source.where(function (t) { return !target.contains(t); }), - removed: target.where(function (t) { return !source.contains(t); }), - }; - return res; -} -Array.prototype.hasDiff = function (target) { - var diff = this.diff(target); - return diff.added.length > 0 || diff.removed.length > 0; -} - -Array.prototype._forEachAsyncProgressive = function (actionWithCallback, finalCallback, index) { - if (index == null) - index = 0; - if (index >= this.length) { - if (finalCallback != null) - finalCallback(); - return; - } - var item = this[index]; - actionWithCallback(item, function () { this._forEachAsyncProgressive(actionWithCallback, finalCallback, index + 1); }.bind(this)); -} - - -/// Iterates over the array, performing an async function for each item, going to the next one only when the previous one has finished (called his callback) -Array.prototype.mapAsyncProgressive = function (actionWithCallback, finalCallback) { - this._mapAsyncProgressive(actionWithCallback, finalCallback, 0, []); -} - -Array.prototype._mapAsyncProgressive = function (actionWithCallbackWithResult, finalCallback, index, results) { - if (index == null) - index = 0; - if (index >= this.length) { - if (finalCallback != null) - finalCallback(results); - return; - } - var item = this[index]; - actionWithCallbackWithResult(item, function (res) { - results.push(res); - this._mapAsyncProgressive(actionWithCallbackWithResult, finalCallback, index + 1, results); - }.bind(this)); -} - -Array.prototype.mapWith = function (anotherList, funcForTwoItems) { - if (funcForTwoItems == null) - funcForTwoItems = function (x, y) { return [x, y]; }; - var list = []; - var maxLength = Math.max(this.length, anotherList.length); - for (var i = 0; i < maxLength; i++) - list.push(funcForTwoItems(this[i], anotherList[i])); - return list; -} - -Array.prototype.min = function () { - var min = null; - for (var i = 0; i < this.length; i++) { - var value = this[i]; - if (min==null || value < min) - min = value; - } - return min; -} - -Array.prototype.max = function () { - var max = null; - for (var i = 0; i < this.length; i++) { - var value = this[i]; - if (max == null || value > max) - max = value; - } - return max; -} - -Array.prototype.getEnumerator = function () { - return new ArrayEnumerator(this); -} - -var ArrayEnumerator = function (list) { - this.index = -1; - this.list = list; -} - -ArrayEnumerator.prototype.moveNext = function () { - if (this.index == -2) - throw new Error("End of array"); - this.index++; - if (this.index >= this.list.length) { - this.index = -2; - return false; - } - return true; -} -ArrayEnumerator.prototype.getCurrent = function () { - if (this.index < 0) - throw new Error("Invalid array position"); - return this.list[this.index]; -} - -String.prototype.endsWith = function (suffix) { - return this.indexOf(suffix, this.length - suffix.length) !== -1; -}; - -var Comparer = function () { - -} -Comparer.prototype.compare = function (x, y) { - if (x > y) - return 1; - if (x < y) - return -1; - return 0; -} -Comparer.default = new Comparer(); - -function combineCompareFuncs(compareFuncs) { - return function (a, b) { - var count = compareFuncs.length; - for (var i = 0; i < count; i++) { - var compare = compareFuncs[i]; - var x = compare(a, b); - if (x != 0) - return x; - } - return 0; - }; -} - -function createCompareFuncFromSelector(selector, desc) { - desc = desc ? -1 : 1; - var compare = Comparer.default.compare; - var type = typeof (selector); - if (type == "string" || type == "number") { - return function (x, y) { - return compare(x[selector], y[selector]) * desc; - }; - } - return function (x, y) { - return compare(selector(x), selector(y)) * desc; - }; -} -Array.prototype.sortBy = function (selector, desc) { - var compareFunc; - if (selector instanceof Array) { - var pairs = selector; - var funcs = pairs.map(function (pair) { - if (pair instanceof Array) - return createSortFuncFromCompareFunc(pair[0], pair[1]); - return createCompareFuncFromSelector(pair); - }); - compareFunc = combineCompareFuncs(funcs); - } - else { - compareFunc = createCompareFuncFromSelector(selector, desc); - } - this.sort(compareFunc); - return this; -} - -Array.prototype.sortByDescending = function (selector) { - return this.sortBy(selector, true); -} -String.prototype.startsWith = function (s) { - return this.indexOf(s) == 0; -} - -//Performs an async function on each item in the array, invoking a finalCallback when all are completed -//asyncFunc -> function(item, callback -> function(result)) -//finalCallback -> function(results); -Array.prototype.mapAsyncParallel = function (asyncFunc, finalCallback) { - var results = []; - var length = this.length; - if (length == 0) { - finalCallback(results); - return; - } - var cb = function (res) { - results.push(res); - if (results.length == length) - finalCallback(results); - }; - for (var i = 0; i < length; i++) { - var item = this[i]; - asyncFunc(item, cb); - } -} - - -Array.prototype.clear = function () { - this.splice(0, this.length); -} - - -var Timer = function (action, ms) { - this.action = action; - if(ms!=null) - this.set(ms); -} - -Timer.prototype.set = function (ms) { - if(ms==null) - ms = this._ms; - else - this._ms = ms; - this.clear(); - if(ms==null) - return; - this.timeout = window.setTimeout(this.onTick.bind(this), ms); -} - -Timer.prototype.onTick = function () { - this.clear(); - this.action(); -} - -Timer.prototype.clear = function (ms) { - if (this.timeout == null) - return; - window.clearTimeout(this.timeout); - this.timeout = null; -} - -Array.prototype.itemsEqual = function (list) { - if (list == this) - return true; - if (list.length != this.length) - return false; - for (var i = 0; i < this.length; i++) - if (this[i] != list[i]) - return false; - return true; - -} - -Number.prototype.format = function (format) { - var s = this.toString(); - for (var i = 0; i < format.length; i++) { - var ch = format.charAt(i); - if (ch == "0") { - if (s.length < i + 1) - s = "0" + s; - } - else - throw new Error("not implemented"); - } - return s; -} - - -/** - * ReplaceAll by Fagner Brack (MIT Licensed) - * Replaces all occurrences of a substring in a string - */ -String.prototype.replaceAll = function (token, newToken, ignoreCase) { - var _token; - var str = this + ""; - var i = -1; - - if (typeof token === "string") { - - if (ignoreCase) { - - _token = token.toLowerCase(); - - while (( - i = str.toLowerCase().indexOf( - token, i >= 0 ? i + newToken.length : 0 - )) !== -1 - ) { - str = str.substring(0, i) + - newToken + - str.substring(i + token.length); - } - - } else { - return this.split(token).join(newToken); - } - - } - return str; -}; - - - - - - - -/* Date extensions, taken from jsclr framework */ -Date.new = function (y, m, d, h, mm, s, ms) { - if (ms != null) - return new Date(y, m - 1, d, h, mm, s, ms); - if (s != null) - return new Date(y, m - 1, d, h, mm, s); - if (mm != null) - return new Date(y, m - 1, d, h, mm); - if (h != null) - return new Date(y, m - 1, d, h); - if (d != null) - return new Date(y, m - 1, d); - if (m != null) - return new Date(y, m - 1); - if (y != null) - return new Date(y); - var x = new Date(0); - x.setHours(0, 0, 0, 0); - return x; -} -Date.prototype.compareTo = function (value) { - return this.valueOf() - value.valueOf(); -}; -Date.prototype.year = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCFullYear(); - return this.getFullYear(); - } - if (this._Kind == 1) - this.setUTCFullYear(value); - else - this.setFullYear(value); - return this; -}; -Date.prototype.totalDays = function () { - return this.valueOf() / (24 * 60 * 60 * 1000); -}; -Date.prototype.totalHours = function () { - return this.valueOf() / (60 * 60 * 1000); -}; - -Date.prototype.month = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCMonth() + 1; - return this.getMonth() + 1; - } - if (this._Kind == 1) - this.setUTCMonth(value - 1); - else - this.setMonth(value - 1); - return this; -}; -Date.prototype.day = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCDate(); - return this.getDate(); - } - if (this._Kind == 1) - this.setUTCDate(value); - else - this.setDate(value); - return this; -}; -Date.prototype.hour = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCHours(); - return this.getHours(); - } - if (this._Kind == 1) - this.setUTCHours(value); - else - this.setHours(value); - return this; -}; -Date.prototype.minute = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCMinutes(); - return this.getMinutes(); - } - if (this._Kind == 1) - this.setUTCMinutes(value); - else - this.setMinutes(value); - return this; -}; -Date.prototype.second = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCSeconds(); - return this.getSeconds(); - } - if (this._Kind == 1) - this.setUTCSeconds(value); - else - this.setSeconds(value); - return this; -}; -Date.prototype.ms = function (value) { - if (value == null) { - if (this._Kind == 1) - return this.getUTCMilliseconds(); - return this.getMilliseconds(); - } - if (this._Kind == 1) - this.setUTCMilliseconds(value); - else - this.setMilliseconds(value); - return this; -}; -Date.prototype.toUnix = function () { - if (this._Kind == 1) - throw new Error(); - return Math.round(this.getTime() / 1000); -}; -Date.fromUnix = function (value) { - return new Date(value * 1000); -}; - -Date.prototype.dayOfWeek = function () { - return this.getDay()+1; -}; -Date.prototype.toLocalTime = function () { - if (this._Kind != 1) - return this; - var x = this.clone(); - x._Kind = 2; - return x; -}; -Date.prototype.toUniversalTime = function () { - if (this._Kind == 1) - return this; - var x = this.clone(); - x._Kind = 1; - return x; -}; -Date.today = function () { - return new Date().removeTime(); -}; -//Date.now = function () { -// return new Date(); -//}; -Date.prototype.subtract = function (date) { - var diff = this.valueOf() - date.valueOf(); - return new Date(diff); -}; -Date.prototype.Subtract$$DateTime = function (value) { - var diff = this.valueOf() - value.valueOf(); - return new System.TimeSpan.ctor$$Int64(diff * 10000); -}; -Date.prototype.Subtract$$TimeSpan = function (value) { - var newDate = this.clone(); - newDate.setMilliseconds(this.getMilliseconds() + value.getTotalMilliseconds()); - return newDate; -}; -Date.prototype.format = function (format) { - if (typeof (format) == "object") { - var options = format; - if (options.noTime!=null && !this.hasTime()) - return this.format(options.noTime); - else if (options.noDate!=null && !this.hasDate()) - return this.format(options.noDate); - else if (options.fallback!=null) - return this.format(options.fallback); - return this.toString(); - } - var s = format; - s = s.replaceAll("yyyy", this.year().format("0000")); - s = s.replaceAll("yy", this.year().format("00").truncateStart(2)); - s = s.replaceAll("y", this.year().toString()); - s = s.replaceAll("MM", this.month().format("00")); - s = s.replaceAll("M", this.month().toString()); - s = s.replaceAll("dd", this.day().format("00")); - s = s.replaceAll("d", this.day().toString()); - s = s.replaceAll("HH", this.hour().format("00")); - s = s.replaceAll("H", this.hour().toString()); - s = s.replaceAll("mm", this.minute().format("00")); - s = s.replaceAll("m", this.minute().toString()); - s = s.replaceAll("ss", this.second().format("00")); - s = s.replaceAll("s", this.second().toString()); - return s.toString(); -}; -String.prototype.truncateEnd = function (finalLength) { - if (this.length > finalLength) - return this.substr(0, finalLength); - return this; -} -String.prototype.truncateStart = function (finalLength) { - if (this.length > finalLength) - return this.substr(this.length-finalLength); - return this; -} -String.prototype.remove = function (index, length) { - var s = this.substr(0, index); - s += this.substr(index + length); - return s; -} -String.prototype.insert = function (index, text) { - var s = this.substr(0, index); - s += text; - s += this.substr(index); - return s; -} -String.prototype.replaceAt = function (index, length, text) { - return this.remove(index, length).insert(index, text); -} -String.prototype.padRight = function (totalWidth, paddingChar) { - if (paddingChar == null || paddingChar == "") - paddingChar = " "; - var s = this; - while (s.length < totalWidth) - s += paddingChar; - return s; -} -String.prototype.padLeft = function (totalWidth, paddingChar) { - if (paddingChar == null || paddingChar == "") - paddingChar = " "; - var s = this; - while (s.length < totalWidth) - s = paddingChar + s; - return s; -} - -Date._parsePart = function (ctx, part, setter) { - if (ctx.failed) - return; - var index = ctx.format.indexOf(part); - if (index < 0) - return; - var token = ctx.s.substr(index, part.length); - if (token.length == 0) { - ctx.failed = true; - return; - } - var value = Q.parseInt(token); - if (value == null) { - ctx.failed = true; - return; - } - setter.call(ctx.date, value); - ctx.format = ctx.format.replaceAt(index, part.length, "".padRight(part.length)); - ctx.s = ctx.s.replaceAt(index, part.length, "".padRight(part.length)); -} -Date.tryParseExact = function (s, formats) { - if (typeof (formats) == "string") - formats = [formats]; - for (var i = 0; i < formats.length; i++) { - var x = Date._tryParseExact(s, formats[i]); - if (x != null) - return x; - } - return null; -}; -Date._tryParseExact = function (s, format) { - if (s.length != format.length) - return null; - var date = Date.new(); - var ctx = { date: date, s: s, format: format }; - Date._parsePart(ctx, "yyyy", date.year); - Date._parsePart(ctx, "yy", date.year); - Date._parsePart(ctx, "MM", date.month); - Date._parsePart(ctx, "dd", date.day); - Date._parsePart(ctx, "HH", date.hour); - Date._parsePart(ctx, "mm", date.minute); - Date._parsePart(ctx, "ss", date.second); - if (ctx.failed) - return null; - if (ctx.s != ctx.format) - return null; - return ctx.date; -}; -Date.prototype.clone = function () { - var x = new Date(this.valueOf()); - x._Kind = this._Kind; - return x; -}; -Date.prototype.addMs = function (miliseconds) { - var date2 = this.clone(); - date2.setMilliseconds(date2.getMilliseconds() + miliseconds); - return date2; -}; -Date.prototype.addSeconds = function (seconds) { - var date2 = this.clone(); - date2.setSeconds(date2.getSeconds() + seconds); - return date2; -}; -Date.prototype.addMinutes = function (minutes) { - var date2 = this.clone(); - date2.setMinutes(date2.getMinutes() + minutes); - return date2; -}; -Date.prototype.addHours = function (hours) { - var date2 = this.clone(); - date2.setHours(date2.getHours() + hours); - return date2; -}; -Date.prototype.addDays = function (days) { - var date2 = this.clone(); - date2.setDate(date2.getDate() + days); - return date2; -}; -Date.prototype.addMonths = function (months) { - var date2 = this.clone(); - date2.setMonth(date2.getMonth() + months); - return date2; -}; -Date.prototype.addYears = function (years) { - var date2 = this.clone(); - date2.setMonth(date2.getFullYear() + years); - return date2; -}; -Date.prototype.removeTime = function () { - var date2 = this.clone(); - date2.setHours(0, 0, 0, 0); - return date2; -}; -Date.prototype.hasTime = function () { - return this.hour() != 0 && this.second() != 0 && this.ms() != 0; -}; -Date.prototype.hasDate = function () { - var date2 = new Date(0); - return this.year() != date2.year() && this.month() != date2.month() && this.day() != date2.day(); -}; -Date.prototype.removeDate = function () { - var time = this.clone(); - time.setHours(this.hour(), this.minute(), this.second(), this.ms()); - return time; -}; -Date.prototype.extractTime = function () { - return this.removeDate(); -}; -Date.prototype.extractDate = function () { - return this.removeTime(); -}; -Date.prototype.equals = function (obj) { - if (obj == null) - return false; - return obj.valueOf() == this.valueOf(); -}; -Date.prototype.GetHashCode = function () { - return this.valueOf(); -}; -Date.prototype.getKind = function () { - if (this._Kind == null) - return 2; - return this._Kind; -}; - - - -/* Binds all function on an object to the object, so the 'this' context will be reserved even if referencing the function alone */ -Q.bindFunctions = function (obj) { - for (var p in obj) { - var func = obj[p]; - if (typeof (func) != "function") - continue; - if (func.boundTo == obj) - continue; - func = func.bind(obj); - func.boundTo = obj; - if (func.name == null) - func.name = p; - obj[p] = func; - } -} - -// Similar to func.apply(thisContext, args), but creates a new object instead of just calling the function - new func(args[0], args[1], args[2]...) -Function.prototype.applyNew = function (args) { - var args2 = args.toArray(); - args2.insert(0, null); - var ctor2 = this.bind.apply(this, args2); - var obj = new ctor2(); - return obj; -} -// Similar to func.call(thisContext, args), but creates a new object instead of just calling the function - new func(arguments[0], arguments[1], arguments[2]...) -Function.prototype.callNew = function (varargs) { - var args2 = Array.prototype.slice.call(arguments); - args2.insert(0, null); - var ctor2 = this.bind.apply(this, args2); - var obj = new ctor2(); - return obj; -} - -Error.prototype.wrap = function (e) { - e.innerError = this; - return e; -} - -Error.prototype.causedBy = function (e) { - this.innerError = e; -} - -Q.parseInt = function(s){ - var intRegex = /^[+-]?[0-9]+$/; - if (!intRegex.test(s)) - return null; - var x = parseInt(s); - if (isNaN(x)) - return null; - return x; -} - -Q.parseFloat = function (s) { - var floatRegex = /^[+-]?[0-9]*[\.]?[0-9]*$/; - if (!floatRegex.test(s)) - return null; - var x = parseFloat(s); - if (isNaN(x)) - return null; - return x; -} - -Number.prototype.round = function (decimals) { - if (decimals) { - var x = Math.pow(10, decimals); - return Math.round(this * x) / x; - } - return Math.round(this); -} -Q.createSelectorFunction = function(selector){ - if (selector == null) - return function (t) { return t; }; - if (typeof (selector) == "function") - return selector; - return function (t) { return t[selector]; }; -} -Array.prototype.select = function (selector) { - var func = Q.createSelectorFunction(selector); - return this.map(func); -} - -Array.prototype.selectInvoke = function (name) { - return this.map(function (t) { return t[name](); }); -} - -Array.prototype.joinWith = function (list2, keySelector1, keySelector2, resultSelector) { - keySelector1 = Q.createSelectorFunction(keySelector1); - keySelector2 = Q.createSelectorFunction(keySelector2); - resultSelector = Q.createSelectorFunction(resultSelector); - - var list1 = this; - - var groups1 = list1.groupByToObject(keySelector1); - var groups2 = list2.groupByToObject(keySelector2); - - var list = []; - var group = {}; - for (var p in groups1) { - if(groups2[p]!=null) - list.push(resultSelector(groups1[p], groups2[p])); - } - - return list; -} -Array.prototype.all = function (predicate) { - return this.every(Q.createSelectorFunction(predicate)); -} - -String.prototype.all = Array.prototype.all; -String.prototype.every = Array.prototype.every; -Array.prototype.flatten = function () { - var list = []; - this.forEach(function (t) { - list.addRange(t); - }); - return list; -} - -Array.joinAll = function (lists, keySelector, resultSelector) { - keySelector = Q.createSelectorFunction(keySelector); - resultSelector = Q.createSelectorFunction(resultSelector); - - var groupMaps = lists.map(function (list) { - return list.groupByToObject(keySelector); - }); - - var groupMap1 = groupMaps[0]; - - var list = []; - for (var p in groupMap1) { - if (groupMaps.all(p)) - list.push(resultSelector(groupMaps.select(p))); - } - - return list; -} - -Q.isNullOrEmpty = function (stringOrArray) { - return stringOrArray == null || stringOrArray.length == 0; -} -Q.isNotNullOrEmpty = function (stringOrArray) { - return stringOrArray != null && stringOrArray.length > 0; -} - - - -Array.prototype.selectToObject = function (keySelector, valueSelector) { - var obj = {}; - if (valueSelector == null) { - var list = this.select(keySelector); - for (var i = 0; i < list.length; i++) { - var obj2 = this[i]; - if (obj2 != null) { - if (obj2 instanceof Array) { - for (var i = 0; i < obj2.length; i++) { - obj[obj2[0]] = obj2[1]; - } - } - else { - Q.copy(obj2, obj, { overwrite: true }); - } - } - } - } - else { - for (var i = 0; i < this.length; i++) { - var item = this[i]; - obj[keySelector(item)] = valueSelector(item); - } - } - return obj; -} -Array.prototype.groupByToObject = function (keySelector, itemSelector) { - keySelector = Q.createSelectorFunction(keySelector); - itemSelector = Q.createSelectorFunction(itemSelector); - var obj = {}; - for (var i = 0; i < this.length; i++) { - var item = this[i]; - var key = keySelector(item); - if (obj[key] == null) { - obj[key] = []; - obj[key].key = key; - } - var value = itemSelector(item); - obj[key].push(value); - } - return obj; -} -Array.prototype.groupBy = function (keySelector, itemSelector) { - var groupsMap = this.groupByToObject(keySelector, itemSelector); - return Object.values(groupsMap); -} - -Array.prototype.splitIntoChunksOf = function (countInEachChunk) { - var chunks = Math.ceil(this.length / countInEachChunk); - var list = []; - for(var i=0;i"); - var prms; - var body; - if (arrow > 0) { - var tPrms = exp.substring(0, arrow).replace("(", "").replace(")", ""); - prms = tPrms.split(",").map(function (t) { return t.trim(); }); - body = exp.substring(arrow + 2); - } - else { - prms = []; - body = exp; - } - if (!body.contains("return")) - body = "return " + body+";"; - prms.push(body); - return Function.applyNew(prms); -} -String.prototype.toLambda = function () { - return Function.lambda(this); -} -Array.generateNumbers = function (from, until) { - if (arguments.length == 1) { - until = from; - from = 0; - } - var length = until - from; - var list = new Array(length); - for (var i = 0; i < length; i++) { - list[i] = i + from; - } - return list; -} - -Array.prototype.removeNulls = function () { - return this.removeAll(function (t) { return t != null; }); -} - -Array.prototype.exceptNulls = function () { - return this.where(function (t) { return t != null; }); -} - -Number.prototype.inRangeInclusive = function (min, max) { - return this >= min && this <= max; -} -Array.generate = function (length, generator) { - var list = new Array(length); - for (var i = 0; i < length; i++) { - list[i] = generator(i); - } - return list; -} -Math.randomInt = function(min, max){ - return Math.floor(Math.random() * (max - min + 1)) + min; -} -Array.prototype.random = function(){ - return this[Math.randomInt(0, this.length-1)]; -} - -String.prototype.substringBetween = function(start, end){ - var s = this; - var i1 = s.indexOf(start); - if(i1<0) - return null; - var i2 = s.indexOf(end, i1+1); - if(i2<0) - return null; - return s.substring(i1+start.length, i2); -} - diff --git a/htdocs/js/samples/zoom2.js b/htdocs/js/samples/zoom_reduction.js similarity index 51% rename from htdocs/js/samples/zoom2.js rename to htdocs/js/samples/zoom_reduction.js index aa64fec..0c12921 100644 --- a/htdocs/js/samples/zoom2.js +++ b/htdocs/js/samples/zoom_reduction.js @@ -30,8 +30,8 @@ function main() { type: "line", x: "x" }, - zoom2: { - enabled: true, + zoom2: { + enabled: true, } }; chart = c3ext.generate(options); @@ -41,9 +41,9 @@ function main() { function refreshStatus() { var zoomInfo = chart.zoom2.getZoom(); var info = { - reduced:chart.zoom2.maxItems(), - actual:(zoomInfo.currentZoom[1]-zoomInfo.currentZoom[0]), - range:zoomInfo.currentZoom[0] + "-" + zoomInfo.currentZoom[1], + reduced: chart.zoom2.maxItems(), + actual: (zoomInfo.currentZoom[1] - zoomInfo.currentZoom[0]), + range: zoomInfo.currentZoom[0] + "-" + zoomInfo.currentZoom[1], total: zoomInfo.totalItems }; $("#status").text(JSON.stringify(info, null, " ")); @@ -51,4 +51,31 @@ function main() { }; - +if (typeof (Array.generate) == "undefined") { + Array.generate = function (length, generator) { + var list = new Array(length); + for (var i = 0; i < length; i++) { + list[i] = generator(i); + } + return list; + } +} +if (typeof (Math.randomInt) == "undefined") { + Math.randomInt = function (min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } +} +if (typeof (Array.generateNumbers) == "undefined") { + Array.generateNumbers = function (from, until) { + if (arguments.length == 1) { + until = from; + from = 0; + } + var length = until - from; + var list = new Array(length); + for (var i = 0; i < length; i++) { + list[i] = i + from; + } + return list; + } +} \ No newline at end of file diff --git a/htdocs/samples/zoom_reduction.html b/htdocs/samples/zoom_reduction.html index dc9b0bb..a3d47f4 100644 --- a/htdocs/samples/zoom_reduction.html +++ b/htdocs/samples/zoom_reduction.html @@ -11,7 +11,7 @@ - +