Author: Xavier Badosa / Archived under Tools
The JSON-stat format stores multidimensional data (a cube) as a unidimensional array using the row-major order method. This sample code illustrates how you can get the value of a particular cube cell (see the getValue() function). For this, it’s necessary to translate multidimensional indices (categories) into a unidimensional one (value).
This code has been written with clarity in mind, not efficiency.
See examples based on this code: Children Aged 0-4 in 1900’s Norway, Children Aged 0-4 in Norway, US Unemployment Rate.
Example 1: Unemployment rate in the US in 2010 according to the sample OECD dataset (oecd.json).
Result: 9.627692959
<script> var query={ "concept" : "UNR", "area" : "US", "year" : "2010" }; </script> <script src="http://json-stat.org/samples/oecd.json?callback=main"></script>
Example 2: Value in cell with dimension A=“1”, dimension B=“2” and dimension C=“4” in the sample “order” dataset (order.json).
Result: "A1B2C4"
<script> var query={ "A" : "1", //1..3 "B" : "2", //1..2 "C" : "4" //1..4 }; </script> <script src="http://json-stat.org/samples/order.json?callback=main"></script>
Example 3: 0-4 years old population in 1900 according to Statistics Norway 65195 dataset.
Result: 286900
<script> var query={ "Alder": "F00-04", "Kjonn": "0", "Tid": "1900", "ContentsCode": "Personer" }; </script> <script src="http://data.ssb.no/api/v0/dataset/65195.json?callback=main"></script>
This program returns some data value by categories’ IDs (expressed as an assoc array: query) from a JSON-stat object (obj).
function main( obj ){ //Validate jsonstat var jsonstat=JSONstat( obj ); if( !jsonstat ){ return; } //Parse: Get value from jsonstat and query var value=getValue( jsonstat , query ); //Write: Display query and result show( query , value ); }
getValue() converts a dimension/category assoc array into a data value in three steps.
Input example: {"concept":"UNR","area":"US","year":"2010"}
Output example: 9.627692959
function getValue( jsonstat , query ){ //1. {"concept":"UNR","area":"US","year":"2010"} ==> [0, 33, 7] var indices=getDimIndices( jsonstat , query ); //2. [0, 33, 7] ==> 403 var index=getValueIndex( jsonstat , indices ); //3. 403 ==> 9.627692959 return jsonstat.value[index]; }
getDimIndices() converts a dimension/category assoc array into an array of dimensions’ indices.
Input example: {"concept":"UNR","area":"US","year":"2010"}
Output example: [0, 33, 7]
function getDimIndices( jsonstat , query ){ var dim=jsonstat.dimension, ids=jsonstat.id || dim.id ; //JSON-stat 2.0-ready for( var arr=[], i=0, len=ids.length; i<len ; i++ ){ arr[i]=getDimIndex( dim , ids[i] , query[ids[i]] ); } return arr; }
getValueIndex() converts an array of dimensions’ indices into a numeric value index.
Input example: [0, 33, 7]
Output example: 403
function getValueIndex( jsonstat , indices ){ var size=jsonstat.size || jsonstat.dimension.size; //JSON-stat 2.0-ready for( var i=0, ndims=size.length, num=0, mult=1; i<ndims; i++ ){ mult*=( i<0 ) ? size[ndims-i] : 1; num+=mult*indices[ndims-i-1]; } return num; }
getDimIndex() converts a dimension ID string and a category ID string into the numeric index of that category in that dimension.
Input example: "area"
, "US"
Output example: 33
function getDimIndex( dim , name , value ){ //In single category dimensions, "index" is optional if( !dim[name].category.index ){ return 0; } var ndx=dim[name].category.index; //"index" can be an object or an array if( Object.prototype.toString.call(ndx) !== "[object Array]" ){ //Object return ndx[value]; }else{ //Array return ndx.indexOf( value ); //Polyfill required in old browsers } }
JSONstat() validates object is JSON-stat. If bundle response, first dataset is retrieved.
function JSONstat( jsonstat ){ if( !jsonstat ){ window.alert( "Error: no response could be retrieved." ); return NULL; } //If no "class", "bundle" response: //use the first dataset available //(assuming single dataset bundle response) //[Of course, it’d be better to add an argument //to the function to pass a dataset ID if //bundle responses must be properly supported.] if( !jsonstat.class ){ jsonstat=jsonstat[Object.keys( jsonstat )[0]]; //Polyfill required in old browsers }else{ //Verify it's a "dataset" response if( jsonstat.class!=="dataset" ){ window.alert( "Error: response was not a JSON-stat bundle or dataset response." ); return NULL; } } //Program requires "value" and "dimension" properties if( !jsonstat.value || !jsonstat.dimension ){ window.alert( "Error: response is not valid JSON-stat or does not contain required information." ); return NULL; } return jsonstat; }
show() displays the query and its result.
function show( query , result ){ var text=""; for(var prop in query) { text+=prop + "=" + query[prop] + " "; } text+="==> " + result; document.getElementsByTagName("p")[0].innerHTML=text; }