Creating a Visualization App Using the Google Charts API and AngularJS – Part 3

Tweet
This entry is part 3 of 4 in the series Creating a Visualization App Using the Google Charts API and AngularJS

Creating a Visualization App Using the Google Charts API and AngularJS

In the first and second parts of this series, we focused on AngularJS controllers and directives. In this part, we’ll focus on the two-way data binding feature of AngularJS.

Data Binding in AngularJS

Angular’s data binding allows changes to a model to be automatically reflected in the view, and vice versa. A detailed explanation of AngularJS data binding can be found here.

We will be adding a few features to our visualization app. First, we’ll add a drop down where we can select the type of graph. Let’s add a few charts in the drop down. Open up index.html and add a select element as shown below:

<select id="chartType"></select>

If we want, we can define the options for the dropdown in HTML only, but let’s do it the Angular way. Open up controllers.js, and define the options as shown below.

$scope.chartTypes = [
  {typeName: 'PieChart', typeValue: 'PieChart'},
  {typeName: 'BarChart', typeValue: 'BarChart'},
  {typeName: 'ScatterChart', typeValue: 'ScatterChart'},
  {typeName: 'LineChart', typeValue: 'LineChart'}
];
$scope.chartType = $scope.chartTypes[0];

Now, controllers.js looks like this:

'use strict';

/* Controllers */
google.load('visualization', '1', {packages: ['corechart']});
google.setOnLoadCallback(function() {
  angular.bootstrap(document.body, ['myApp']);
});
angular.module('myApp.controllers', []).
  controller('MyCtrl1', ['$scope',function($scope) {
    var data = google.visualization.arrayToDataTable([
      ['Year', 'Sales', 'Expenses'],
      ['2004',  1000,      400],
      ['2005',  1170,      460],
      ['2006',  660,       1120],
      ['2007',  1030,      540]
    ]);
    var options = {
      title: 'Company Performance'
    };
    var chart = {};

    chart.data = data;
    chart.options = options;

    $scope.chartTypes = [
      {typeName: 'LineChart', typeValue: '1'},
      {typeName: 'BarChart', typeValue: '2'},
      {typeName: 'ColumnChart', typeValue: '3'},
      {typeName: 'PieChart', typeValue: '4'}
    ];
    $scope.chartType = $scope.chartTypes[0];
    $scope.chart = chart;
  }])
  .controller('MyCtrl2', [function() {
  }]);

Now, we need to bind chartTypes to the drop down. In AngularJS, we can bind options to a drop down using ngOptions. We also need to bind chartType to the selected value in the drop down, and for that we use ngModel. So, add attributes named ng-options and ng-model to the drop down, as shown below.

<select id="chartType" ng-model="chartType" ng-options="c.typeName for c in chartTypes">
</select>

ng-options iterates over the values in chartTypes and binds each typeName to the drop down. Before running the node server, we need to modify the ng-controller value such that it is attached to the body element. The resulting index.html file is shown below.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My AngularJS App</title>
    <link rel="stylesheet" href="css/app.css" />
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
  </head>
  <body ng-controller="MyCtrl1">
    <div g-chart></div>
    <select id="chartType" ng-model="chartType" ng-options="c.typeName for c in chartTypes">
    </select>
    <div>Angular seed app: v<span app-version></span></div>

    <script src="lib/angular/angular.js"></script>
    <script src="lib/angular/angular-route.js"></script>
    <script src="js/app.js"></script>
    <script src="js/services.js"></script>
    <script src="js/controllers.js"></script>
    <script src="js/filters.js"></script>
    <script src="js/directives.js"></script>
  </body>
</html>

Next, start the node server using the following command.

node scripts/web-server.js

By navigating to http://localhost:8000/app/index.html you should see the pre-populated drop down list.

Changing the Chart Type

We’re going to use ngChange to render our chart based on the section in the drop down list. Inside controllers.js define another $scope variable as shown below.

$scope.selectType = function(type) {
  $scope.chart.type = type.typeValue;
}

We also want to set the default chart type:

chart.type = $scope.chartTypes[0].typeValue;

After adding ng-change to the select element, it should look like this:

<select id="chartType" ng-change="selectType(chartType)" ng-model="chartType" ng-options="c.typeName for c in chartTypes">
</select>

Changing the chart type causes the $scope.chart.type variable to be udpated. This change should be watched so that the chart changes accordingly. For that we have some thing called $scope.$watch, which watches for a change in the $scope. In directives.js, wrap the link callback, inside $scope.$watch as shown below.

link: function($scope, elm, attrs) {
  $scope.$watch('chart', function() {
    var chart = new google.visualization.LineChart(elm[0]);

    chart.draw($scope.chart.data, $scope.chart.options);
  }, true);
}

This change causes every change to $scope.chart to trigger the callback function. Inside the $scope.$watch callback function, we need to check for $scope.chart.type and create a chart object accordingly. Modify the gChart directive in directives.js as shown below.

.directive('gChart',function() {
  return {
    restrict: 'A',
    link: function($scope, elm, attrs) {
      $scope.$watch('chart', function() {
        var type = $scope.chart.type;
        var chart = '';

        if (type == '1') {
          chart = new google.visualization.LineChart(elm[0]);
        } else if (type == '2') {
          chart = new google.visualization.BarChart(elm[0]);
        } else if (type == '3') {
          chart = new google.visualization.ColumnChart(elm[0]);
        } else if (type == '4') {
          chart = new google.visualization.PieChart(elm[0]);
        }

        chart.draw($scope.chart.data, $scope.chart.options);
      },true);
    }
  };
});

Now, when you select a different chart type from the drop down, the chart is updated.

Conclusion

In this tutorial, we implemented a drop down list and bound it using Angular’s two-way data binding. In our next tutorial, we’ll focus on adding some more features and bootstrapping the app to give it a feel good look. In the meantime, the code is available on GitHub, and a live demo is hosted on Heroku.

Creating a Visualization App Using the Google Charts API and AngularJS

<< Creating a Visualization App Using the Google Charts API and AngularJS – Part 2Creating a Visualization App Using the Google Charts API and AngularJS – Part 4 >>

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • James Sheives

    Excellent, thank you.

  • Ravi

    It was really helpful. Thank you.