December 19, 2011

Virtual Solari Board Improved

As part of the series of posts about displaying data, I've updated the virtual Solari board project again.

It now uses a plugin framework to handle customized look and feel. You create a javascript object with properties and methods specific to your data source, like so:

sf.display.ImageDrum = function() {
  this.order = [' ','AFL','AAL','BAW','DAL','UAE','KLM','DLH','RYR','UAL','AWE'];
};

sf.plugins.airport =  {
  
  // input: map of parameters
  // output: url
  url: function(params){
    var base_url = "data/airport_schedule.php";
    return base_url + "?" + params.serialize();
  },

  formatData: function(data){
    return data.response.results[0].data;
  }

};

sf.display.ImageDrum()'s order is now a series of strings instead of integers, which should be more readable. So in the above example, the CSS looks like:

.splitflap .image span.ctrn { background-position: 0px 0px; } /* transition */
.splitflap .image span.csp { background-position: 0px -40px; } /* blank */
.splitflap .image span.AFL { background-position: 0px -80px; } /* aeroflot */
.splitflap .image span.AAL { background-position: 0px -120px; } /* american */
.splitflap .image span.BAW { background-position: 0px -160px; } /* british airways */
.splitflap .image span.DAL { background-position: 0px -200px; } /* delta */
.splitflap .image span.UAE { background-position: 0px -240px; } /* emirates */
.splitflap .image span.KLM { background-position: 0px -280px; } /* klm */
.splitflap .image span.DLH { background-position: 0px -320px; } /* lufthansa */
.splitflap .image span.RYR { background-position: 0px -360px; } /* ryanair */
.splitflap .image span.UAL { background-position: 0px -400px; } /* united */
.splitflap .image span.AWE { background-position: 0px -440px; } /* us airways */

But the big change here is that the project now uses backbone.js as its MVC framework. That means that the list of rows is a Collection and each row is a Model. This allows us to use Backbone's comparator function to handle row sorts. The Collection is always maintained in the correct order, and you have access to all the cool stuff you get in that framework.

It also means that split-flap.js used only for the display stuff. In fact, there's really only one object there--sf.display--and you really only call two methods on it: initRow() and either loadRow() or loadSequentially(). The rest of the code is outside split-flap.js.

Creating a board now looks like this:

// generate the empty rows markup (a backbone View)
var board = new Board;

// get the sort, etc. params
var container = $("#display1");
var params = container.find(".chartPrefs input");
var dataOptions = {
  "sort": container.find("input[name=sort]").val(),
  "order": container.find("input[name=order]").val()
};

// create the chart object (a backbone Collection)
var flights = new Flights;
flights.dataOptions = dataOptions;
flights.url = sf.plugins.airport.url(params);
flights.comparator = function(flight){
  if(dataOptions === "desc"){
    return -flight.get(dataOptions.sort);
  } else {
    return flight.get(dataOptions.sort);
  }
}
// update the chart (and set a refresh interval)
flights.update(container);
setInterval(function(){
  flights.update(container);
}, 30000); // refresh interval

See that "flights.comparator"? That's just an example of how you might want to handle sorting. How you structure your Collections is up to you. For example, the collection of flights looks like this:

// This Collection is used to hold the datset for this board. 
var Flights = Backbone.Collection.extend({
  update: function(container){
    this.fetch({
      success: function(response){
         sf.display.loadSequentially(response.toJSON(), container);
      }
    });
  },
  parse: function(json){
    return(sf.plugins.airport.formatData(json)); // normalize this data 
  }
});

You can see the plugin I showed earlier at work here where we call sf.plugins.airport.formatData(). This allows you to normalize your data formatting across APIs, which is something I've been pushing a lot lately.

I've also created another example board to go with the airport departures board. This one uses the Weather Underground's Weather API to display some airport weather data. This one is actually slightly more complex than the airport board because it has to make several calls to the API to build the Collection.

Anyway, check it out. As always, the project is on github here:
https://github.com/baspete/Split-Flap

and the live demo is here:
http://dev.basdesign.com/split-flap/

[edit - changed github repo]

No comments:

Post a Comment