带有分组数据过滤器的 Google 仪表板 - 如何绘制分组数据图表

Posted

技术标签:

【中文标题】带有分组数据过滤器的 Google 仪表板 - 如何绘制分组数据图表【英文标题】:Google dashboard with filters from grouped data - how to chart grouped data 【发布时间】:2011-09-17 20:14:45 【问题描述】:

我希望创建一个带有过滤功能的 Google 图表 API 仪表板,但我想根据分组数据绘制数据图表。例如,我可以创建一个这样的数据表:

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

我可以适当地创建一个仪表板,该仪表板创建两个控件(用于 cust_age 和 cust_sex)和任意数量的输出图形和表格,所有这些都从外部数据源中提取 - 这是非常常见的东西,请参阅 http://code.google.com/apis/chart/interactive/docs/gallery/controls.html

我遇到的问题是如何按分组值显示所有图表。以饼图为例,在没有任何过滤器的情况下,饼图有 5 个切片(Joe、Joe、Suzie、Dave、Dave)——我只想看到三个(Joe、Suzie Dave)。当然,当一个控件被应用时,一切都应该更新。

换句话说,过滤器应该作用于原始数据表,但图表应该基于分组数据表。

我猜我们可以使用分组功能: http://code.google.com/apis/ajax/playground/?type=visualization#group 但是我似乎无法将过滤器绑定到更大的数据表,更新分组表,然后根据分组表绘制图表。

有什么想法吗?

【问题讨论】:

运气好吗?我实际上需要做一些与此非常相似的事情...... 【参考方案1】:

我找到了一个解决方法,你应该使用不带仪表板的 chartWrapper,这样你就可以传递一个 dataTable 作为参数:

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);

然后,您应该向控件添加回调,以便每当控件更改时,仪表板外部的图表都会更新,就像手动绑定一样,假设 cust_sex 的控件是 $genderPicker 并且 ChartWrapper 表对象是 $表格包装器:

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();
);

结果:无论您选择男性、女性还是两者,饼图都会反映按名称分组的过滤结果。希望它对某人有所帮助,并为我的英语不好感到抱歉。

【讨论】:

看起来不错,但在我的代码中根本没有可用的变量google.visualization.events.addListener(orgFilter, 'statechange', function(e) alert(e); ); 给出“null”。在此语句之前定义的变量也不可用。有什么想法吗?【参考方案2】:

另一种方法是使用仪表板对象的“就绪”事件,然后根据对仪表板主表进行的分组在其中创建图表或表格。

例如:

//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)

【讨论】:

这种方式比在控件上监听状态变化更干净、更容易,因为我在尝试更新图表之前遇到了一些应用了过滤器的表格的竞争条件。在仪表板上聆听准备就绪可以消除这种竞争条件并且像魅力一样工作。谢谢 对于那些寻找其他示例的人,我找到了一个相关的解决方案,其中包含有助于澄清用法的详细信息:***.com/a/23836866/4088892【参考方案3】:

经过长时间的研发,我找到了解决这个问题的方法。对于修复,我使用了两个事件侦听器,其中一个是 ready 事件,另一个是 statechange 事件,

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();
 );

找到我最初的(有问题的)sample here 和修复的(已解决的)sample here

【讨论】:

【参考方案4】:

阅读此主题:How to not display the data table(至少阅读前两篇文章 - 其余的只有在处理大型数据集时才真正重要)。

基本上,您必须使用对用户完全隐藏的中间图表(表格是一个不错的选择,因为它们的编写和渲染速度相对较快,内存占用量比大多数图表低)。您将类别选择器绑定到仪表板中的此图表。然后为选取器的“statechange”事件设置一个事件处理程序,该事件处理程序获取数据,将其分组到一个新的 DataTable 中,并根据分组数据绘制饼图。

【讨论】:

我找到了一个相关的 SO 答案,它说明了这个答案中提到的隐藏中间图。见***.com/a/23836866/4088892。

以上是关于带有分组数据过滤器的 Google 仪表板 - 如何绘制分组数据图表的主要内容,如果未能解决你的问题,请参考以下文章

Google 数据洞察:日期范围过滤器错误

带有 SQL 后端的高性能仪表板

Google Data Studio:使用 Google BigQuery 数据连接器应用自定义维度作为过滤器

Google 可视化仪表板错误

使用报表和仪表板分析数据

如何使用侧车部署 Grafana 仪表板并将仪表板与特定仪表板文件夹分组