HomeContact
Archive
More Google Charts with a CSV: Bubble Charts
Jon Page
August 01, 2013
3 min

Table Of Contents

01
Add Controls for Size and Color
02
Changing the Chart Type
03
Feeding the Data to the Chart
04
Updating the Chart
05
Improving Upon the Defaults
06
Conclusion

Last time we built an interactive scatter plot. This time we’re going to turn that scatter plot into a bubble chart (see a preview of the finished product here). Start by openning up the HTML document we created last time. You can see the source here or see the section below:

<!DOCTYPE html>
<html>
  <head>
    <title>Google Chart Example</title>
    <script src="https://www.google.com/jsapi"></script>
    <script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script src="jquery.csv-0.71.js"></script>
    <script>
      // load the visualization library from Google and set a listener
      google.load("visualization", "1", {packages: ["corechart" ]});
      google.setOnLoadCallback(drawChart);

      function drawChart() {
        // grab the CSV
        $.get("kzn1993.csv", function(csvString) {
          // transform the CSV string into a 2-dimensional array
          var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});

          // use arrayData to load the select elements with the appropriate options
          for (var i = 0; i < arrayData\[0\].length; i++) {
            // this adds the given option to both select elements
            $("select").append("<option value='" + i + "'>" + arrayData[0][i] + "</option");
          }
          // set the default selection
          $("#domain option[value='0']").attr("selected","selected");
          $("#range option[value='1']").attr("selected","selected");

          // this new DataTable object holds all the data
          var data = new google.visualization.arrayToDataTable(arrayData);

          // this view can select a subset of the data at a time
          var view = new google.visualization.DataView(data);
          view.setColumns([0,1]);
          var options = {
            title: "KwaZulu-Natal Household Survey (1993)",
            hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
            vAxis: {title: data.getColumnLabel(1), minValue: data.getColumnRange(1).min, maxValue: data.getColumnRange(1).max},
            legend: 'none'
          };
          var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
          chart.draw(view, options);

          // set listener for the update button
          $("select").change(function(){
            // determine selected domain and range
            var domain = +$("#domain option:selected").val();
            var range = +$("#range option:selected").val();
            // update the view
            view.setColumns([domain,range]);
            // update the options
            options.hAxis.title = data.getColumnLabel(domain);
            options.hAxis.minValue = data.getColumnRange(domain).min;
            options.hAxis.maxValue = data.getColumnRange(domain).max;
            options.vAxis.title = data.getColumnLabel(range);
            options.vAxis.minValue = data.getColumnRange(range).min;
            options.vAxis.maxValue = data.getColumnRange(range).max;
            // update the chart
            chart.draw(view, options);
          });
        });
      }
    </script>
  </head>
  <body>
    <div id="chart" style="width:800px; height:500px;"></div>
    <select id="range"></select>
    <select id="domain"></select>
  </body>
</html>

Add Controls for Size and Color

Bubble charts add two dimension, size and color, to the standard scatter plot (here I’m using Google’s terminology, several other graphics libraries simply add this functionality to their scatter plot functions). To keep the nice interactivity we built into our last chart, let’s start by adding controls for the color and size. We’ll nest everything in an unordered list and add labels to the controls. Just change the section with two <select> tags to match the following:

<ul>
  <li>Y-Axis <select id="range"></select></li>
  <li>X-Axis <select id="domain"></select></li>
  <li>Color <select id="color"></select></li>
  <li> Size <select id="size"></select></li>
</ul>

Next we want to get rid of the bullets in our unordered list. Add the following <style> tag inside your <head> tag.

<style> ul {list-style-type: none; } </style>

Changing the Chart Type

Change the line that loads the chart object from this:

var chart = new google.visualization.ScatterChart(document.getElementById('chart'));

to this:

var chart = new google.visualization.BubbleChart(document.getElementById('chart'));

Feeding the Data to the Chart

The data table for Google’s bubble chart requires the first coloumn to be a string which can be used to identify the bubbles. When we loaded the CSV into an array in the last tutorial, we parsed all values as scalars. We need to update our DataView call to change the values in the first column, the household ids (hhid), to string. This requires us to add a function to retrieve these strings from the DataTable.

var view = new google.visualization.DataView(data);
view.setColumns([{calc:stringID, type: "string"},1,2,3]);
// this function returns the first column values as strings (by row)
function stringID(dataTable, rowNum){
  return dataTable.getValue(rowNum, 0).toString();
}

Updating the Chart

Now we need to modify the code that updates the chart when a user changes the selected variables. First we’ll add local variables for color and size to the <select> listener function. These variables need to be assigned the value of the respective <select> tag. After we have column indices for color and size, we will set these as the third and fourth columns (after the id column) in our bubble chart view. See the highlighted lines below:

