Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading local data for visualization using D3.js

I am working on a project which requires me to visualize a rather complicated type of data (see this older question). In short, I have a large chunk of data which I can export to JSON, CSV or some other arbitrary flat format although I prefer to avoid XML if possible (see the linked question above for in-detail explanation of the underlying data).

I have started working on a visualization using D3, the layout I wrote seems to work OK so far when I test it with some very simple data that I hardcode in the Javascript as an array. The tutorials I read on data binding in D3 have been a bit confusing in the sense that some use JSON and some use TXT/CSV format while some others use hardcoded arrays/matrices.

In the case of JSON, I watched a tutorial where the narrator firmly advises to host the JSON file on a webserver and get it using a HTTP request instead of a local file read. I realize that this is due to cross domain request limitations, which I believe I have to work-around somehow. At this point I am not sure how to proceed since:

  1. The D3-powered visualization will be on a series of HTML reports which are created as results of an analysis tool I wrote. The analysis is done on the users computer, and the HTML reports are also created locally on the client-side.

  2. The intended users are most definitely not tech-savvy, so it is not an option to instruct them to run an webserver on their computer to be able to serve JSON or any other type or resource via localhost

For the record, I have tried running the python SimpleHTTPServer module to try it out, and again everything works fine. I then tried to hard-code the data in the generated HTML reports, then call on the JSON object from my script which uses D3,

//d3.json("mydata.json", function(json){
d3.json(myjson, function(json){
    nodeData = json.elements;
....
}

which fails since in that case I end up sending in a JSON object while D3.js is expecting a URL.

What can I do to avoid/solve this problem?

like image 847
posdef Avatar asked Jul 10 '12 10:07

posdef


1 Answers

To load data local files without using a server, append a script tag to the body with the source data assigned to a variable or object element that you are expecting. In the example below, I load data for a certain country from a [COUNTRY_ISO3CODE].js file. Specifically, an Afghanistan data file might have the content in the format:

data[AFG] = {"name": "Afghanistan", "estimate": 9.003, ... }

The calling file will have something like:

if (!data[iso3]) { //only load the needed data-script as needed

    // if using jQuery
    $('body').append("<script type='text/javascript' src='jdb/"+ iso3 +".js'></script>")

    //If not using jQuery
    /*var script   = document.createElement("script");
    script.type  = "text/javascript";
    script.src   = "jdb/"+iso3+".js"; //?_="+ (new Date()); URL might have to be randomized to avoid cached data
    document.body.appendChild(script);
    */

    // call the data-handling function only after 
    // the desired data has fully loaded
    // in this case, I check every 100 milliseconds
    var intervalId = setInterval( function () {
        if (data[iso3]) {    //once data is detected, process data
            clearInterval(intervalId); //stop checking for data
            prepData(mainWrapper, iso3)
            drawCharts(mainWrapper, iso3)
        }
    }, 100)
}
else drawCharts(mainWrapper, iso3)
like image 113
Edgar Avatar answered Sep 28 '22 07:09

Edgar