谷歌柱形图仪表板

Posted

技术标签:

【中文标题】谷歌柱形图仪表板【英文标题】:Google column chart dashboard 【发布时间】:2015-12-22 23:28:24 【问题描述】:

我有这个谷歌仪表板柱形图:

我的问题是如何对团队进行分组。例如,hAxes 应该只有一列 DOCOPS,而 Utilization 应该是所有 DOCOPS 的总和。

下面是我的代码:-

  <!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script type="text/javascript">

      // Load the Visualization API and the controls package.
     google.load('visualization', '1.0', 'packages':['controls','corechart']);
      // google.load('visualization', '1', 'packages':['corechart']);

      // Set a callback to run when the Google Visualization API is loaded.

     google.setOnLoadCallback(drawDashboard);
      // Callback that creates and populates a data table,
      // instantiates a dashboard, a range slider and a pie chart,
      // passes in the data and draws it.
      function drawDashboard() 

        // Create our data table.
        var data = new google.visualization.DataTable(<?=$jsonTable?>);
      var options = 
           title: 'Utilization',
          is3D: 'true',
          width: 1000,
          height: 600
        ;

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

     var donutRangeSlider = new google.visualization.ControlWrapper(
          'controlType': 'NumberRangeFilter',
          'containerId': 'filter_div',
          'options': 
            'filterColumnLabel': 'Month'
          
        );

     var categoryPicker = new google.visualization.ControlWrapper(
        controlType: 'CategoryFilter',
        containerId: 'TeamName',
        options: 
            filterColumnLabel: 'Teams', // filter by Team name
            ui: 
                caption: 'Choose a Team',
                sortValues: true,
                allowNone: true,
                allowMultiple: true,
                allowTyping: true
            

        
     );

     var columnChart = new google.visualization.ChartWrapper(
          'chartType': 'ColumnChart',
          'containerId': 'chart_div',
          'options': 
            'width': 600,
            'height': 400,

            'legend': 'none',
      'hAxis': 
        'title': 'Teams',
        'titleColor':'#cc0000',
                'titleFontSize':20
      ,
      'vAxis': 
        'title': 'Utilization',
        'titleColor':'#cc0000',
                'titleFontSize':20

      
          ,
      view:
      columns:['Group','Utilization']
      
        );

  /*  var pieChart = new google.visualization.ChartWrapper(
          'chartType': 'PieChart',
          'containerId': 'pie_div',
          'options': 
            'width': 500,
            'height': 300,
            'pieSliceText': 'value',
            'legend': 'right'
          
        ); */



        // Establish dependencies, declaring that 'filter' drives 'pieChart',
        // so that the pie chart will only display entries that are let through
        // given the chosen slider range.
        dashboard.bind([donutRangeSlider, categoryPicker], [columnChart]);

     dashboard.draw(data);
    


    </script>



<body>
    <!--Div that will hold the dashboard-->
    <div id="dashboard_div">
      <!--Divs that will hold each control and chart-->
      <div id="filter_div"></div>
    <div><br><br></div>
      <div id="TeamName"></div>

      <div id="chart_div"></div>
      <div id="pie_div"></div>
    </div>
  </body>

我们有办法做到这一点吗?我不想修改 json 数据。某些参数或将 hAxes 分组为团队名称的东西?

提前致谢!

演示:-

https://jsfiddle.net/dineshrawat/gy7o2yq4/1/

【问题讨论】:

查看演示:jsfiddle.net/dineshrawat/gy7o2yq4/1 【参考方案1】:

您可以通过使用数据表进行分组来实现此目的。将以下监听器添加到您的代码中并添加 dataTable:

 google.visualization.events.addListener(categoryPicker, 'ready',
     function(event) 
         columnChart.setDataTable(google.visualization.data.group(

             table.getDataTable(), [0], [
                 'column': 5,
                 'aggregation': google.visualization.data.sum,
                 'type': 'number'
             ]
         ));

         columnChart.draw();
     );

 google.visualization.events.addListener(categoryPicker, 'statechange',

     function(event) 
         columnChart.setDataTable(google.visualization.data.group(
             table.getDataTable(), [0], [
                 'column': 5,
                 'aggregation': google.visualization.data.sum,
                 'typdpe': 'number'
             ]
         ));
         columnChart.draw();
     );
 

