11
votes

I am looking to create a Google charts API dashboard with filtering but I would like to chart the data based on grouped data. For example, I can create a datatable such as this:

salesman  cust_age  cust_sex  quantity
Joe       21        Male      3
Joe       30        Female    10
Suzie     40        Female    2
Dave      15        Female    5
Dave      30        Male      10

I can appropriately create a dashboard that creates two controls (for cust_age and cust_sex) and any number of output graphs and tables all pulling from an external data source - this is pretty stock stuff, see http://code.google.com/apis/chart/interactive/docs/gallery/controls.html

The problem that I am having is how to show all charts by grouped values. Using a pie chart as an example, without any filters there are 5 slices of the pie (Joe, Joe, Suzie, Dave, Dave) - I would like to see only three (Joe, Suzie Dave). Of course, when a control is applied everything should update.

In other words, the filters should act on the original datatable, but the charts should be based on a grouped datatable.

I would guess that we could use the grouping function: http://code.google.com/apis/ajax/playground/?type=visualization#group however I cannot seem to bind the filters to the larger datatable, update the grouped table, and then draw the charts based on the grouped table.

Any thoughts?

4
Any luck? I actually need to do something very similar to this...André Morujão

4 Answers

11
votes

I found a workaround, you should use the chartWrapper without the dashboard, so you can pass a dataTable as parameter:

var $pieChart  = new google.visualization.ChartWrapper({
  'chartType': 'PieChart',
  'containerId': 'pie_chart',
  'options': {
    'width': 300,
    'height': 300,
  },
  //group the data for the pie chart
  'dataTable' : google.visualization.data.group($dataTable, [0],
  [{'column': 3, 'aggregation': google.visualization.data.sum, 'type': 'number'}])
});  
 $pieChart.draw();
 $tableWrapper =  new google.visualization.ChartWrapper({
  'chartType': 'Table',
  'containerId': 'table_data'
});
var $genderPicker = new google.visualization.ControlWrapper({
  'controlType': 'CategoryFilter',
  'containerId': 'gender_filter',
  'options': {
    'filterColumnIndex': '2',
    'useFormattedValue' : true,
    'ui': {
      'allowTyping': false,
      'allowMultiple': false,
      'labelStacking': 'vertical'
    }
  }      
});
new google.visualization.Dashboard(document.getElementById('table_dashboard')).
   bind([$genderPicker], [ $tableWrapper]).
   draw($dataTable);

Then, you should add a callback to your controls so whenever the control changes the charts outside of the dashboard will be updated, like a manual binding, let's assume that the control for cust_sex is $genderPicker and the ChartWrapper table object is $tableWrapper:

google.visualization.events.addListener($genderPicker, 'statechange',
function(event) {
  // group the data of the filtered table and set the result in the pie chart.
  $pieChart.setDataTable( google.visualization.data.group(
    // get the filtered results
    $tableWrapper.getDataTable(),
    [0],
    [{'column': 3, 'aggregation': google.visualization.data.sum, 'type': 'number'}]
  ));
  // redraw the pie chart to reflect changes
  $pieChart.draw();
});

The result: whenever you chose male, female or both the pie chart will reflect the filtered results grouped by name. Hope it helps someone and sorry for my broken english.

6
votes

another way to do it, is to use the 'ready' event of the dashboard object, then create a chart or table in there based on a grouping done to the main table of the dashboard.

eg:

//create datatable, filter elements and chart elements for the the dashboard then:

dash=new google.visualization.Dashboard(document.getElementById(elId));
google.visualization.events.addListener(dash, 'ready', function() {
        //redraw the barchart with grouped data
        //console.log("redraw grouped");
        var dt=mainTable.getDataTable();
        var grouped_dt = google.visualization.data.group(
                          dt, [0],
                          [{'column': 7, 'aggregation': google.visualization.data.sum, 'type': 'number'}]);

        var mainChart = new google.visualization.ChartWrapper({
              'chartType': 'ColumnChart',
              'containerId': 'barChart',
              'options': {
                'height':500,
                'chartArea':{'left':200}
              },
              //view columns from the grouped datatable
              'view': {'columns': [0, 1]},
              'dataTable':grouped_dt
            });
        mainChart2.draw();
    });

dash.bind(
        [lots,of,filter,elements], 
        [lots,of,chart,elements]
    );
dash.draw(data)
3
votes

After a long R&D, I found the solution fot this problem. For the fix, I used two event listeners in which one is ready event and other is statechange event as,

google.visualization.events.addListener(subdivPicker, 'ready',
function(event) {
// group the data of the filtered table and set the result in the pie chart.
columnChart1.setDataTable( google.visualization.data.group(
// get the filtered results
 table.getDataTable(),
 [0],
[{'column': 2, 'aggregation': google.visualization.data.sum, 'type': 'number'}]
));    
// redraw the pie chart to reflect changes
columnChart1.draw();
});

google.visualization.events.addListener(subdivPicker, 'statechange',
 function(event) {
 // group the data of the filtered table and set the result in the pie chart.
 columnChart1.setDataTable( google.visualization.data.group(
 // get the filtered results
 table.getDataTable(),
 [0],
 [{'column': 2, 'aggregation': google.visualization.data.sum, 'type': 'number'}]
 ));
 // redraw the pie chart to reflect changes
 columnChart1.draw();
 });

Find my initial (problematic) sample here and fixed (solved) sample here

0
votes

Read this thread: How to not display the data table (read at least the first two posts - the rest are really only important if you are dealing with large data sets).

Basically, you have to use an intermediary chart (tables are a good choice, because they are relatively fast to write and render, with a lower memory footprint than most charts) that is completely hidden from the users. You bind the category picker to this chart in the dashboard. Then you set up an event handler for the picker's "statechange" event that takes the data, groups it into a new DataTable, and draws the PieChart based on the grouped data.