I'm trying to learn to use d3js datamaps and I'm struggling with dynamic data.
Every example in the site uses some static data, written as a javascript object, but I need it to be dynamic.
I'm starting from a JSON file in which I've got some data, and I'm parsing them to create a new JSON that follows the data format of datamaps.
The output JSON is like this one:
{
ARG: {
plays: 15768,
fillKey: "LOW"
},
AUT: {
plays: 31061,
fillKey: "LOW"
},
AUS: {
plays: 169478,
fillKey: "LOW"
},
BEL: {
plays: 65295,
fillKey: "LOW"
},
BRA: {
plays: 12602,
fillKey: "LOW"
},
GBR: {
plays: 731583,
fillKey: "LOW"
},
ITA: {
plays: 131569,
fillKey: "LOW"
},
USA: {
plays: 272685,
fillKey: "LOW"
}
}
If I execute
map.updateChoropleth({ARG: {plays: 15768,fillKey: "LOW"},AUT: {plays: 31061,fillKey: "LOW"},AUS: {plays: 169478,fillKey: "LOW"},BEL: {plays: 65295,fillKey: "LOW"},BRA: {plays: 12602,fillKey: "LOW"},GBR: {plays: 731583,fillKey: "LOW"},ITA: {plays: 131569,fillKey: "LOW"},USA: {plays: 272685,fillKey: "LOW"}})
or if I instantiate the map with
data: {ARG: {plays: 15768,fillKey: "LOW"},AUT: {plays: 31061,fillKey: "LOW"},AUS: {plays: 169478,fillKey: "LOW"},BEL: {plays: 65295,fillKey: "LOW"},BRA: {plays: 12602,fillKey: "LOW"},GBR: {plays: 731583,fillKey: "LOW"},ITA: {plays: 131569,fillKey: "LOW"},USA: {plays: 272685,fillKey: "LOW"}}
it all goes fine, but this means using static hardcoded data and this is not what I need.
Until now I've tried some routes, with no success.
Writing the data property of the map object like this
data: function() { return parseJSON("json/world-top/latest.json")}
leads to nothing, and the same applies to
data: parseJSON("json/world-top/latest.json")
and
var jsonString = parseJSON("json/world-top/latest.json");
map.updateChoropleth(jsonString);
Where am I wrong?
EDIT:
The parseJSON function that I'm using is a function that I wrote to change my JSON data from
{
"tracks": [{
"date": "2014-05-11",
"country": "ARG",
"track_url": "https:\/\/play.spotify.com\/track\/3cHyrEgdyYRjgJKSOiOtcS",
"track_name": "Timber",
"artist_name": "Pitbull",
"artist_url": "https:\/\/play.spotify.com\/artist\/0TnOYISbd1XYRBk9myaseg",
"album_name": "Global Warming: Meltdown (Deluxe Version)",
"album_url": "https:\/\/play.spotify.com\/album\/2F7tejLHzTqFq2XLol9ZGy",
"artwork_url": "http:\/\/o.scdn.co\/300\/d096684f9d3fa3525421f2c4204f4e8e2cbba471",
"num_streams": 50382
},
{
"date": "2014-05-11",
"country": "AUT",
"track_url": "https:\/\/play.spotify.com\/track\/7b71WsDLb8gG0cSyDTFAEW",
"track_name": "Summer",
"artist_name": "Calvin Harris",
"artist_url": "https:\/\/play.spotify.com\/artist\/7CajNmpbOovFoOoasH2HaY",
"album_name": "Summer",
"album_url": "https:\/\/play.spotify.com\/album\/0IGsZsrvIe5AQKvMmVobYq",
"artwork_url": "http:\/\/o.scdn.co\/300\/ca67ba1425e4308104ecae9fc493f3ef96ceb72a",
"num_streams": 32885
},
{
"date": "2014-05-11",
"country": "AUS",
"track_url": "https:\/\/play.spotify.com\/track\/3oxO64VclwEDBoJWkeneBW",
"track_name": "Fancy",
"artist_name": "Iggy Azalea",
"artist_url": "https:\/\/play.spotify.com\/artist\/5yG7ZAZafVaAlMTeBybKAL",
"album_name": "Fancy",
"album_url": "https:\/\/play.spotify.com\/album\/5oX3sr8ft9IwnI090Xf35t",
"artwork_url": "http:\/\/o.scdn.co\/300\/d71d05ded1704bcf849465dd5e76e196847d1c0a",
"num_streams": 201763
},
{
"date": "2014-05-11",
"country": "BEL",
"track_url": "https:\/\/play.spotify.com\/track\/3s4U7OHV7gnj42VV72eSZ6",
"track_name": "Rather Be feat. Jess Glynne",
"artist_name": "Clean Bandit",
"artist_url": "https:\/\/play.spotify.com\/artist\/6MDME20pz9RveH9rEXvrOM",
"album_name": "Rather Be feat. Jess Glynne",
"album_url": "https:\/\/play.spotify.com\/album\/4UB0J5V3JsZZtNR360pZ6r",
"artwork_url": "http:\/\/o.scdn.co\/300\/a1babd2524962d4703a6c1aa9dfddcc2018713fd",
"num_streams": 110491
},
{
"date": "2014-05-11",
"country": "BRA",
"track_url": "https:\/\/play.spotify.com\/track\/3s4U7OHV7gnj42VV72eSZ6",
"track_name": "Rather Be feat. Jess Glynne",
"artist_name": "Clean Bandit",
"artist_url": "https:\/\/play.spotify.com\/artist\/6MDME20pz9RveH9rEXvrOM",
"album_name": "Rather Be feat. Jess Glynne",
"album_url": "https:\/\/play.spotify.com\/album\/4UB0J5V3JsZZtNR360pZ6r",
"artwork_url": "http:\/\/o.scdn.co\/300\/a1babd2524962d4703a6c1aa9dfddcc2018713fd",
"num_streams": 17953
},
{
"date": "2014-05-11",
"country": "GBR",
"track_url": "https:\/\/play.spotify.com\/track\/5Sf3GyLEAzJXxZ5mbCPXTu",
"track_name": "Waves - Robin Schulz Radio Edit",
"artist_name": "Mr. Probz",
"artist_url": "https:\/\/play.spotify.com\/artist\/33W1pnW9zScZtYTnAoWnOT",
"album_name": "Waves",
"album_url": "https:\/\/play.spotify.com\/album\/7l4LGPXk2mB80WgXy4VeuB",
"artwork_url": "http:\/\/o.scdn.co\/300\/ccfb05bea829a2dc0c736f591a22eac50c18aa56",
"num_streams": 1401994
},
{
"date": "2014-05-11",
"country": "ITA",
"track_url": "https:\/\/play.spotify.com\/track\/3s4U7OHV7gnj42VV72eSZ6",
"track_name": "Rather Be feat. Jess Glynne",
"artist_name": "Clean Bandit",
"artist_url": "https:\/\/play.spotify.com\/artist\/6MDME20pz9RveH9rEXvrOM",
"album_name": "Rather Be feat. Jess Glynne",
"album_url": "https:\/\/play.spotify.com\/album\/4UB0J5V3JsZZtNR360pZ6r",
"artwork_url": "http:\/\/o.scdn.co\/300\/a1babd2524962d4703a6c1aa9dfddcc2018713fd",
"num_streams": 228436
},
{
"date": "2014-05-11",
"country": "USA",
"track_url": "https:\/\/play.spotify.com\/track\/3oqCnpAoHf3SDFynxx7AU4",
"track_name": "Fancy",
"artist_name": "Iggy Azalea",
"artist_url": "https:\/\/play.spotify.com\/artist\/5yG7ZAZafVaAlMTeBybKAL",
"album_name": "Fancy",
"album_url": "https:\/\/play.spotify.com\/album\/20a4p8pXFFG3ZungWSbYv3",
"artwork_url": "http:\/\/o.scdn.co\/300\/62d2b5169d34280636d6f2f93f0215f50621c75e",
"num_streams": 2877914
}
],
"prevDate": "2014-05-04"
}
to the output JSON that I wrote before.
This is the parseJSON function:
parseJSON = function(jsonFile){
var tracks = {};
var json = $.ajax({
url: jsonFile,
dataType: 'json',
data: "",
success: function(data){tracks = data.tracks;},
async: false
});
console.log(tracks);
var outputString = "{";
for(var i = 0; i<tracks.length; i++){
var numberOfPlays = Math.round(tracks[i].num_streams*Math.random(1000));
var fillColor = (numberOfPlays > 5000000)? "HIGH" : (numberOfPlays < 5000000 && numberOfPlays > 1000000) ? "MEDIUM" : "LOW";
outputString+=tracks[i].country + ":{ plays:" + numberOfPlays + ", fillKey: \"" + fillColor + "\"}";
if (i != tracks.length-1) outputString+=",";
}
outputString+="}";
console.log(outputString);
return outputString;
}
I need to do this because datamaps expect the data to be formatted like
{
COUNTRY-CODE: {
property1: value,
property2: value
}
...
}
That's why using
d3.json("json/world-top/latest.json", function(error, latest_data) {
if (error) {
// Display a helpful message to the user
console.log(error);
} else {
console.log("updating");
map.updateChoropleth(latest_data);
}
});
as suggested by @James Trimble is not working too.
As far as I know, parseJSON is not available unless you are using jQuery, in which case you would use $.parseJSON. (JavaScript in modern browsers does have a built-in JSON.parse method.)
The bigger problem is that your code is trying to parse the file name rather than the contents of the JSON file. This is easily solved by using d3.json to load the data via AJAX. Here is an example that uses this method. The code you will need is something like:
d3.json("json/world-top/latest.json", function(error, latest_data) {
if (error) {
// Display a helpful message to the user
} else {
map.updateChoropleth(latest_data);
}
});
An important point to remember is that the code following the d3.json statement will continue to run while the data is being loaded. Therefore, you need to put all of your update code within the callback function.
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