Expected DEMO

还可以查看 Improved Demo 附加的滑块事件。由@Henrik 创建


完成sn-p:

    <!--Div that will hold the dashboard-->
    <div id="dashboard_div">
      <!--Divs that will hold each control and chart-->
      <div id="filter_div"></div>
    <div><br><br></div>
      <div id="TeamName"></div>

      <div id="chart_div"></div>
      <div id="pie_div"></div>
        <div id="table_div"></div>
    </div>
 
<script type="text/javascript" src="http://www.google.com/jsapi"></script>

<script type="text/javascript">
        
// Load the Visualization API and the controls package.
     google.load('visualization', '1.0', 'packages':['controls','corechart']);
      // google.load('visualization', '1', 'packages':['corechart']);

      // Set a callback to run when the Google Visualization API is loaded.

     google.setOnLoadCallback(drawDashboard);
      // Callback that creates and populates a data table,
      // instantiates a dashboard, a range slider and a pie chart,
      // passes in the data and draws it.
      function drawDashboard() 

        // Create our data table.
        var data = new google.visualization.DataTable("cols":["label":"Group","type":"string","label":"Teams","type":"string","label":"Month","type":"number","label":"Work hours","type":"number","label":"Training hours","type":"number","label":"Utilization","type":"number"],"rows":["c":["v":"CLNTSV","v":"CSDelv","v":7,"v":2097.26,"v":0,"v":0.949158],"c":["v":"CLNTSV","v":"CSPro","v":4,"v":168,"v":0,"v":0.5],"c":["v":"CLNTSV","v":"CSPro","v":5,"v":166,"v":112,"v":0.891026],"c":["v":"CLNTSV","v":"CSPro","v":6,"v":228.5,"v":107,"v":1.02287],"c":["v":"CLNTSV","v":"CSPro","v":7,"v":314.25,"v":23,"v":0.900775],"c":["v":"CLNTSV","v":"CSSppt","v":7,"v":2552.46,"v":878.42,"v":0.815323],"c":["v":"CLNTSV","v":"CSSrch","v":7,"v":1231.46,"v":403.81,"v":0.851703],"c":["v":"CLNTSV","v":"Docstars","v":4,"v":1548.36,"v":193.99,"v":0.951064],"c":["v":"CLNTSV","v":"Docstars","v":5,"v":1404.41,"v":192.51,"v":0.988193],"c":["v":"CLNTSV","v":"Docstars","v":6,"v":1421.97,"v":183.93,"v":0.979207],"c":["v":"CLNTSV","v":"Docstars","v":7,"v":164.17,"v":18.17,"v":0.592013],"c":["v":"CLNTSV","v":"JPMC","v":4,"v":2887.24,"v":330.78,"v":0.867859],"c":["v":"CLNTSV","v":"JPMC","v":5,"v":2560.9,"v":1397.62,"v":0.885179],"c":["v":"CLNTSV","v":"JPMC","v":6,"v":3248.59,"v":1931.85,"v":0.933076],"c":["v":"CLNTSV","v":"JPMC","v":7,"v":234.52,"v":142.2,"v":0.370787],"c":["v":"CLNTSV","v":"XFT","v":4,"v":1613.74,"v":114.66,"v":0.862475],"c":["v":"CLNTSV","v":"XFT","v":5,"v":1890.48,"v":69,"v":0.971964],"c":["v":"CLNTSV","v":"XFT","v":6,"v":2083.39,"v":32.52,"v":1.02515],"c":["v":"CLNTSV","v":"XFT","v":7,"v":0,"v":0,"v":0],"c":["v":"DEVLOP","v":"AppSupp","v":4,"v":202.74,"v":65.92,"v":0.233252],"c":["v":"DEVLOP","v":"AppSupp","v":5,"v":137.89,"v":67.83,"v":0.171205],"c":["v":"DEVLOP","v":"AppSupp","v":6,"v":225.98,"v":88,"v":0.266537],"c":["v":"DEVLOP","v":"AppSupp","v":7,"v":317.36,"v":113,"v":0.315513],"c":["v":"DEVLOP","v":"DEVQA","v":4,"v":1727.51,"v":555.75,"v":0.975752],"c":["v":"DEVLOP","v":"DEVQA","v":5,"v":1907.48,"v":85,"v":0.943409],"c":["v":"DEVLOP","v":"DEVQA","v":6,"v":2152.03,"v":108.25,"v":0.987885],"c":["v":"DEVLOP","v":"DEVQA","v":7,"v":2207.88,"v":61.16,"v":0.978034],"c":["v":"DEVLOP","v":"DPS","v":4,"v":205.44,"v":82,"v":0.865783],"c":["v":"DEVLOP","v":"DPS","v":5,"v":102.93,"v":132.75,"v":0.775263],"c":["v":"DEVLOP","v":"DPS","v":6,"v":230.36,"v":140.09,"v":0.945026],"c":["v":"DEVLOP","v":"DPS","v":7,"v":316.99,"v":23,"v":0.923886],"c":["v":"DEVLOP","v":"JiraAdmin","v":4,"v":17.55,"v":0.58,"v":0.172996],"c":["v":"DEVLOP","v":"JiraAdmin","v":5,"v":76.96,"v":7.83,"v":0.815288],"c":["v":"DEVLOP","v":"JiraAdmin","v":6,"v":58.64,"v":0,"v":0.523571],"c":["v":"DEVLOP","v":"JiraAdmin","v":7,"v":63.45,"v":0,"v":0.619629],"c":["v":"DEVLOP","v":"NAT","v":4,"v":276.48,"v":17.67,"v":0.90787],"c":["v":"DEVLOP","v":"NAT","v":5,"v":256.26,"v":14.33,"v":0.914155],"c":["v":"DEVLOP","v":"NAT","v":6,"v":278.43,"v":5,"v":0.90843],"c":["v":"DEVLOP","v":"NAT","v":7,"v":305.96,"v":10.17,"v":0.898097],"c":["v":"DEVLOP","v":"OPSTESTING","v":5,"v":252,"v":32,"v":0.910256],"c":["v":"DEVLOP","v":"OPSTESTING","v":6,"v":340.5,"v":5.5,"v":1.00581],"c":["v":"DEVLOP","v":"OPSTESTING","v":7,"v":246.84,"v":59.75,"v":0.98266],"c":["v":"DEVLOP","v":"OraDev","v":4,"v":264.42,"v":47,"v":0.705208],"c":["v":"DEVLOP","v":"OraDev","v":5,"v":266.92,"v":5.25,"v":0.81003],"c":["v":"DEVLOP","v":"OraDev","v":6,"v":202,"v":8,"v":0.815217],"c":["v":"DEVLOP","v":"OraDev","v":7,"v":314.57,"v":1,"v":0.805026],"c":["v":"DEVLOP","v":"OraSupp","v":4,"v":599.21,"v":164.33,"v":0.821364],"c":["v":"DEVLOP","v":"OraSupp","v":5,"v":530.28,"v":58.54,"v":0.591185],"c":["v":"DEVLOP","v":"OraSupp","v":6,"v":605.3,"v":76,"v":0.665332],"c":["v":"DEVLOP","v":"OraSupp","v":7,"v":476.86,"v":32.18,"v":0.499451],"c":["v":"DEVLOP","v":"WebDev","v":4,"v":1284.88,"v":172.34,"v":0.961227],"c":["v":"DEVLOP","v":"WebDev","v":5,"v":1498.06,"v":84.33,"v":0.981632],"c":["v":"DEVLOP","v":"WebDev","v":6,"v":1238.35,"v":178.83,"v":0.917863],"c":["v":"DEVLOP","v":"WebDev","v":7,"v":1218.26,"v":360.59,"v":0.922225],"c":["v":"DOCOPS","v":"CmpAna","v":4,"v":745.59,"v":139.16,"v":0.795639],"c":["v":"DOCOPS","v":"CmpAna","v":5,"v":806.07,"v":35.25,"v":0.808962],"c":["v":"DOCOPS","v":"CmpAna","v":6,"v":921.2,"v":35.5,"v":0.842165],"c":["v":"DOCOPS","v":"CmpAna","v":7,"v":1031.24,"v":33.25,"v":0.887075],"c":["v":"DOCOPS","v":"OpsSupp","v":4,"v":144.29,"v":44.42,"v":1.00914],"c":["v":"DOCOPS","v":"OpsSupp","v":5,"v":218.52,"v":53.33,"v":1.14608],"c":["v":"DOCOPS","v":"OpsSupp","v":6,"v":207.19,"v":33.26,"v":1.01029],"c":["v":"DOCOPS","v":"OpsSupp","v":7,"v":214.45,"v":33,"v":0.806552],"c":["v":"DOCOPS","v":"PPT&SecPro","v":4,"v":674.52,"v":143.3,"v":0.540886],"c":["v":"DOCOPS","v":"PPT&SecPro","v":5,"v":865.97,"v":50.6,"v":0.615974],"c":["v":"DOCOPS","v":"PPT&SecPro","v":6,"v":874.73,"v":101.3,"v":0.601004],"c":["v":"DOCOPS","v":"PPT&SecPro","v":7,"v":647.69,"v":88.8,"v":0.393424],"c":["v":"DOCOPS","v":"prod","v":4,"v":398.01,"v":146.42,"v":0.677152],"c":["v":"DOCOPS","v":"prod","v":5,"v":372.54,"v":147.82,"v":0.62244],"c":["v":"DOCOPS","v":"prod","v":6,"v":388.74,"v":165.16,"v":0.68552],"c":["v":"DOCOPS","v":"prod","v":7,"v":442.38,"v":44.91,"v":0.591371],"c":["v":"DOCOPS","v":"QINT","v":4,"v":2448.71,"v":291.03,"v":0.839381],"c":["v":"DOCOPS","v":"QINT","v":5,"v":2286.09,"v":330.49,"v":0.838647],"c":["v":"DOCOPS","v":"QINT","v":6,"v":2336.49,"v":459.6,"v":0.855597],"c":["v":"DOCOPS","v":"QINT","v":7,"v":2390.9,"v":821.27,"v":0.857036],"c":["v":"DOCOPS","v":"VP&SPPro","v":4,"v":379.7,"v":114.3,"v":0.382353],"c":["v":"DOCOPS","v":"VP&SPPro","v":5,"v":538.7,"v":105.6,"v":0.362782],"c":["v":"DOCOPS","v":"VP&SPPro","v":6,"v":620.8,"v":89.4,"v":0.386819],"c":["v":"DOCOPS","v":"VP&SPPro","v":7,"v":737.8,"v":52.7,"v":0.420479],"c":["v":"MR","v":"MR","v":5,"v":0,"v":0,"v":0],"c":["v":"MR","v":"MR","v":6,"v":297,"v":207,"v":0.379518],"c":["v":"MR","v":"MR","v":7,"v":1301.76,"v":220,"v":0.932451],"c":["v":"Viewpoint","v":"CLUTCHBOD","v":4,"v":171,"v":37.5,"v":0.461283],"c":["v":"Viewpoint","v":"CLUTCHBOD","v":5,"v":273.38,"v":0,"v":0.813631],"c":["v":"Viewpoint","v":"CLUTCHBOD","v":6,"v":245.45,"v":0,"v":0.829223],"c":["v":"Viewpoint","v":"CLUTCHBOD","v":7,"v":292.31,"v":0,"v":0.86997],"c":["v":"Viewpoint","v":"DBA","v":4,"v":151.5,"v":0,"v":0.901786],"c":["v":"Viewpoint","v":"DBA","v":5,"v":143.75,"v":0,"v":0.945724],"c":["v":"Viewpoint","v":"DBA","v":6,"v":162.59,"v":3,"v":0.940852],"c":["v":"Viewpoint","v":"DBA","v":7,"v":165.25,"v":0,"v":0.898098],"c":["v":"Viewpoint","v":"VPDEV","v":4,"v":285.14,"v":0,"v":0.963311],"c":["v":"Viewpoint","v":"VPDEV","v":5,"v":452.75,"v":46.66,"v":0.97541],"c":["v":"Viewpoint","v":"VPDEV","v":6,"v":646.68,"v":13,"v":0.964444],"c":["v":"Viewpoint","v":"VPDEV","v":7,"v":611.54,"v":2.66,"v":0.953727],"c":["v":"Viewpoint","v":"VPSupp","v":4,"v":203.05,"v":103.65,"v":0.878293],"c":["v":"Viewpoint","v":"VPSupp","v":5,"v":130.68,"v":88.94,"v":0.710285],"c":["v":"Viewpoint","v":"VPSupp","v":6,"v":185.11,"v":101.01,"v":0.756131],"c":["v":"Viewpoint","v":"VPSupp","v":7,"v":172.78,"v":80.42,"v":0.688792]]);
          
      var options = 
           title: 'Utilization',
          is3D: 'true',
          width: 1000,
          height: 600
        ;

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

     var donutRangeSlider = new google.visualization.ControlWrapper(
          'controlType': 'NumberRangeFilter',
          'containerId': 'filter_div',
          'options': 
            'filterColumnLabel': 'Month'
          
        );

     var categoryPicker = new google.visualization.ControlWrapper(
        controlType: 'CategoryFilter',
        containerId: 'TeamName',
        options: 
            filterColumnLabel: 'Teams', // filter by Team name
            ui: 
                caption: 'Choose a Team',
                sortValues: true,
                allowNone: true,
                allowMultiple: true,
                allowTyping: true
            

        
     );
    
    var table = new google.visualization.ChartWrapper(
                    'chartType': 'Table',
                    'containerId': 'table_div',
                    'options': 
                        'width': '100%'
                    ,
                    'view': 'columns': [0, 1, 2, 3, 4, 5]
                ); 

     var columnChart = new google.visualization.ChartWrapper(
          'chartType': 'ColumnChart',
          'containerId': 'chart_div',
          'dataTable':google.visualization.data.group(data, [0],
                    ['column': 5, 'aggregation': google.visualization.data.sum, 'type': 'number']),
          'options': 
            'width': 600,
            'height': 400,

            'legend': 'none',
              'hAxis': 
                'title': 'Teams',
                'titleColor':'#cc0000',
                        'titleFontSize':20
              ,
              'vAxis': 
                'title': 'Utilization',
                'titleColor':'#cc0000',
                        'titleFontSize':20

              
          ,
      view:
      columns:['Group','Utilization']
      
        );
    
    
    

  /*  var pieChart = new google.visualization.ChartWrapper(
          'chartType': 'PieChart',
          'containerId': 'pie_div',
          'options': 
            'width': 500,
            'height': 300,
            'pieSliceText': 'value',
            'legend': 'right'
          
        ); */



        // Establish dependencies, declaring that 'filter' drives 'pieChart',
        // so that the pie chart will only display entries that are let through
        // given the chosen slider range.
        dashboard.bind([donutRangeSlider, categoryPicker], [table ,columnChart]);
