Creating Interactive GeoCharts in Salesforce Visualforce

Creating Interactive GeoCharts in Salesforce Visualforce

Hello There! Welcome Back
Hope you are doing great

In this blog we are gonna take a look at plotting our Salesforce Data onto Geographical Charts(A geographical representation of our Salesforce Data) using the Google Charts’ Library.
We get our data from an Apex Controller.

Let’s get started!

Things we will be using:

  1. GeoCharts(Google Charts Library)

  2. Google GeoCoding API

Step 1: Gathering the resources we need.

  1. Getting a Google API Key:
    We will be using the API Key to Geocode the Region(ex. Country) get a Standard Name for the region that is to be plotted onto the map.
    This required because the GeoChart Library accepts a particular format of the Regions’ Name to plot it on to the chart as specified in Google GeoCharts’ documentation here.
    You can get the API Key here.
    1) Click “Get A Key”.
    2) Sign In with your Google Account you already havent.
    3) Create a New Project and Enable API.

Now we have all the stuff we need, lets code what we want.

Step 2: The Code.

  1. Define a controller and its constructor to get the data from Salesforce which is basically the count of records per BillingCountry (Apex Code Snippet).

  2. Add the Google Charts Script Source (Visualforce Code: Line 3)

  3. Add a container for GeoChart (Visualforce Code: Line 5)

  4. Add JavaScript code to load the GeoChart module (Visualforce Code: Line)

  5. Add the code to call the “standardizeData” function on chart load that loops through our data to standardize it using Google’s GeoCoding API and puts the Country Name into one array and the number of records for the country in another array (Visualforce Code: Lines)

  6. Once we are done standardising our data, we call the “drawChart” function which prepares our standardized data to be plotted onto the GeoChart and draw the chart with color options (Visualforce Code: Line)

Visualforce Code

<apex:page sidebar="false" controller="geoChartCon" readOnly="true">
   <!–Google Charts Script Source–>
   <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
   <!–GeoChart Container–>
   <div id="GeoChart" style="width: 100%;height: 500px;">
      <!– SLDS Spinner Start–>
      <div class="slds-spinner_container">
         <div role="status" class="slds-spinner slds-spinner–large slds-spinner–brand">
            <span class="slds-assistive-text">Loading</span>
            <div class="slds-spinner__dot-a"></div>
            <div class="slds-spinner__dot-b"></div>
         </div>
      </div>
      <!– SLDS Spinner End–>
   </div>
   <script type="text/javascript">
      //Loading the GeoChart Library
      google.charts.load(‘upcoming’, {‘packages’:[‘geochart’]});
      var country = [];
      var count = [];
      //Our Data From Apex
      var ChartData = {!AllData};
      //Length of our Data Array
      var chartDatalen = ChartData.length;
      var cntr = 0;
      //Calling a standardizing function with the first record from our data
      google.charts.setOnLoadCallback(function(){standardizeData(cntr)});

      function standardizeData(idx) {

      var xmlhttp = new XMLHttpRequest();
      //REPLACE YOUR_API_KEY BELOW WITH YOUR GOOGLE API KEY AS GENERATED WITH THE STEPS MENTIONED ABOVE
      var url = ‘https://maps.googleapis.com/maps/api/geocode/json?address=’+ChartData[idx].BillingCountry+’&key=YOUR_API_KEY’;

      xmlhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
      var myArr = JSON.parse(this.responseText);
      if(myArr.status != ‘ZERO_RESULTS’){
      var countryname = myArr.results[0].address_components[0].long_name;
      if(country.indexOf(countryname) != -1){
      count[country.indexOf(countryname)] += ChartData[idx].expr0;
      }else{
      country.push(countryname);
      count.push(ChartData[idx].expr0);
      }
      }
      if(idx < chartDatalen-1){
      standardizeData(idx+1);
      }else{
      //Calling the drawChart function to prepare data and draw the chart
      drawChart();
      }
      }
      };
      xmlhttp.open(‘GET’, url, true);
      xmlhttp.send();
      }

      function drawChart(){
      //Initializing a Google DataTable(required format to plot data onto chart)
      var data = new google.visualization.DataTable();
      data.addColumn(‘string’, ‘Country’);
      data.addColumn(‘number’, ‘Count’);

      //Adding our Standardized Data to Google DataTable
      for(i = 0; i < count.length; i++)
      data.addRow([country[i], count[i]]);

      //Color options for the Chart, white and blue to blend into the standard salesforce colors
      var options = {
      colorAxis: {colors: [‘#76c6ee’, ‘#1589ee’, ‘#0070d2’]},
      backgroundColor: ‘#ffffff’,
      datalessRegionColor: ‘#ffffff’,
      defaultColor: ‘#0070d2’
      };

      //Getting the GeoChart Div Container
      var chart = new google.visualization.GeoChart(document.getElementById(‘GeoChart’));

      //Drawing the GeoChart with Data and Options
      chart.draw(data, options);
      }
   </script>
</apex:page>

geoChartCon.apxc

public with sharing class geoChartCon {

    public string AllData { get; set; }

    public geoChartCon() {
        AllData = JSON.serialize([SELECT BillingCountry, COUNT(Name) FROM Account GROUP BY BillingCountry ORDER BY BillingCountry]);
    }

}

And it will look like this:

There it is! We just created an interactive GeoChart to visualize our salesforce data.
Awesome, Right?

You can also checkout my other post about Using Google Charts in Salesforce here.

For more chart customizations checkout the awesome Google GeoCharts’ library here.