Playing the Unique game...

goo.gl/io2011charts

Using Google Chart Tools
to Create Interactive Dashboards

Michael Fink, Riccardo Govoni and Amit Weinstein
May 10, 2011

Feedback http://goo.gl/ZBOCN,     Hashtag #GoogleAPIs

Outline

  • Part 1 - charts for everyone...

  • Part 2 - hands on session
    • Apps scripts - charts services
    • Chart wrapper
    • Chart editor
    • Controls and dashboards

Image Credits: Randall Munroe

Motivation

democratized cartography...

democratized video...

democratized 3D...

Can we democratize data visualization?

One chart is worth 1,000 images...

Gravity Wells

Image Credits: Randall Munroe

Scatter plots, bar chart and heat maps by xkcd.com

Image Credits: Randall Munroe

Our Mission

Make the world’s structured data universally accessible and useful using enticing visualizations
Charts for everyone:
  • Consumers
  • Developers
  • Apps / Enterprise
Image Credits: Randall Munroe

For consumers - new charts in Google Spreadsheets...

New Chart Editor in Google Spreadsheets

Unique game votes...

Chart for Developers

  • Chart gallery
  • DataTable
  • DataSources

Charts for developers - Highly customizable

legend:'bottom', colors:['#226622','#aa6644']

Image Credits: Randall Munroe

Charts for developers - Highly customizable

Charts for developers - highly customizable.

Charts for developers - xkcd vs. Dilbert

What else is new?

The Unique game - and the winner is...

Charts in Google Apps Scripts

What is Google Apps Script?

"A JavaScript cloud scripting language that provides easy ways to automate tasks across Google products and third party services."

Built-in support for charts in Google Apps Scripts

The Unique game - Chart generation

  // Populating the DataTable.
  var dataTable = Charts.newDataTable()
      .addColumn("Range" , [1, 2, 3, 4, 5, ...])
      .addColumn("Others", [2, 4, 6, 1, 0, ...])
      .addColumn("You"   , [0, 0, 1, 0, 0, ...])
      .addColumn("Winner", [0, 0, 0, 1, 0, ...]);
  // Creating the chart.
  var chart = Charts.newColumnChart()
      .setTitle("Unique Game: The Results")
      .setDimensions(1200, 800)
      .setDataTable(dataTable)
      .setStacked()
      .build();

The Unique Game - Email the chart

  // Creating the chart blob.
  var chartBlob = chart.getBlob().getBytes();

  // Prepare the email attachment.
  var chartFile = [{fileName: "chart.png",
                    mimeType: "image/png",
                    content: chartBlob}];

  // Send the email.
  MailApp.sendEmail(
      "charts@google.com",
      "The unique game results",  // Subject
      "Sorry, you did not win. Better luck next time.",  // Content
      {attachments: chartFile});

ChartWrapper - Making things simpler

ChartWrapper - Before

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

function drawVisualization() {
  var query = new google.visualization.Query(
      'http://spreadsheets.google.com/tq?key=abc');
  query.send(handleQueryResponse);
}
    
function handleQueryResponse(response) {
  if (response.isError()) { return; } // Handle error.

  var data = response.getDataTable();
  var container = document.getElementById('chart_div')
  chart = new google.visualization.ColumnChart(container);
  chart.draw(data, {});
}

ChartWrapper - After

google.load('visualization', '1');

function drawVisualization() {
  wrapper = new google.visualization.ChartWrapper(
        {dataSourceUrl: 'http://spreadsheets.google.com/tq?key=abc',
         chartType    : 'ColumnChart', 
         containerId  : 'chart_div'});
  wrapper.draw();
}
// We can also easily modify and redraw.
wrapper.setChartType('AreaChart');
wrapper.setOption('title', 'My new AreaChart');
wrapper.draw();

ChartWrapper - One class that does it all

var wrapper = new google.visualization.ChartWrapper({...});
// Serializing the wrapper.
wrapper.toJSON();

// Creating a snippet.
google.visualization.createSnippet(wrapper.toJSON());

Chart Editor

Chart Editor - Chart creation and customization widget

  • Auto suggestions
  • Instant preview
  • Charts gallery
  • Easy customization
As of today, embeddable
in your site.

Chart Editor - Example

// Create the ChartWrappter.
var chartWrapper = new google.visualization.ChartWrapper({
  dataSourceUrl: url    // Using a remote data source.
});

