Drawing plots with NVD3

D3 is a library that offers low-level components for building interactive visualizations in JavaScript. By offering the low-level components, it gives a huge degree of flexibility to the developer. The learning curve can, however, be quite steep. In this example, we will use NVD3, a library which provides pre-made graphs for D3. This can greatly speed up initial development. We will place the code in the file repoGraph.js and expose a single method, build, which takes, as arguments, a model and a div and draws a pie chart in that div. The pie chart will aggregate language use across all the user's repositories.

The code for generating a pie chart is nearly identical to the example given in the NVD3 documentation, available at http://nvd3.org/examples/pie.html. The data passed to the graph must be available as an array of objects. Each object must contain a label field and a size field. The label field identifies the language, and the size field is the total size of all the repositories for that user written in that language. The following would be a valid data array:

[ 
  { label: "Scala", size: 1234 },
  { label: "Python", size: 4567 }
]

To get the data in this format, we must aggregate sizes across the repositories written in a particular language in our model. We write the generateDataFromModel function to transform the repos array in the model to an array suitable for NVD3. The crux of the aggregation is performed by a call to Underscore's groupBy method, to group repositories by language. This method works exactly like Scala's groupBy method. With this in mind, the generateDataFromModel function is:

// public/javascripts/repoGraph.js

define(["underscore", "d3", "nvd3"], 
function(_, d3, nv) {

  // Aggregate the repo size by language.
  // Returns an array of objects like:
  // [ { label: "Scala", size: 1245}, 
  //   { label: "Python", size: 432 } ]
  function generateDataFromModel(model) {

    // Build an initial object mapping each
    // language to the repositories written in it
    var language2Repos = _.groupBy(model.repos, 
      function(repo) { return repo.language ; }) ;

    // Map each { "language":  [ list of repos ], ...} 
    // pairs to a single document { "language": totalSize }
    // where totalSize is the sum of the individual repos.
    var plotObjects = _.map(language2Repos, 
      function(repos, language) {
        var sizes = _.map(repos, function(repo) { 
          return repo.size; 
        });
        // Sum over the sizes using 'reduce'
        var totalSize = _.reduce(sizes, 
          function(memo, size) { return memo + size; },
        0) ;
        return { label: language, size: totalSize } ;
      }) ;

     return plotObjects;
  }

We can now build the pie chart, using NVD3's addGraph method:

  // Build the chart.
  function build(model, divName) {
    var transformedModel = generateDataFromModel(model) ;
    nv.addGraph(function() {

      var height = 350;
      var width = 350; 

      var chart = nv.models.pieChart()
        .x(function (d) { return d.label ; })
        .y(function (d) { return d.size ;})
        .width(width)
        .height(height) ;

      d3.select(divName).append("svg")
        .datum(transformedModel)
        .transition()
        .duration(350)
        .attr('width', width)
        .attr('height', height)
        .call(chart) ;

      return chart ;
    });
  }

  return { "build" : build } ;

});

This was the last component of our application. Point your browser to 127.0.0.1:9000 and you should see the application running.

Congratulations! We have built a fully-functioning single-page web application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.151.220