65.9K
CodeProject is changing. Read more.
Home

Google Visualization Geomap in AngularJS

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3 votes)

Jul 1, 2016

CPOL

2 min read

viewsIcon

13772

downloadIcon

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>
   <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).

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

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

Surround the rest of code in Angular Module and Controller

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.

 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.

 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.

 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.

 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:

 $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.

  $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.

<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