1

Pulling my hair out here.

Jquery, Multiple JSON files & Ajax

I have a python script that is gathering data and dumping JSON files into a folder on my webserver

I am trying to visualise that data.

Basically I am first drawing an SVG map and coloring it in with a dummy json file. Subsequently I want to color it in using the JSON data. Each JSON file will represent one complete rendering (coloring) of the map.

I am using an Ajax call to a php script that returns the files in the directory. I then want to use Ajax (or the shorthand .getJson) to lad the data in that file -colour the map, and then move on to the next one (end result is an animation). The problem is the asynchronous nature of AJAX and not having any control over the timely execution and completion of the Ajax bit. Obviously i don't want to make a synchronous call because i don't want to lock up the browser.

Here's my code (apologies -it's fairly hefty)

jQuery(document).ready(function() {

$(function() {

    var map, c = [];
    var dep_data;
    var val = {};
    var max= 0;
    var vals = new Array();

    c = $('#map');
    c.height(c.width()*.5);

    drawMap('mapData.json');

    function drawMap(url){
        console.log(url);
        $.ajax({
        url: 'mapData.json',
        dataType: 'json',
        success: function(data) {

            dep_data = data;

            map = window.m = $K.map('#map', 600, 800);
            map.loadMap('ireland.svg', function() {
                map.loadStyles('./mapping_files/style.css');
                map.addLayer({
                    id: 'regions',
                    key: 'name-1'
                });

                colourMap(dep_data);

                    var mapData = $.ajax({
                        url: './php/getfiles.php',
                        type : 'POST',
                        dataType: 'json',
                        success: function (files){

                            for (_a in files.response){
                                for (_b in files.response[_a]){
                                      $.ajax({
                                        url: files.response[_a][_b],
                                        dataType: 'json',
                                        success: function (json){
                                          colourMap(json);
                                          $(this).dequeue();
                                        }
                                      });
                                }       

                            }
                        },

                        error: function (files){
                            console.log(files.message);
                        },

                    });

                });

            }
        });



    }

    colourMap = function(data) {

    //do the coloring in...

}

}); });
Danny Browne
  • 293
  • 1
  • 2
  • 7

2 Answers2

0

Ok,

You might want to decouple your json processing code from the ajax success() function. Instead, sort the data and store it in a global variable. Once all data has been received (check for that), you can call a function to draw your SVG, thus having control over timing. Its like the $.document(ready) of jquery

EDIT:

Depending on your scenario, you need a more efficient queue system for your json files. One method would be to load json files in chunks instead of randomly. You've mentioned that a new file is created every 10 minutes, so obtain the first json file and acquire, lets say, 35 more json files, in effect obtaining 6 hours of data. If one folder currently has less than 36 files, you can choose to wait until all 36 are present, then run the svg code and move on to, or wait for, the next 36 json files. This brings in control over timing, where one svg file represents 6hrs of data. You can also change from 36 to any reasonable value

A Person
  • 1,350
  • 12
  • 23
  • That's kinda where i was headed but once I call the AJAX function to get the JSON filenames in the directory how can i be sure i've got them all (and the order is important) before i start executing my next set of AJAX functions -again, i want these done sequentially but also asynchronously because they are time stamped and the order they are rendered in is important... – Danny Browne Apr 13 '12 at 14:44
  • ok ask yourself, do new json files come in while you are drawing the svg (calling getfiles.php)? – A Person Apr 13 '12 at 14:46
  • how do you choose which json files to obtain in getfiles.php? be specific please – A Person Apr 13 '12 at 14:47
  • Preferably all of them, a new folder is created every day and a json file is created and dumped into that folder every 10 minutes. So the number of files returned will vary depending on the time of day. Early on it will be just a few, by later that day it could be 100+ files. Or i could load 144 at a time so it's a rolling 24hr thing... or fewer... depending on performance. – Danny Browne Apr 13 '12 at 14:55
  • ` $date = date("dmY"); //path to directory to scan $directory = "../json_data/" . $date . "/"; //get all files with a .json extension. $files = glob($directory . "*.json"); foreach ($files as &$file){ $file = substr($file, 1); } $json = json_encode($files); if ($files){ // To return a successful response echo json_encode( array( 'success' => true, 'response' => array($files), ) ); } else { // To return an error echo json_encode( array( 'error' => true, 'message' => 'Error', ) ); }` – Danny Browne Apr 13 '12 at 14:56
  • let me process this, do you mind if i post it as an answer? bit crowded here – A Person Apr 13 '12 at 14:57
  • wait, before that, do you call the svg drawing script at random times or at a set time(noon,midnight,6pm)? – A Person Apr 13 '12 at 14:59
  • ah ok... this is all going to run in a browser (or actually possibly a webView wrapper for an iPad). The map is rendered & initialized form an SVG file (rather than drawn) as soon as the page loads. I then go about adding the colors. Chorlopleth style... – Danny Browne Apr 13 '12 at 15:05
  • here it is hosted on my own site: http://dannybrowne.com/public/vibes/mapping.html – Danny Browne Apr 13 '12 at 15:08
  • i guessed as much when i saw 'map' and 'ireland' – A Person Apr 13 '12 at 15:11
0

Found an awesome solution here that i have tweaked a little as below. Works perfectly. Thanks for the input on this one guys.

        function getFiles(){

        $.ajax({
            url: './php/getfiles.php',
            type : 'POST',
            dataType: 'json',
            success: function (files){

                for (_a in files.response){
                    for (_b in files.response[_a]){
                        var fname = files.response[_a][_b].substr(30, 8);
                        jsonVals[fname] = files.response[_a][_b];
                    }       
                }

                getData();

            },

            error: function (files){
                console.log(files.message);
            },

        });

    }


    function getData(){

        _d = 0;

        function fireRequest(jsonURL) {
                return $.ajax({
                    type: "GET",
                    url: jsonURL,
                    dataType: 'json',
                    success: function(data){
                        console.log("got " + jsonURL);
                        if (_d == Object.size(jsonVals)){ console.log('done'); }


                    }
                });
        }

        var countries=["US","CA","MX"], startingpoint=$.Deferred();
        startingpoint.resolve();

        $.each(jsonVals,function(key, file) {
            startingpoint=startingpoint.pipe( function() {
                    console.log("making requst for " + file);
                    _d = _d + 1;
                    return fireRequest(file);
            });
        });


    }
Community
  • 1
  • 1
Danny Browne
  • 293
  • 1
  • 2
  • 7