Search code examples
javascriptchartsgoogle-visualizationdashboardgraphing

Using data.group for Google Visualization Dashboards


I have a table with two keys, like so:

+------+------+-------+
| key1 | key2 | value |
+------+------+-------+
| abc  | 123  |   5   |
| abc  | 456  |   7   |
| abc  | 789  |   9   |
| xyz  | 123  |   2   |
| xyz  | 456  |   4   |
| xyz  | 789  |   6   |
+------+------+-------+

I wish to be able to filter this table by key2, so I created a google.visualization.Dashboard like so:

var dashboard = new google.visualization.Dashboard();
dashboard.bind([
    new google.visualization.ControlWrapper({
        "controlType": "CategoryFilter",
        "containerId": "...",
        "options": {
            "filterColumnIndex": 1
        }
    });
], [
    new google.visualization.ChartWrapper({
        "chartType": "Table",
        "containerId": "...",
        "options": {...}
    });
]);

Now here's the rub: I wish to add a pie chart to this table which aggregates data by key1. So without any filtering, the pie chart would show something like:

abc = 21
xyz = 12

But if I filtered down to "456" then it should show:

abc = 7
xyz = 4

Now if I weren't using a dashboard, I can accomplish this aggregation like so:

var graph = new google.visualization.PieChart();
var aggregatedData = google.visualization.data.group(
    data,
    [0],
    [{
        "column": 2,
        "aggregation": google.visualization.data.sum,
        "type": "number"
    }]
);
graph.draw(aggregatedData);

However I don't know how to perform this aggregation within a dashboard


Solution

  • save a reference to the table chart,
    use its 'ready' event to draw the pie chart

    anytime the filter changes, the 'ready' event will fire

    you can pull the filtered data table from the table chart,
    to use for your aggregation

    it will be the same data table used to draw the dashboard,
    with any filters applied

    just be sure to assign the 'ready' event,
    before drawing the dashboard

    something like the following snippet...

    var chartTable = new google.visualization.ChartWrapper({
        "chartType": "Table",
        "containerId": "...",
        "options": {...}
    });
    
    var dashboard = new google.visualization.Dashboard();
    dashboard.bind([
        new google.visualization.ControlWrapper({
            "controlType": "CategoryFilter",
            "containerId": "...",
            "options": {
                "filterColumnIndex": 1
            }
        });
    ], [
        chartTable
    ]);
    
    google.visualization.events.addListener(chartTable, 'ready', function () {
        var graph = new google.visualization.PieChart(needContainer);
        var aggregatedData = google.visualization.data.group(
            chartTable.getDataTable(),
            [0],
            [{
                "column": 2,
                "aggregation": google.visualization.data.sum,
                "type": "number"
            }]
        );
        graph.draw(aggregatedData);
    });
    
    dashboard.draw(data);
    

    note: the dashboard also has a 'ready' event,
    but it will fire for each bound control and chart,
    so twice in this scenario

    and you also need somewhere to pull the filtered data table from,
    hence saving a reference to the table chart...