console.log(data)
     dashboard.draw(data);
    
    
     google.visualization.events.addListener(categoryPicker, 'ready',
         function(event) 
             columnChart.setDataTable(google.visualization.data.group(

                 table.getDataTable(), [0], [
                     'column': 5,
                     'aggregation': google.visualization.data.sum,
                     'type': 'number'
                 ]
             ));

             columnChart.draw();
         );

     google.visualization.events.addListener(categoryPicker, 'statechange',

         function(event) 
             columnChart.setDataTable(google.visualization.data.group(
                 table.getDataTable(), [0], [
                     'column': 5,
                     'aggregation': google.visualization.data.sum,
                     'type': 'number'
                 ]
             ));
             columnChart.draw();
         );
    

    
      </script>


 

【讨论】:

这样做的主要缺陷是,除了其他所有内容之外,您实际上还必须绘制表格。您还需要为每次更改重新绘制柱形图三次。 1) 仪表板更新,2) 状态更改,3) 就绪事件。 另一件事是,这根本不适用于范围滑块。 Corrected version 是的,我更关注selectPicker。好吧,谢谢@HenrikAronsson。您的改进已添加到答案中。 在我制作的图表中,我觉得仪表板不是很完善,它缺乏很多可能进行更改并完全按照您的意愿进行操作。我通常用事件监听器构建仪表板,以确保我可以在我想要的时候调用任何东西。检查此版本:jsfiddle.net/heennkkee/kej15cr9/4

以上是关于谷歌柱形图仪表板的主要内容,如果未能解决你的问题,请参考以下文章

powerbi簇状条形图,如何去掉x轴字段

Keen.io 仪表板图表上的最大和最小 Y 轴值

从谷歌图表中的柱形图创建汇总表

获取柱形图的hAxis高度(谷歌图表)

Pelican商店

ELKStack可视化