diff --git a/bower.json b/bower.json index b92fc01..d798b72 100644 --- a/bower.json +++ b/bower.json @@ -4,7 +4,7 @@ "name": "Xavier Badosa", "url": "http://xavierbadosa.com" }, - "version": "0.8.2", + "version": "0.8.3", "main": "json-stat.js", "ignore": [ "**/.*" diff --git a/json-stat.js b/json-stat.js index d625153..225112a 100644 --- a/json-stat.js +++ b/json-stat.js @@ -1,6 +1,6 @@ /* -JSON-stat Javascript Toolkit v. 0.8.2 +JSON-stat Javascript Toolkit v. 0.8.3 http://json-stat.org https://github.com/badosa/JSON-stat @@ -10,7 +10,7 @@ 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 + 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, @@ -19,4 +19,127 @@ or implied. See the License for the specific language governing permissions and limitations under the License. */ -function JSONstat(t,e){return window===this?new JSONstat.jsonstat(t,e):void 0}var JSONstat=JSONstat||{};JSONstat.version="0.8.2",function(){"use strict";function t(t){return"[object Array]"===Object.prototype.toString.call(t)}function e(e,n){var i,s,r,l,u=function(t,e){var n,i,s=e!==!1;if(window.XDomainRequest&&/^(http(s)?:)?\/\//.test(t)){if(!s)return;i=new XDomainRequest,i.onload=function(){n=JSON.parse(i.responseText),e.call(JSONstat(n))},i.open("GET",t),i.send()}else if(i=new XMLHttpRequest,i.onreadystatechange=function(){if(4===i.readyState){var t=i.status;n=t&&i.responseText&&(t>=200&&300>t||304===t)?JSON.parse(i.responseText):null,s&&e.call(JSONstat(n))}},i.open("GET",t,s),i.send(null),!s)return n},a=function(e,n){var i,s=[];if("string"==typeof e&&(e=[e]),t(e)){if(e.length===n)return e;if(1===e.length){for(i=0;n>i;i++)s.push(e[0]);return s}}for(i=0;n>i;i++){var r="undefined"==typeof e[i]?null:e[i];s.push(r)}return s};if(this.length=0,this.id=[],null!==e&&"undefined"!=typeof e)switch(this.class=e.class||"bundle",this.class){case"bundle":var o=[],h=0;if(this.error=null,this.length=0,"string"==typeof e&&e.length>0&&(e=u(e,"function"==typeof n?n:!1)),null===e||"object"!=typeof e)return;if(e.hasOwnProperty("error"))return void(this.error=e.error);if("dataset"===e.class||"collection"===e.class)return JSONstat(e);for(s in e)h++,o.push(s);this.__tree__=e,this.length=h,this.id=o;break;case"dataset":e.hasOwnProperty("__tree__")||(delete e.class,e={__tree__:e}),this.__tree__=i=e.__tree__,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.updated=i.updated||null,this.source=i.source||null,this.extension=i.extension||null;var f,d=0;if(i.hasOwnProperty("value")&&t(i.value))d=i.value.length;else if(i.hasOwnProperty("status")&&t(i.status))d=i.status.length;else if(i.hasOwnProperty("dimension")){var c=i.dimension.size,p=1;for(f=c.length;f--;)p*=c[f];d=p}if(this.value=a(i.value,d),this.status=i.hasOwnProperty("status")?a(i.status,d):null,i.hasOwnProperty("dimension")){if(!t(i.dimension.id)||!t(i.dimension.size)||i.dimension.id.length!=i.dimension.size.length)return;var y=i.dimension,v=y.role||null,g=y.id,_=y.size.length,b=function(t){v.hasOwnProperty(t)||(v[t]=null)};if(this.length=_,this.id=g,v&&(b("time"),b("geo"),b("metric"),b("classification")),v&&null===v.classification){var m=[],w=["time","geo","metric"],O=function(t,e){for(var n=e.length;n--;)if(t===e[n])return!0;return!1};for(f=0;3>f;f++){var x=v[w[f]];null!==x&&(m=m.concat(x))}for(v.classification=[],f=0;_>f;f++)O(g[f],m)||v.classification.push(g[f]);0===v.classification.length&&(v.classification=null)}this.role=v,this.n=d;for(var S=0,k=this.length;k>S;S++)if(y[y.id[S]].category.hasOwnProperty("index")){if(t(y[y.id[S]].category.index)){var P={},D=y[y.id[S]].category.index;for(r=D.length,l=0;r>l;l++)P[D[l]]=l;y[y.id[S]].category.index=P}}else{var j=0;y[y.id[S]].category.index={};for(s in y[y.id[S]].category.label)y[y.id[S]].category.index[s]=j++}}else this.length=0;break;case"dimension":i=e.__tree__;var J=[],N=i.category;if(!e.hasOwnProperty("__tree__")||!i.hasOwnProperty("category"))return;if(!N.hasOwnProperty("label")){N.label={};for(s in N.index)N.label[s]=s}for(s in N.index)J[N.index[s]]=s;this.__tree__=i,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.id=J,this.length=J.length,this.role=e.role,this.hierarchy=N.hasOwnProperty("child"),this.extension=i.extension||null;break;case"category":var T=e.child;this.id=T,this.length=null===T?0:T.length,this.index=e.index,this.label=e.label,this.note=e.note||null,this.unit=e.unit,this.coordinates=e.coord;break;case"collection":if(this.length=0,this.label=e.label||null,this.note=e.note||null,this.link=e.link||null,this.href=e.href||null,this.updated=e.updated||null,this.source=e.source||null,this.extension=e.extension||null,null!==this.link&&e.link.item){var z=e.link.item;if(this.length=t(z)?z.length:0,this.length)for(l=0;lthis.length||0>t?null:this.link.item[t];var e,n=[];"object"==typeof t?t.class?e=function(t,e,i){i.class===t.link.item[e].class&&n.push(t.link.item[e])}:t.follow&&(e=function(t,e){n.push(JSONstat(t.id[e]))}):e=function(t,e){n.push(t.link.item[e])};for(var i=0;ii;i++)n.push(this.Dataset(this.id[i]));return n}if("number"==typeof t){var r=this.id[t];return"undefined"!=typeof r?this.Dataset(r):null}var l=this.__tree__[t];return"undefined"==typeof l?null:new e({"class":"dataset",__tree__:l})},e.prototype.Dimension=function(t){var n,i=[],s=this.id.length,r=function(t,e){var n=t.role;if(null!==n)for(var i in n)for(var s=null!==n[i]?n[i].length:0;s--;)if(n[i][s]===e)return i;return null};if(null===this||"dataset"!==this.class)return null;if("undefined"==typeof t){for(n=0;s>n;n++)i.push(this.Dimension(this.id[n]));return i}if("number"==typeof t){var l=this.id[t];return"undefined"!=typeof l?this.Dimension(l):null}var u=this.__tree__.dimension;if("undefined"==typeof u)return null;if("object"==typeof t){if(t.hasOwnProperty("role")){for(n=0;s>n;n++){var a=this.id[n];r(u,a)===t.role&&i.push(this.Dimension(a))}return"undefined"==typeof i[0]?null:i}return null}var o=u[t];return"undefined"==typeof o?null:new e({"class":"dimension",__tree__:o,role:r(u,t)})},e.prototype.Category=function(t){if(null===this||"dimension"!==this.class)return null;if("undefined"==typeof t){for(var n=[],i=0,s=this.id.length;s>i;i++)n.push(this.Category(this.id[i]));return n}if("number"==typeof t){var r=this.id[t];return"undefined"!=typeof r?this.Category(r):null}var l=this.__tree__.category;if("undefined"==typeof l)return null;var u=l.index[t];if("undefined"==typeof u)return null;var a=l.unit&&l.unit[t]||null,o=l.coordinates&&l.coordinates[t]||null,h=l.child&&l.child[t]||null,f=l.note&&l.note[t]||null;return new e({"class":"category",index:u,label:l.label[t],note:f,child:h,unit:a,coord:o})},e.prototype.Data=function(e){var n,i,s=[],r=function(t){for(var e in t)if(t.hasOwnProperty(e))return e},l=function(t,e){for(var n=[],i=t.dimension,s=i.id,l=0,u=s.length;u>l;l++){var a=s[l],o=e[a];n.push("string"==typeof o?o:1===i.size[l]?r(i[a].category.index):null)}return n};if(null===this||"dataset"!==this.class)return null;if("undefined"==typeof e){for(i=this.value.length,n=0;i>n;n++)s.push(this.Data(n));return s}if("number"==typeof e){var u=this.value[e];return"undefined"!=typeof u?{value:u,status:this.status?this.status[e]:null}:null}var a=this.__tree__,o=a.dimension.size,h=o.length;if(t(e)){if(this.length!==e.length)return null;var f=1,d=0,c=[],p=[];for(n=0;h>n;n++)if("undefined"!=typeof e[n]){if("number"!=typeof e[n]||e[n]>=o[n])return null;f*=n>0?o[h-n]:1,d+=f*e[h-n-1]}else c.push(n),p.push(o[n]);if(c.length>1)return null;if(1===c.length){for(var y=0,v=p[0];v>y;y++){var g=[];for(n=0;h>n;n++)g.push(n!==c[0]?e[n]:y);s.push(this.Data(g))}return s}return{value:this.value[d],status:this.status?this.status[d]:null}}var _=l(a,e),b=[],m=a.dimension;for(i=_.length,n=0;i>n;n++)b.push(m[m.id[n]].category.index[_[n]]);return this.Data(b)},e.prototype.toTable=function(t,e){if(null===this||"dataset"!==this.class)return null;1==arguments.length&&"function"==typeof t&&(e=t,t=null);var n,i,s,r,l,u=this.__tree__;if(t=t||{field:"label",content:"label",vlabel:"Value",slabel:"Status",type:"array",status:!1},"function"==typeof e){n=this.toTable(t);var a=[],o="array"!==t.type?0:1,h="object"!==t.type?n.slice(o):n.rows.slice(0);for(l=h.length,i=0;l>i;i++){var f=e.call(this,h[i],i);"undefined"!=typeof f&&a.push(f)}return"object"===t.type?{cols:n.cols,rows:a}:("array"===t.type&&a.unshift(n[0]),a)}if("arrobj"===t.type){n=this.toTable({field:"id",content:t.content,status:t.status});var d=[],c=n.shift();for(l=n.length,i=0;l>i;i++){var p={};for(s=n[i].length;s--;)p[c[s]]=n[i][s];d.push(p)}return d}var y,v,g,_,b="id"===t.field;if("object"===t.type){var m="number"==typeof this.value[0]||null===this.value[0]?"number":"string";y=function(t,e){var n=b&&t||e||t;z.push({id:t,label:n,type:"string"})},v=function(t,e,n){var i=b&&"value"||t||"Value",s=b&&"status"||e||"Status";n&&z.push({id:"status",label:s,type:"string"}),z.push({id:"value",label:i,type:m})},g=function(t){B.push({v:t})},_=function(t){B.push({v:t}),V.push({c:B})}}else y=function(t,e){var n=b&&t||e||t;z.push(n)},v=function(t,e,n){var i=b&&"value"||t||"Value",s=b&&"status"||e||"Status";n&&z.push(s),z.push(i),T.push(z)},g=function(t){B.push(t)},_=function(t){B.push(t),T.push(B)};var w=u.dimension,O=w.id,x=O.length,S=w.size;if(x!=S.length)return!1;var k=[],P=1,D=1,j=[],J=[],N=[],T=[],z=[],V=[];for(i=0;x>i;i++){var q=O[i],C=w[q].label;y(q,C),P*=S[i],D*=S[i];var R=[];for(s=0;si;i++){for(var G=[],A=0,H=k[i].length;H>A;A++)for(var I=0;I

i;i++){var L=[],M=0;for(r=0;P>r;r++)L.push(J[i][M]),M++,M===J[i].length&&(M=0);N.push(L)}for(r=0;P>r;r++){var B=[];l=J.length;for(var F=0;l>F;F++)g(N[F][r]);t.status&&g(this.status?this.status[r]:null),_(this.value[r])}return"object"===t.type?{cols:z,rows:V}:T},e.prototype.node=function(){return this.__tree__},e.prototype.toString=function(){return this.class},e.prototype.toValue=function(){return this.length},JSONstat.jsonstat=e}(); \ No newline at end of file + +function JSONstat(t,e){return window===this?new JSONstat.jsonstat(t,e):void 0}var JSONstat=JSONstat||{} +JSONstat.version="0.8.3",function(){"use strict" +function t(t){return"[object Array]"===Object.prototype.toString.call(t)}function e(e,n){var i,s,r,l,a=function(t,e){var n,i,s=e!==!1 +if(window.XDomainRequest&&/^(http(s)?:)?\/\//.test(t)){if(!s)return +i=new XDomainRequest,i.onload=function(){n=JSON.parse(i.responseText),e.call(JSONstat(n))},i.open("GET",t),i.send()}else if(i=new XMLHttpRequest,i.onreadystatechange=function(){if(4===i.readyState){var t=i.status +n=t&&i.responseText&&(t>=200&&300>t||304===t)?JSON.parse(i.responseText):null,s&&e.call(JSONstat(n))}},i.open("GET",t,s),i.send(null),!s)return n},o=function(e,n){var i,s=[] +if("string"==typeof e&&(e=[e]),t(e)){if(e.length===n)return e +if(1===e.length){for(i=0;n>i;i++)s.push(e[0]) +return s}}for(i=0;n>i;i++){var r=void 0===e[i]?null:e[i] +s.push(r)}return s} +if(this.length=0,this.id=[],null!==e&&void 0!==e)switch(this["class"]=e["class"]||"bundle",this["class"]){case"bundle":var u=[],h=0 +if(this.error=null,this.length=0,"string"==typeof e&&e.length>0&&(e=a(e,"function"==typeof n?n:!1)),null===e||"object"!=typeof e)return this["class"]=null,void(void 0===e&&(delete this.id,delete this["class"],delete this.error,delete this.length)) +if(e.hasOwnProperty("error"))return void(this.error=e.error) +if("dataset"===e["class"]||"collection"===e["class"])return JSONstat(e) +for(s in e)h++,u.push(s) +this.__tree__=e,this.length=h,this.id=u +break +case"dataset":e.hasOwnProperty("__tree__")||(delete e["class"],e={__tree__:e}),this.__tree__=i=e.__tree__,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.updated=i.updated||null,this.source=i.source||null,this.extension=i.extension||null +var f,c=0 +if(i.hasOwnProperty("value")&&t(i.value))c=i.value.length +else if(i.hasOwnProperty("status")&&t(i.status))c=i.status.length +else if(i.hasOwnProperty("dimension")){var d=i.dimension.size,p=1 +for(f=d.length;f--;)p*=d[f] +c=p}if(this.value=o(i.value,c),this.status=i.hasOwnProperty("status")?o(i.status,c):null,i.hasOwnProperty("dimension")){if(!t(i.dimension.id)||!t(i.dimension.size)||i.dimension.id.length!=i.dimension.size.length)return +var v=i.dimension,g=v.role||null,y=v.id,_=v.size.length,b=function(t){g.hasOwnProperty(t)||(g[t]=null)} +if(this.length=_,this.id=y,g&&(b("time"),b("geo"),b("metric"),b("classification")),g&&null===g.classification){var m=[],w=["time","geo","metric"],O=function(t,e){for(var n=e.length;n--;)if(t===e[n])return!0 +return!1} +for(f=0;3>f;f++){var x=g[w[f]] +null!==x&&(m=m.concat(x))}for(g.classification=[],f=0;_>f;f++)O(y[f],m)||g.classification.push(y[f]) +0===g.classification.length&&(g.classification=null)}this.role=g,this.n=c +for(var S=0,k=this.length;k>S;S++)if(v[v.id[S]].category.hasOwnProperty("index")){if(t(v[v.id[S]].category.index)){var P={},D=v[v.id[S]].category.index +for(r=D.length,l=0;r>l;l++)P[D[l]]=l +v[v.id[S]].category.index=P}}else{var j=0 +v[v.id[S]].category.index={} +for(s in v[v.id[S]].category.label)v[v.id[S]].category.index[s]=j++}}else this.length=0 +break +case"dimension":i=e.__tree__ +var J=[],N=i.category +if(!e.hasOwnProperty("__tree__")||!i.hasOwnProperty("category"))return +if(!N.hasOwnProperty("label")){N.label={} +for(s in N.index)N.label[s]=s}for(s in N.index)J[N.index[s]]=s +this.__tree__=i,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.id=J,this.length=J.length,this.role=e.role,this.hierarchy=N.hasOwnProperty("child"),this.extension=i.extension||null +break +case"category":var T=e.child +this.id=T,this.length=null===T?0:T.length,this.index=e.index,this.label=e.label,this.note=e.note||null,this.unit=e.unit,this.coordinates=e.coord +break +case"collection":if(this.length=0,this.label=e.label||null,this.note=e.note||null,this.link=e.link||null,this.href=e.href||null,this.updated=e.updated||null,this.source=e.source||null,this.extension=e.extension||null,null!==this.link&&e.link.item){var z=e.link.item +if(this.length=t(z)?z.length:0,this.length)for(l=0;lthis.length||0>t?null:this.link.item[t] +var e,n=[] +if("object"==typeof t){if(!t["class"]&&!t.follow)return null +t["class"]?e=function(t,e,i){i["class"]===t.link.item[e]["class"]&&n.push(t.link.item[e])}:t.follow&&(e=function(t,e){n.push(JSONstat(t.id[e]))})}else e=function(t,e){n.push(t.link.item[e])} +for(var i=0;ii;i++)n.push(this.Dataset(this.id[i])) +return n}if("number"==typeof t){var r=this.id[t] +return void 0!==r?this.Dataset(r):null}var l=this.__tree__[t] +return void 0===l?null:new e({"class":"dataset",__tree__:l})},e.prototype.Dimension=function(t){var n,i=[],s=this.id.length,r=function(t,e){var n=t.role +if(null!==n)for(var i in n)for(var s=null!==n[i]?n[i].length:0;s--;)if(n[i][s]===e)return i +return null} +if(null===this||"dataset"!==this["class"])return null +if(void 0===t){for(n=0;s>n;n++)i.push(this.Dimension(this.id[n])) +return i}if("number"==typeof t){var l=this.id[t] +return void 0!==l?this.Dimension(l):null}var a=this.__tree__.dimension +if(void 0===a)return null +if("object"==typeof t){if(t.hasOwnProperty("role")){for(n=0;s>n;n++){var o=this.id[n] +r(a,o)===t.role&&i.push(this.Dimension(o))}return void 0===i[0]?null:i}return null}var u=a[t] +return void 0===u?null:new e({"class":"dimension",__tree__:u,role:r(a,t)})},e.prototype.Category=function(t){if(null===this||"dimension"!==this["class"])return null +if(void 0===t){for(var n=[],i=0,s=this.id.length;s>i;i++)n.push(this.Category(this.id[i])) +return n}if("number"==typeof t){var r=this.id[t] +return void 0!==r?this.Category(r):null}var l=this.__tree__.category +if(void 0===l)return null +var a=l.index[t] +if(void 0===a)return null +var o=l.unit&&l.unit[t]||null,u=l.coordinates&&l.coordinates[t]||null,h=l.child&&l.child[t]||null,f=l.note&&l.note[t]||null +return new e({"class":"category",index:a,label:l.label[t],note:f,child:h,unit:o,coord:u})},e.prototype.Data=function(e){var n,i,s=[],r=function(t){for(var e in t)if(t.hasOwnProperty(e))return e},l=function(t,e){for(var n=[],i=t.dimension,s=i.id,l=0,a=s.length;a>l;l++){var o=s[l],u=e[o] +n.push("string"==typeof u?u:1===i.size[l]?r(i[o].category.index):null)}return n} +if(null===this||"dataset"!==this["class"])return null +if(void 0===e){for(i=this.value.length,n=0;i>n;n++)s.push(this.Data(n)) +return s}if("number"==typeof e){var a=this.value[e] +return void 0!==a?{value:a,status:this.status?this.status[e]:null}:null}var o=this.__tree__,u=o.dimension.size,h=u.length +if(t(e)){if(this.length!==e.length)return null +var f=1,c=0,d=[],p=[] +for(n=0;h>n;n++)if(void 0!==e[n]){if("number"!=typeof e[n]||e[n]>=u[n])return null +f*=n>0?u[h-n]:1,c+=f*e[h-n-1]}else d.push(n),p.push(u[n]) +if(d.length>1)return null +if(1===d.length){for(var v=0,g=p[0];g>v;v++){var y=[] +for(n=0;h>n;n++)y.push(n!==d[0]?e[n]:v) +s.push(this.Data(y))}return s}return{value:this.value[c],status:this.status?this.status[c]:null}}var _=l(o,e),b=[],m=o.dimension +for(i=_.length,n=0;i>n;n++)b.push(m[m.id[n]].category.index[_[n]]) +return this.Data(b)},e.prototype.toTable=function(t,e){if(null===this||"dataset"!==this["class"])return null +1==arguments.length&&"function"==typeof t&&(e=t,t=null) +var n,i,s,r,l,a=this.__tree__ +if(t=t||{field:"label",content:"label",vlabel:"Value",slabel:"Status",type:"array",status:!1},"function"==typeof e){n=this.toTable(t) +var o=[],u="array"!==t.type?0:1,h="object"!==t.type?n.slice(u):n.rows.slice(0) +for(l=h.length,i=0;l>i;i++){var f=e.call(this,h[i],i) +void 0!==f&&o.push(f)}return"object"===t.type?{cols:n.cols,rows:o}:("array"===t.type&&o.unshift(n[0]),o)}if("arrobj"===t.type){n=this.toTable({field:"id",content:t.content,status:t.status}) +var c=[],d=n.shift() +for(l=n.length,i=0;l>i;i++){var p={} +for(s=n[i].length;s--;)p[d[s]]=n[i][s] +c.push(p)}return c}var v,g,y,_,b="id"===t.field +if("object"===t.type){var m="number"==typeof this.value[0]||null===this.value[0]?"number":"string" +v=function(t,e){var n=b&&t||e||t +z.push({id:t,label:n,type:"string"})},g=function(t,e,n){var i=b&&"value"||t||"Value",s=b&&"status"||e||"Status" +n&&z.push({id:"status",label:s,type:"string"}),z.push({id:"value",label:i,type:m})},y=function(t){B.push({v:t})},_=function(t){B.push({v:t}),V.push({c:B})}}else v=function(t,e){var n=b&&t||e||t +z.push(n)},g=function(t,e,n){var i=b&&"value"||t||"Value",s=b&&"status"||e||"Status" +n&&z.push(s),z.push(i),T.push(z)},y=function(t){B.push(t)},_=function(t){B.push(t),T.push(B)} +var w=a.dimension,O=w.id,x=O.length,S=w.size +if(x!=S.length)return!1 +var k=[],P=1,D=1,j=[],J=[],N=[],T=[],z=[],V=[] +for(i=0;x>i;i++){var q=O[i],C=w[q].label +v(q,C),P*=S[i],D*=S[i] +var R=[] +for(s=0;si;i++){for(var G=[],A=0,H=k[i].length;H>A;A++)for(var I=0;I

i;i++){var L=[],M=0 +for(r=0;P>r;r++)L.push(J[i][M]),M++,M===J[i].length&&(M=0) +N.push(L)}for(r=0;P>r;r++){var B=[] +l=J.length +for(var F=0;l>F;F++)y(N[F][r]) +t.status&&y(this.status?this.status[r]:null),_(this.value[r])}return"object"===t.type?{cols:z,rows:V}:T},e.prototype.node=function(){return this.__tree__},e.prototype.toString=function(){return this["class"]},e.prototype.toValue=function(){return this.length},JSONstat.jsonstat=e}() diff --git a/json-stat.max.js b/json-stat.max.js index 786f19e..8e127e9 100644 --- a/json-stat.max.js +++ b/json-stat.max.js @@ -1,6 +1,6 @@ /* -JSON-stat Javascript Toolkit v. 0.8.2 +JSON-stat Javascript Toolkit v. 0.8.3 http://json-stat.org https://github.com/badosa/JSON-stat @@ -10,7 +10,7 @@ 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 + 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, @@ -22,875 +22,888 @@ permissions and limitations under the License. var JSONstat = JSONstat || {}; -JSONstat.version="0.8.2"; +JSONstat.version="0.8.3"; /* jshint newcap:false */ function JSONstat(resp,f){ - if(window===this){ - return new JSONstat.jsonstat(resp,f); - } + if(window===this){ + return new JSONstat.jsonstat(resp,f); + } } (function(){ - "use strict"; - - function isArray(o) { - return Object.prototype.toString.call(o) === "[object Array]"; - } - function Jsonstat(o,f){ - var - xhr=function(uri, func){ - var json, async=(func!==false), req; - if(window.XDomainRequest && /^(http(s)?:)?\/\//.test(uri)){ //IE9 cross-domain (assuming access to same domain won't be specified using an absolute address). Not integrated because it will be removed someday... - if(!async){ //JSONstat: IE9 sync cross-domain request? Sorry, not supported (only async if IE9 and cross-domain). - return; - } - req=new XDomainRequest(); - /* - req.onerror=function(){ - return; //JSONstat: Can't access "+uri; - } - */ - req.onload=function(){ - json=JSON.parse(req.responseText); - func.call(JSONstat(json)); - }; - req.open("GET", uri); - req.send(); - }else{ //Standard xhr - req=new XMLHttpRequest(); - req.onreadystatechange=function(){ - if(req.readyState===4){ - var s=req.status; - json=(s && req.responseText && (s>=200 && s<300 || s===304)) ? JSON.parse(req.responseText) : null; - if(async){ - func.call(JSONstat(json)); - } - } - }; - req.open("GET",uri,async); - req.send(null); - if(!async){ - return json; - } - } - }, - //sparse cube (value or status) - //If only one value/status is provided it means same for all (if more than one, then missing values/statuses are nulled). - normalize=function(s,len){ - var ret=[], l; - - if(typeof s==="string"){ - s=[s]; - } - if(isArray(s)){ - if(s.length===len){ //normal case - return s; - } - if(s.length===1){ //all obs same status - for(l=0; l0){ - o=xhr(o, typeof f==="function"? f : false);//If second argument is function then async - } - - // Wrong input object or wrong URI or connection problem - if(o===null || typeof o!=="object"){ - return; - } - - // Explicit error - if(o.hasOwnProperty("error")){ - this.error=o.error; - return; - } - - //When o is a URI, class won't be set before the request - //and it will enter the bundle case: once we have a response - //if class if dataset we redirect to case "dataset". 0.7.5 - if(o.class==="dataset" || o.class==="collection"){ - return JSONstat(o); - } - - for (prop in o){ - ds++; - /* If sparse cube, we can't rely on value to check size - if (isArray(o[prop].value)){ - a++; - } - */ - arr.push(prop); - } - this.__tree__=o; - this.length=ds; - this.id=arr; - break; - - case "dataset" : - //It's a native response of class "dataset" - if (!o.hasOwnProperty("__tree__")){ - delete o.class; //class shouldn't go inside __tree__ - o={ "__tree__": o }; //remove all elements from o (native response "dataset"), put everything inside __tree__ (native response "bundle") - } - - this.__tree__=ot=o.__tree__; - this.label=ot.label || null; - this.note=ot.note || null; //v.0.7.0 - this.link=ot.link || null; //v.0.7.0 - this.href=ot.href || null; //v.0.7.0 - this.updated=ot.updated || null; - this.source=ot.source || null; //v.0.5.0 - this.extension=ot.extension || null; //v.0.7.0 - - //Sparse cube (If toTable() removed, this logic can be moved inside Data() - //which is more efficient when retrieving a single value/status. - var s, dsize=0; //data size - if (ot.hasOwnProperty("value") && isArray(ot.value)){ - dsize=ot.value.length; - }else{ - if (ot.hasOwnProperty("status") && isArray(ot.status)){ - dsize=ot.status.length; - }else{ - if(ot.hasOwnProperty("dimension")) { - var size=ot.dimension.size, length=1; - for(s=size.length; s--;){ - length*=size[s]; - } - dsize=length; - } - } - } - - this.value=normalize(ot.value,dsize); - this.status=(!(ot.hasOwnProperty("status"))) ? null : normalize(ot.status,dsize); - - // if dimensions are defined, id and size arrays are required and must have equal length - if (ot.hasOwnProperty("dimension")){ - if ( - !(isArray(ot.dimension.id)) || - !(isArray(ot.dimension.size)) || - ot.dimension.id.length!=ot.dimension.size.length - ){ - return; - } - var - otd=ot.dimension, - otr=otd.role || null, - otdi=otd.id, - otdl=otd.size.length, - createRole=function(s){ - if(!otr.hasOwnProperty(s)){ - otr[s]=null; - } - } - ; - - this.length=otdl; - this.id=otdi; - - if(otr){ - createRole("time"); - createRole("geo"); - createRole("metric"); - createRole("classification"); - } - - //If role not null, leave it as it is but add a classification role if it's null. Added in 0.7.1 - if (otr && otr.classification===null){ - var - gmt=[], - roles=["time","geo","metric"], - //Replace with polyfill of Array.indefOf at some point? - inArray=function(e, a){ - for(var i=a.length;i--;){ - if(e===a[i]){ - return true; - } - } - return false; - } - ; - - for(s=0; s<3; s++){ - var rr=otr[roles[s]]; - if(rr!==null){ - gmt=gmt.concat(rr); - } - } - - otr.classification=[]; - - //not inverse looping to preserve dim order - for(s=0; sthis.length || o<0){ - return null; - } - return this.link.item[o]; - } - - var ret=[], func; - - if(typeof o==="object"){ - if(o.class){ - func=function(t,i,c){ - if(c.class===t.link.item[i].class){ - ret.push(t.link.item[i]); - } - }; - }else{ - //{follow: true} not documented because sync xhr are deprecated outside of workers. Use only for testing and demoing. That's why it's been defined as incompatible with {class: ...} - if(o.follow){ - func=function(t,i){ - ret.push(JSONstat(t.id[i])); - }; - } - } - }else{ //not object, not number: void or string (ignore) - func=function(t,i){ - ret.push(t.link.item[i]); - }; - } - - for(var i=0; i=n[i]){ - return null; /* removed in 0.5.2.2 {"value" : undefined, "status": undefined, "length" : 0};*/ - } - //Used if normal case (miss.length===0) - mult*=(i>0) ? n[(dims-i)] : 1; - res+=mult*e[dims-i-1]; //simplified in 0.4.3 - }else{ - //Used if missing dimensions miss.length>0 - miss.push(i); //missing dims - nmiss.push(n[i]); //missing dims size - } - } - - //If all dims are specified, go ahead as usual. - //If one non-single dimension is missing create array of results - //If more than one non-single dimension is missing, WARNING - if(miss.length>1){ - return null; /* removed in 0.5.2.2 {"value" : undefined, "status": undefined, "length" : 0};*/ - } - if(miss.length===1){ - for(var c=0, clen=nmiss[0]; c=200 && s<300 || s===304)) ? JSON.parse(req.responseText) : null; + if(async){ + func.call(JSONstat(json)); + } + } + }; + req.open("GET",uri,async); + req.send(null); + if(!async){ + return json; + } + } + }, + //sparse cube (value or status) + //If only one value/status is provided it means same for all (if more than one, then missing values/statuses are nulled). + normalize=function(s,len){ + var ret=[], l; + + if(typeof s==="string"){ + s=[s]; + } + if(isArray(s)){ + if(s.length===len){ //normal case + return s; + } + if(s.length===1){ //all obs same status + for(l=0; l0){ + o=xhr(o, typeof f==="function"? f : false);//If second argument is function then async + } + + // Wrong input object or wrong URI or connection problem + // Or async (o is undefined) + if(o===null || typeof o!=="object"){ + this.class=null; + // Async: remove properties: they are meaningless (0.8.3) + if(typeof o==="undefined"){ + delete(this.id); + delete(this.class); + delete(this.error); + delete(this.length); + } + return; + } + + // Explicit error + if(o.hasOwnProperty("error")){ + this.error=o.error; + return; + } + + //When o is a URI, class won't be set before the request + //and it will enter the bundle case: once we have a response + //if class if dataset we redirect to case "dataset". 0.7.5 + if(o.class==="dataset" || o.class==="collection"){ + return JSONstat(o); + } + + for (prop in o){ + ds++; + /* If sparse cube, we can't rely on value to check size + if (isArray(o[prop].value)){ + a++; + } + */ + arr.push(prop); + } + this.__tree__=o; + this.length=ds; + this.id=arr; + break; + + case "dataset" : + //It's a native response of class "dataset" + if (!o.hasOwnProperty("__tree__")){ + delete o.class; //class shouldn't go inside __tree__ + o={ "__tree__": o }; //remove all elements from o (native response "dataset"), put everything inside __tree__ (native response "bundle") + } + + this.__tree__=ot=o.__tree__; + this.label=ot.label || null; + this.note=ot.note || null; //v.0.7.0 + this.link=ot.link || null; //v.0.7.0 + this.href=ot.href || null; //v.0.7.0 + this.updated=ot.updated || null; + this.source=ot.source || null; //v.0.5.0 + this.extension=ot.extension || null; //v.0.7.0 + + //Sparse cube (If toTable() removed, this logic can be moved inside Data() + //which is more efficient when retrieving a single value/status. + var s, dsize=0; //data size + if (ot.hasOwnProperty("value") && isArray(ot.value)){ + dsize=ot.value.length; + }else{ + if (ot.hasOwnProperty("status") && isArray(ot.status)){ + dsize=ot.status.length; + }else{ + if(ot.hasOwnProperty("dimension")) { + var size=ot.dimension.size, length=1; + for(s=size.length; s--;){ + length*=size[s]; + } + dsize=length; + } + } + } + + this.value=normalize(ot.value,dsize); + this.status=(!(ot.hasOwnProperty("status"))) ? null : normalize(ot.status,dsize); + + // if dimensions are defined, id and size arrays are required and must have equal length + if (ot.hasOwnProperty("dimension")){ + if ( + !(isArray(ot.dimension.id)) || + !(isArray(ot.dimension.size)) || + ot.dimension.id.length!=ot.dimension.size.length + ){ + return; + } + var + otd=ot.dimension, + otr=otd.role || null, + otdi=otd.id, + otdl=otd.size.length, + createRole=function(s){ + if(!otr.hasOwnProperty(s)){ + otr[s]=null; + } + } + ; + + this.length=otdl; + this.id=otdi; + + if(otr){ + createRole("time"); + createRole("geo"); + createRole("metric"); + createRole("classification"); + } + + //If role not null, leave it as it is but add a classification role if it's null. Added in 0.7.1 + if (otr && otr.classification===null){ + var + gmt=[], + roles=["time","geo","metric"], + //Replace with polyfill of Array.indefOf at some point? + inArray=function(e, a){ + for(var i=a.length;i--;){ + if(e===a[i]){ + return true; + } + } + return false; + } + ; + + for(s=0; s<3; s++){ + var rr=otr[roles[s]]; + if(rr!==null){ + gmt=gmt.concat(rr); + } + } + + otr.classification=[]; + + //not inverse looping to preserve dim order + for(s=0; sthis.length || o<0){ + return null; + } + return this.link.item[o]; + } + + var ret=[], func; + + if(typeof o==="object"){ + //Do not accept invalid objects (0.8.3) + if(!o.class && !o.follow){ + return null; + } + if(o.class){ + func=function(t,i,c){ + if(c.class===t.link.item[i].class){ + ret.push(t.link.item[i]); + } + }; + }else{ + //{follow: true} not documented because sync xhr are deprecated outside of workers. Use only for testing and demoing. That's why it's been defined as incompatible with {class: ...} + if(o.follow){ + func=function(t,i){ + ret.push(JSONstat(t.id[i])); + }; + } + } + }else{ //not object, not number: void or string (ignore) + func=function(t,i){ + ret.push(t.link.item[i]); + }; + } + + for(var i=0; i=n[i]){ + return null; /* removed in 0.5.2.2 {"value" : undefined, "status": undefined, "length" : 0};*/ + } + //Used if normal case (miss.length===0) + mult*=(i>0) ? n[(dims-i)] : 1; + res+=mult*e[dims-i-1]; //simplified in 0.4.3 + }else{ + //Used if missing dimensions miss.length>0 + miss.push(i); //missing dims + nmiss.push(n[i]); //missing dims size + } + } + + //If all dims are specified, go ahead as usual. + //If one non-single dimension is missing create array of results + //If more than one non-single dimension is missing, WARNING + if(miss.length>1){ + return null; /* removed in 0.5.2.2 {"value" : undefined, "status": undefined, "length" : 0};*/ + } + if(miss.length===1){ + for(var c=0, clen=nmiss[0]; c