Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating d3js Datamap with dynamic data

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.

like image 327
StepTNT Avatar asked Apr 15 '26 08:04

StepTNT


1 Answers

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.

like image 109
James Trimble Avatar answered Apr 16 '26 21:04

James Trimble



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!