I made several tests today related to the way we can load json files with d3 because I was intrigued by this question: d3.json works but $.getJson fails. However some of the tests that I made are a little bit tricky.
d3.xhr("http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*+where+%7B%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FRoger_Federer%3E+%3Fp+%3Fo+filter%28lang%28%3Fo%29+%3D+%27en%27%29%7D%0D%0A&debug=on&timeout=&format=application%2Fsparql-results%2Bjson&save=display&fname=", function(data)
console.log("success1");
alert(data);
});
d3.json("http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*+where+%7B%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FRoger_Federer%3E+%3Fp+%3Fo+filter%28lang%28%3Fo%29+%3D+%27en%27%29%7D%0D%0A&debug=on&timeout=&format=application%2Fsparql-results%2Bjson&save=display&fname=", function(data){ console.log("success2");
alert(data);
});
d3.xhr("http://api.worldbank.org/countries/BRA/indicators/BX.KLT.DINV.CD.WD?per_page=10&date=2007:2012&format=json", function(data){
console.log("success3");
alert(data);
})
d3.json("http://api.worldbank.org/countries/BRA/indicators/BX.KLT.DINV.CD.WD?per_page=10&date=2007:2012&format=json", function(data){
console.log("success4");
alert(data);
})
I know that the problem can be related to at least 2 reasons: MIME type and CORS, but I can't understand several other things:
if the callback is always executed (even tough sometimes with the OK 200 which can also be an error as seen from jQuery's .ajax() and .getJSON() methods) why can I see the data in only one case (the first one) - the rest of the cases are always errors?
what are the MIME types supported by d3.xhr method?
if d3.json was just a nice wrapper for d3.xhr why does example 1 works and example 2 doesn't work...? I would like some clarification. I mostly use d3 with files from my server, but there are cases like this when I also have to use some external data, and it would be really nice to do this also with D3, not just with jQuery.
I think there should be a list with all the MIME types accepted by these methods.
The reason why the first request succeeds while the second fails has to do with a configuration of the dbpedia.org server. The d3.json()
function does two things:
It sets the Accept
header to the mimetype application/json
It parses the response using JSON.parse()
Number 1 is the issue - the dbpedia.org server is returning a response of 406 (Unacceptable)
for the Accept: application/json
header. I'm not sure why this is true, but given the URL parameters you're sending, it looks like the server expects application/sparql-results+json
instead - indeed, specifying this mime-type with d3.xhr()
succeeds, while using application/json
fails.
With the World Bank data, the request fails because the server is not CORS-enabled. The only in-browser way to make a call to a remote API without CORS enabled is to use JSONP (assuming the API supports it). As it happens, data.worldbank.com does support JSONP, but D3 does not - you'll need to either deal with it yourself or use a 3rd-party library like jQuery to make the request.
In general, D3 has not prioritized really robust AJAX support the way that jQuery and other libraries have, because that's not its focus - so if you want to load a wide variety of external resources, you should probably do so with a 3rd-party library that has more support for carefully tweaked AJAX calls. Depending on what you want to load, the other option is to set up a proxy on your own server that can call the remote APIs and then give the data back to your visualizations via a local HTTP call - in which case all of D3's loaders should work fine.
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