JavaScript Sample Code

Author: / Archived under Tools

View raw code

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.

Main

External variables

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>

Program

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

Core function

getValue()

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

Helper functions

getDimIndices()

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()

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()

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

Utility functions

JSONstat()

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()

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