Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Google Visualization Geomap in AngularJS

5.00/5 (3 votes)
1 Jul 2016CPOL2 min read 13.8K   151  
In this small tip, I will explain how we can embed Google Visualization Geomap in the AngularJS with select event getting the selected location and using it to populate other data.

Introduction

This small tip will help to embed Google Visualization Geomap in AngularJS to take AngularJS advantages, e.g., data binding, filtering and responsive behavior.

Let's Start

Let's start with a simple example. Assume there is a big company having consulting business in all states of US. We want to see US map and by clicking on each state, revenue for different departments should be displayed.

The basic code for Geomap is taken from the following URL:

HTML
<html>
   <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>           
     <script type="text/javascript">
       google.charts.load('current', {'packages':['geomap']});
       google.charts.setOnLoadCallback(drawMap);
       function drawMap() 
            {         
             var data = google.visualization.arrayToDataTable([
                                                              ['Country', 'Popularity'],
                                                              ['Germany', 200],
                                                              ['United States', 300],
                                                              ['Brazil', 400],
                                                              ['Canada', 500],
                                                              ['France', 600],
                                                              ['RU', 700]
                                                              ]);
                           var options = {};
                           options['dataMode'] = 'regions';
                           var container = document.getElementById('regions_div');
                           var geomap = new google.visualization.GeoMap(container);
                           geomap.draw(data, options);       
                          };     
         </script>   
       </head>   
     <body>     
      <div id="regions_div" style="width: 900px; height: 500px;"></div>   
     </body>
</html>

Next, let's update this code to have AngularJS and separate the JavaScript and HTML. First, update the Google map setOnLoadCallback method and add angular.bootstrap function to manually start the Angular application (read more about angular.bootstrap here).

JavaScript
google.load('visualization', '1', { 'packages': ['geochart'] });

google.setOnLoadCallback(function () {
    angular.bootstrap(document.body, ['mapsApp']);
});

Surround the rest of code in Angular Module and Controller

JavaScript
angular.module('mapsApp', []).
  controller('MapCtrl', ['$scope', '$filter',
    function ($scope, $filter) {

All states and number of company's branches in each state are added as data input to the Geomap.

JavaScript
var data = google.visualization.arrayToDataTable([
    ['State', 'Number of Branches'],
      ['AL', 32],
      ['AR', 12],
      ['AZ', 181],
      ['CA', 624],
      ['CO', 139],
      ['CT', 45],
      ['DC', 28],
      ..................
      ..................

Next, coding block is used to setup Map UI and regions to display. This is quite self-explanatory.

JavaScript
var opts = {
           backgroundColor: { fill: '#FFFFFF', stroke: '#FFFFFF', strokeWidth: 0 },
           colorAxis: { minValue: 0, maxValue: 4, colors:
           ['blue', 'yellow', 'green', 'purple', 'brown', ] },
           legend: 'none',
           backgroundColor: { fill: '#FFFFFF', stroke: '#FFFFFF', strokeWidth: 0 },
           datalessRegionColor: '#f5f5f5',
           displayMode: 'regions',
           enableRegionInteractivity: 'true',
           resolution: 'continents',
           sizeAxis: { minValue: 1, maxValue: 1, minSize: 10, maxSize: 10 },
           region: 'US',
           displayMode: 'regions',
           resolution: 'provinces',
           width: 640,
           height: 480
       };

Once the UI and data input to Geomap is done, it's time to draw the map. Specify the DIV name where you want to add the Map. In my case, DIV name is visualization.

JavaScript
geochart = new google.visualization.GeoChart(
        document.getElementById('visualization'));
       geochart.draw(data, opts);

According to our requirement, we want to display each state's department revenue so let's add the click event in our Geomap. In Geomap, we have select event that can return value from Geomap input dataset. The following code block will get the state name once user will click on any state on the map and call $scope.findValue method that will search revenue data from JSON array.

JavaScript
google.visualization.events.addListener(geochart, 'select', function () {
           var selectedItem = geochart.getSelection()[0];
           if (selectedItem) {
               $scope.findValue(data.getValue(selectedItem.row, 0));
           }
       });

Following is the revenue data against each state, you can always load this data from datasource using AngularJS services but for POC purpose, I am hard coding the data:

JavaScript
$scope.mapdata = {
           "results": [{
               state: 'AL',

               IT: '$323,208,017.0  ',
               FINANCE: '$46,620,000.00  ',
               MARKETING: '$63,875,000.00  ',
               AUDIT: '$27,440,000.00  ',
           },
           {
               state: 'AR',

               IT: '$107,302,792.00',
               FINANCE: '$11,660,000.00 ',
               MARKETING: '$741,785,000.00',
               AUDIT: '$741,785,000.00',

           },
           ..................
           ..................

The findValue function will take state name as input parameter and by using the  AngularJS $filter method, it searches revenue data from $scope.mapdata JSON array variable and returns the result. There was some issue with two way binding and $scope.result was not visible in HTML so I used the $scope.$apply method to explicitly populate the $scope variables.

JavaScript
$scope.findValue = function (vstate) {
          var res = $filter('filter')($scope.mapdata.results, { state: vstate })[0];
          $scope.$apply(function () { $scope.result = res; });
      }

Our result is stored in $scope.result variable that you can use in HTML file to display.

HTML
<script src="angular.js"></script>
<script src="jsapi.js"></script>

<script src="mapsApp.js"></script>

<div ng-controller="MapCtrl" class="row">
    <div  id="visualization" style="margin: 1em; float:left"> </div>
    
    <div style="float:right">
        <div style="width:600px">
            <div style="width:600px;">
                <div style="width:200px; 
                float:left"><b>Department</b></div>
                <div style="width:200px; 
                float:left"><b>Revenue</b></div>
            </div>
            <br />
            <hr />
            <br />
            <div style="width:600px;">
                <div style="width:200px; 
                float:left"><b>IT</b></div>
                <div style="width:200px; 
                float:left">{{result.IT}}</div>
            </div>
            <br />
            <div style="width:600px;">
                <div style="width:200px; 
                float:left"><b>Finance</b></div>
                <div style="width:200px; 
                float:left">{{result.FINANCE}}</div>
            </div>
            <br />
            <div style="width:600px;">
                <div style="width:200px; 
                float:left"><b>Marketing</b></div>
                <div style="width:200px; 
                float:left">{{result.MARKETING}}</div>
            </div>
            <br />
            <div style="width:600px;">
                <div style="width:200px; 
                float:left"><b>Audit</b></div>
                <div style="width:200px; 
                float:left">{{result.AUDIT}}</div>
            </div>
        </div>
    </div>
</div>

History

  • 7/1/2016: Created

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)