Google 柱形图仪表板

Google column chart dashboard

我有这个 google 仪表板柱形图:

我的问题是如何对团队进行分组。例如,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/

您可以通过使用数据表进行分组来实现这一点。将以下侦听器添加到您的代码中,并添加 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

创建

完整片段:

    <!--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>