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;
}