Google Charts API

Multiple Charts on a Page

Introduction

There should not be a problem putting multiple charts on a page, either displaying the same data in different charts or loading a new set of data in a new datatable. The Google Charts API documentation for multiple charts is fairly clear but there are a couple of gotchas.

Chart Loader

The chart loader must only be called once on a page. Calling it multiple times will result in problems.

<script src="https://www.gstatic.com/charts/loader.js"></script>

Chart Libraries

About half of the charts can be loaded a single library named "corechart"

google.charts.load('current', {'packages':['corechart']});

Charts loaded using corechart are: Area, Bar, Bubble, Candlestick, Column, Combo, Diff, Donut, Histogram, Intervals, Line, Pie, Scatter, Stepped Area, Trendline, and Waterfall

The exceptions are (package to be loaded in brackets): Annotation (annotationchart), Calendar (calendar), Gantt (gantt), Gauge (gauge) , Geo (geochart), Map (map), Org (orgchart), Sankey (sankey), Table (table), Timeline (timeline), Tree Map (treemap), Vega (vegachart), and Word Tree (wordtree)

Where multiple charts need to be loaded a single statement can be used, for example:

google.charts.load('current', {packages: ['corechart', 'table', 'sankey']};

If the chart to be drawn is not one of those included in the the corechart set then it does not need to be included, for example:

google.charts.load('current', {packages: ['timeline']};


Let the User Choose!

There are many ways to visualize data amd the designer must ensure the proper chart type is chosen to display the data. Sometimes it is better to give the user a choice which visualization to use to better understand the data.

The Google Charts API allows the redrawing of the data without importing it again. The following example uses a simple dropdown to allow the user to change the chart type.

Notes

The data comes from a Google Sheet. This is the documentation for the API Column Charts.

This example is not the same as the Controls and Dashboards in the API. Those are designed to filter data, this example changes the chart type drawn.

This chart is based on a column chart and the changes in the sub-type are maded by changing the chart options.

This example uses the onChange event in the dropdown to trigger the redrawing of the chart. Some people may prefer to use an event listener. For more complex projects a single event listener can be used to listen for events anywhere within a element with an ID and distinguish which element inside it triggered the listener. Handling Events for Many Elements by Kirupa explains how to do this.

The code changes between three values for the column chart, false, true and 'percent'. If you just need to toggle between false and true then this simple code works for boolean values:

variable = !variable;

I use namespaces in my JavaScript as per the W3C JavaScript Best Practices. This stops my code interfering with any libraries I may use and vice versa. Because redrawChart needs to accessed by the dropdown, I needed to make a global variable inside the namespace to hold the data table. I also had to return the redrawChart function at the end of the namespece to make that available to the dropdown.

The chart shows the sex of students in a small college for various semesters. By changing the chart type the various relationships and trends of the data can be seen more easily.

The HTML for the dropdown is:


	<select id="chooseChart" onchange="studentSex.redrawChart()">
  	<option value="Column">Column</option>
  	<option value="Stacked">Stacked</option>
  	<option value="Percent">Percent</option>
	</select>
	

The JavaScript for the above chart is:


    <script type="text/javascript">
	var studentSex = (function() {
	// create namespece global variable to hold the data
	var studentData;
    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(drawChart);
	
    function drawChart() {
		var queryString = encodeURIComponent('SELECT B,C,D ORDER BY A');
		var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=1786091632&headers=1&tq=' + queryString);
      query.send(handleQueryResponse);
    }

    function handleQueryResponse(response) {
      if (response.isError()) {
        alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
        return;
      }
		
    studentData = response.getDataTable();
		
	redrawChart();
	} 
		
	unction redrawChart(){
	var chartType = document.getElementById("chooseChart").value;
	var optionVar = false;
	if (chartType == "Stacked") {optionVar = true}
	if (chartType == "Percent") {optionVar = 'percent'}
	var options = {isStacked: optionVar};
	var chart = new google.visualization.ColumnChart(document.getElementById('studentData_div'));
    chart.draw(studentData, options);
	} 
	
	// Make the redrawChart function available outside the studentSex namespece by returning it.
	// This is so the onChange event of the dropdown can access it 
	return{redrawChart};
	})();
	</script>
    

In the following example the same data is used and it is the chart type that is changed.

Notes

Notice that because the code for this example is in a different JavaSCript namepsace than the previous, the same variable and function names can be used and that they do not interfer with each other. This is the whole point of using namespaces. The scope of the functions and variables is confined to the namespace.

There is no easy way for variables to be used in the chart definitions and so the entire line is defined.

If the chartWrapper Class is used then the setChartType or setOptions methods can be used in the options or drawChart constructor to change the chart type and those can accept variables.

There is no reason changing both the chart type and the options for them cannot be used together. Care must be taken that the defaults are defined or odd behaviours may show or the chart may not draw at all.

Both Column and Bar charts use the corechart library so there is no need to load another. Some charts will require the loading of other chart libraries.

The HTML for the dropdown is:


	<select id="chartType" onchange="changeChart.redrawChart()">
  	<option value="Column">Column</option>
  	<option value="Bar">Bar</option>
	</select>
	

The JavaScript for the above chart is:


    <script type="text/javascript">
	var changeChart = (function() {
	// create namespece global variable to hold the data
	var studentData;
    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(drawChart);
	
    function drawChart() {
		var queryString = encodeURIComponent('SELECT B,C,D ORDER BY A');
		var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=1786091632&headers=1&tq=' + queryString);
      query.send(handleQueryResponse);
    }

    function handleQueryResponse(response) {
      if (response.isError()) {
        alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
        return;
      }
		
    studentData = response.getDataTable();
		
	redrawChart();
	} 
		
	function redrawChart(){
	var chartType = document.getElementById("chartType").value;
	if (chartType == "Column") {chart = new google.visualization.ColumnChart(document.getElementById('changeChart_div'));}
	if (chartType == "Bar") {chart = new google.visualization.BarChart(document.getElementById('changeChart_div'));}
	
    chart.draw(studentData);
	}
	
	// Make the redrawChart function available outside the changeChart namespece by returning it.
	// This is so the onChange event of the dropdown can access it 
	return{redrawChart};
	})();
	</script>
    
This page created January 12, 2021; last modified January 20, 2021