Open Data Visualization

So far, all our posts related to Open Data have been focused on the recovery process and contents publication as well as the infrastructure needed for this process.

We start a series of articles where we will make simple examples of visualization, changes (changes in javascripts applying and using the API Rest provided by the platform) in the display CKAN resource and finally implementing a plugin / CKAN extension that allows to incorporate advanced visualization capabilities.

For the virtualization examples of this article, we will take with game data, the result of a consultation on the end-point of the DBPedia SPARQL. Specifically, we will require the name, coordinates and cities around the world (in the example the number of results is limited to 15).

In this first approach, starting with a query on the sparql end-point offered by DBPedia, we will make a simple presentation of the results relying on the most popular graphics libraries (d3, jit y jquery.ui.map).

Open Data visialization sample

Step 1. SPARQL Query

We begin with the construction of the SPARQL query that will return the results that we will visualize later on:

var endpoint = "http://dbpedia-live.openlinksw.com/sparql";
var query = "SELECT * WHERE {
	?subject rdf:type <http://dbpedia.org/ontology/City>.
	?subject rdfs:label ?label.
	?subject rdfs:comment ?descr.
	?subject <http://dbpedia.org/ontology/populationTotal> ?populationTotal.
	?subject <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?geoLat.
	?subject <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?geoLong.
	FILTER (lang(?label) = 'en' && lang(?descr) = 'en')} LIMIT 15";
var progress=10;
var default_graph = "?default-graph-uri=";
var format = "&format=" + "json";
var urlQuery = endpoint + default_graph + "&query=" + escape(query) + format;

Next step will be running the query and trying the JSON result to generate a list of objects that will be used later as javascript parameter in various functions responsible for the data presentation.

$.ajax({
    url: urlQuery,
    dataType: 'jsonp',
    jsonp: 'callback',
    success: function(data) {
    	resQuery  = [];
	for (var i = 0; i < data.results.bindings.length; i++) {
		resQuery.push({
			population: contenido = data.results.bindings[i].populationTotal.value,
			geoLat: data.results.bindings[i].geoLat.value,
			geoLng: data.results.bindings[i].geoLong.value,
			cityName: data.results.bindings[i].label.value});
	}        

    	addMap(resQuery, "#widget1"); //MAP ON DIV1
        addPieChart(resQuery, "#widget2"); //PIE ON DIV3
        addBarChart(resQuery, "#widget3"); //BAR ON DIV3
    }
});

For graphics presentation it will be applyed the HTML structure shown in the following code:

<body>
	<div id="container" class="container">
		<div class="dashboard">
   		 	<ul>
   		 		<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
   		 			<h3>Instance 1: Maps</h3>
   		 			<div id="widget1" class="map"></div>
   		 		</li>
   		 		<li data-row="2" data-col="1" data-sizex="1" data-sizey="1">
   		 			<h3>Instance 2: Bar</h3>
   		 			<div id="widget2" ></div>
   		 		</li>
   		 		<li data-row="1" data-col="2" data-sizex="1" data-sizey="1">
   		 			<h3>Instance 3: Pie graphic</h3>
   		 			<div id="widget3"></div>
   		 		</li>
   		 	</ul>
               </div>
    </div>
</body>

Step 2: Data visualization on maps

We will nsert a marker on the map for each of the cities included in the results, using the library jquery.ui.map:

function addMap(resultArray, widget){
	var geo;

	for (i=0;i<resultArray.length;i++){
		geo = resultArray[i].geoLat +','+resultArray[i].geoLng;
		$(widget).gmap('addMarker',
			{'position': geo, 'bounds': true}).click(function() {
				$(widget).gmap('openInfoWindow',
				   {'content': resultArray[i].cityName}, this);
		});
	}
}

Step 3: Pie / Bar charts generation

To generate the graph examples we inclined on this occasion by the library d3.

Pie chart:

function addPieChart(resultArray, widget){
  	var chart = nv.addGraph(function() {
		var cHeight = 150;
   		var cWidth  = 450;

    	var dataPieChart = [];
     	var valuesPieChart = [];
		for (j=0;j<resultArray.length;j++){
			valuesPieChart.push({
				"label": resultArray[j].cityName,
				"value": resultArray[j].population});
		}  

     	dataPieChart.push({key: "Población Capitales Europeas",
     		values: valuesPieChart});

		var chart = nv.models.pieChart()
        	.x(function(d) { return d.label })
        	.y(function(d) { return d.value })
        	.showLabels(true)
        	.showLegend(false)
        	.labelThreshold(.06)
        	.donut(false)
        	.margin({top: 10, right: 0, bottom: 0 , left: 0})
        	.width(cWidth)
        	.height(cHeight);

    	d3.select(widget)
    		.datum(dataPieChart)
        	.transition().duration(120)
        	.attr('width', cWidth)
        	.attr('height', cHeight)
        	.call(chart);

    	return chart;
     });
}

Bar chart:

function addBarChart(resultArray, widget){
	var chart = nv.addGraph(function() {
		var cHeight = 200;
   		var cWidth  = 900;

     	var dataObj = [];
     	var valuesObj = [];
		for (i=0;i<resultArray.length;i++){
			valuesObj.push({
				"label": resultArray[i].cityName,
				"value": resultArray[i].population});
		}  

     	dataObj.push({key: "Población Capitales Europeas",
     		values: valuesObj});

     	var chart = nv.models.discreteBarChart()
        	.x(function(d) { return d.label })
        	.y(function(d) { return d.value })
        	.taggerLabels(true)
        	.tooltips(true)
        	.showValues(true)
        	.width(cWidth)
        	.height(cHeight);

    	d3.select(widget)
    		.datum(dataObj)
          	.transition().duration(120)
          	.call(chart);

    	return chart;
     });
}

As noted at the beginning of this article, there have been very basic examples of data visualization, but they have let us take the first steps for implementing a CKAN extension that will enrich  the resources visualization offered by CKAN (specifically, we focus in version 2.0).

Leave a Reply