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:
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.
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?
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With