// Create an editor instance.
var editor = new google.visualization.ChartEditor();

// Listen to the 'ok' button/event.
google.visualization.events.addListener(editor, 'ok', function() {
       editor.getChartWrapper().draw(chartContainer);
    });

// Open the editor's dialog.
editor.openDialog(chartWrapper);

Controls and Dashboards

Visualizations are helpful

but they offer a single perspective.

Image credits: Hand Shadows To Be Thrown Upon The Wall, Henry Bursill

Wiring is hard

when you want multiple visualizations to play together

Ethernet cables connected to a router
Image Credits: Randall Munroe

Control

A simple way to drive the data that power one or more visualizations.

A light switch
Image credits: Piotr Lewandowski

Controls gallery

Google Analytics dashboard screenshot

Dashboard

A collection of collaborating controls and visualizations, sharing the same underlying data.

How do Controls and Dashboard work?











  new google.visualization.ChartWrapper({
    'chartType': 'PieChart',
    'options': {'legend': 'right'},
    'containerId': 'chartContainerElement'})
           
                  


  new google.visualization.ControlWrapper({
    'controlType': 'NumberRangeFilter',
    'options' {
      'filterColumnLabel': 'Salary',
      'minValue': 10, 'maxValue': 100},
    'containerId': 'controlContainerElement'})



  new google.visualization.ChartWrapper({
    'chartType': 'PieChart',
    'options': {'legend': 'right'},
    'containerId': 'chartContainerElement'})

                 
new google.visualization.Dashboard(dashboardElement).bind([

  new google.visualization.ControlWrapper({
    'controlType': 'NumberRangeFilter',
    'options': {
      'filterColumnLabel': 'Salary',
      'minValue': 10, 'maxValue': 100},
    'containerId': 'controlContainerElement'})

],[

  new google.visualization.ChartWrapper({
    'chartType': 'PieChart',
    'options': {'legend': 'right'},
    'containerId': 'chartContainerElement'})

])
new google.visualization.Dashboard(dashboardElement).bind([

  new google.visualization.ControlWrapper({
    'controlType': 'NumberRangeFilter',
    'options': {
      'filterColumnLabel': 'Salary',
      'minValue': 10, 'maxValue': 100},
    'containerId': 'controlContainerElement'})

],[

  new google.visualization.ChartWrapper({
    'chartType': 'PieChart',
    'options': {'legend': 'right'},
    'containerId': 'chartContainerElement'})

]).draw(dataTable);

google.visualization.ChartWrapper

Simple wrapper around all chart types. Dead simple.

var wrapper = new google.visualization.ChartWrapper({
  'chartType': 'GeoChart',
  'dataTable': myData,
  'containerId': 'geoElementId',
  'options': {}
});
wrapper.draw();

// Change colors and redraw.
wrapper.setOption('colors', [ '#D6F1FF', '#0A43BF' ]);
wrapper.draw();

// Serialize to JSON
var json = wrapper.toJSON();

google.visualization.ControlWrapper

UI element that collects user input and drives visualizations.

var wrapper = new google.visualization.ControlWrapper({
  'controlType': 'NumberRangeFilter',
  'containerId': 'controlElementId',
  'options': {
    'filterColumnLabel': 'salary',
    'minValue': 100,
    'maxValue': 1000
    },
  'state': {'lowValue': 200, 'highValue': 600}
});

// Change the Control state programmatically
wrapper.setState({'lowValue': 400, 'highValue': 800});

wrapper.setOption('minValue', 0); // And the options too..

google.visualization.Dashboard

Takes care of all the plumbing so you don't have to.

var dashboard = new google.visualization.Dashboard(
  document.getElementById('container'));

// Have one or more Controls affect one or more Charts.
dashboard.bind(
  [controlWrapper1, controlWrapper2],
  [chartWrapper1, chartWrapper2, chartWrapper3]);

// Controls can also affect each other.
dashboard.bind(controlWrapper1, controlWrapper2);

// Draw the entire dashboard.
dashboard.draw(dataTable);

Demo

A blueprint sketch
Image credits: Kahana, O'ahu

Pretending to be Hans Rosling

Watch your steps!

Controls are experimental
(they might break and change over time).

But...

Will improve and evolve listening to your feedback.

We have a lot of features coming down the pipe.

Use them and let us know about your experience.

Thanks!

Image Credits: Randall Munroe