$("select").change(function(){
  // determine selected domain and range
  var domain = +$("#domain option:selected").val();
  var range = +$("#range option:selected").val();
  var color = +$("#color option:selected").val();
  var size = +$("#size option:selected").val();
  // update the view
  view.setColumns([{calc:stringID, type: "string"},domain,range,color,size]);
  // update the options
  options.hAxis.title = data.getColumnLabel(domain);
  options.hAxis.minValue = data.getColumnRange(domain).min;
  options.hAxis.maxValue = data.getColumnRange(domain).max;
  options.vAxis.title = data.getColumnLabel(range);
  options.vAxis.minValue = data.getColumnRange(range).min;
  options.vAxis.maxValue = data.getColumnRange(range).max;
  // update the chart
  chart.draw(view, options);
});

Unfortunately, when I test this and select a few variables of interest I get the following chart. This is not very useful. The id values obscure all the information.

bubble1
bubble1

Improving Upon the Defaults

Removing the Bubble Label

The bubble labels would work fine if we had only a few data points and being able to quickly identify them was important. In this case, we are more interested in the general relationships between the variables and not the specific position of any one household. Let’s start by removing the bubble label. Go to our stringID function and return an empty string instead of the household id (be sure to comment out the old return statement):

function stringID(dataTable, rowNum){
  // return dataTable.getValue(rowNum, 0).toString();
  // return an empty string instead to avoid the bubble labels
  return "";
}

Now let’s check our chart:

bubble2
bubble2

Removing the Bubble Border and Adjusting Bubble Opacity

Okay. This is a lot nicer, but we can do better by removing the bubble borders and lowering the bubble opacity, since both cause issues with occlusion (i.e., there is data we are not seeing due to overly opaque data in the foreground). To remove the bubble’s border we’ll set it’s stroke color to “transparent”. Let’s change the opacity from the default of 0.8 to 0.2. To implement this we need to add an element to our initial options object

var options = {
  title: "KwaZulu-Natal Household Survey (1993)",
  hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
  vAxis: {title: data.getColumnLabel(1), minValue: data.getColumnRange(1).min, maxValue: data.getColumnRange(1).max},
  bubble: {stroke: "transparent", opacity: 0.2},
};

and reset it in our <select> listener function:

// update the options
options.hAxis.title = data.getColumnLabel(domain);
options.hAxis.minValue = data.getColumnRange(domain).min;
options.hAxis.maxValue = data.getColumnRange(domain).max;
options.vAxis.title = data.getColumnLabel(range);
options.vAxis.minValue = data.getColumnRange(range).min;
options.vAxis.maxValue = data.getColumnRange(range).max;
options.bubble = {stroke: "transparent", opacity: 0.2};

Let’s take a look:

bubble3
bubble3

Changing the Color Gradient

This is starting to look great. One issue I have with the default color choice, besides being ugly, is that gray with an opacity of 0.2 is hard to see. Let’s make the color gradient change from red to blue. We do this again by adding an element to the initial options object

var options = {
  title: "KwaZulu-Natal Household Survey (1993)",
  hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
  vAxis: {title: data.getColumnLabel(1), minValue: data.getColumnRange(1).min, maxValue: data.getColumnRange(1).max},
  bubble: {stroke: "transparent", opacity: 0.2},
  colorAxis: {colors: ['red','blue' ]},
};

and resetting it in our <select> listener function:

// update the options
options.hAxis.title = data.getColumnLabel(domain);
options.hAxis.minValue = data.getColumnRange(domain).min;
options.hAxis.maxValue = data.getColumnRange(domain).max;
options.vAxis.title = data.getColumnLabel(range);
options.vAxis.minValue = data.getColumnRange(range).min;
options.vAxis.maxValue = data.getColumnRange(range).max;
options.bubble = {stroke: "transparent", opacity: 0.2};
options.colorAxis = {colors:\['red','blue'\]};

Bam! And here’s our finished product:

bubble4
bubble4
These changes have made it easier to explore the dataset and added a little style in the process. You can find an interactive version here (check the source if you are having problems with your chart).

Conclusion

While this ramped up the complexity of our figure (compared to the chart from the previous tutorial), being able to change which variables control the color and size of the bubbles will make your data that much more engaging. Take the source, change the reference to your CSV, and remember to download a copy of the jquery-csv script. With just a few steps you can have your own interactive chart to encourage your site’s viewers to explore your data. Check out the next tutorial in this series: Google Charts and CSV Part 3: Side-by-Side Bubble Charts For more information on Google’s bubble chart, check the documentation here.


Tags

#javascript#visualizations

Related Posts

Google Charts and CSV Part 3: Side-by-Side Bubble Charts
August 27, 2013
2 min
© 2022, All Rights Reserved.

Quick Links

About UsContact Us

Social Media