Multiple charts in one dashboard with different filtered DataView for each chart

470 views
Skip to first unread message

Ramakrishnan Srinivasan

unread,
Jul 24, 2022, 10:40:20 PM7/24/22
to Google Visualization API
Hi,
 I have given my sample data. My steps

 - Create one dashboard with two charts and two Category Filters
 - For each chart use a different filtered DataView
     - this data comes from SQL query where first column gives what kind of chart it is
 - Use a dummy table and event listeners to apply different filtered views to each chart


 I am facing following problems (my Chrome version = 103.0.5060.134 (Official Build) (64-bit))
 - On load the browser shows the error "Cannot read properties of null (reading '$')" - screen shot attached
 - The category filters are working but when I click on bar, the whole chart freezes
 - in Chrome debug console I see error
 jsapi_compiled_default_module.js:493 Uncaught TypeError: f.getTableRowIndex is not a function
    at gvjs_ho.<anonymous> (jsapi_compiled_default_module.js:493:195)
    at Array.map (<anonymous>)
    at gvjs_v (jsapi_compiled_default_module.js:63:315)
    at gvjs_.Hqa (jsapi_compiled_default_module.js:493:117)
    at gvjs_H.<anonymous> (jsapi_compiled_default_module.js:166:147)
    at gvjs_ni (jsapi_compiled_default_module.js:165:214)
    at gvjs_.dispatchEvent (jsapi_compiled_default_module.js:163:405)
    at gvjs_I (jsapi_compiled_default_module.js:165:635)
    at jsapi_compiled_default_module.js:465:272
    at gvjs_H.<anonymous> (jsapi_compiled_default_module.js:166:147)



At the top of debug console I see
loader.js:148  Attempting to load version '51' of Google Charts, but the previously loaded 'current' will be used instead.


Can you please help me out here to resolve the above issues? 

My requirement is different charts with filtered data from same datas ource but each charts should have its own DataView.

Thank you
with warm regards
ramki

<html>
  <head>
    <!--Load the AJAX API CHROME VERSION Version 103.0.5060.134 (Official Build) (64-bit)-->
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">

      // Load the Visualization API and the controls package.
      google.charts.load('current', {'packages':['corechart', 'controls']});

      // Set a callback to run when the Google Visualization API is loaded.
      google.charts.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() {

        var sampleData = [[{label:'Chart Index', id:'chartindex', type: 'string'}, {label:'Product', id:'jirapkey', type: 'string'}, {label:'Customer', id:'customer', type: 'string'}, {label:'Text Col1', id:'txtcol1', type: 'string'}, {label:'Num1', id:'n1', type: 'number'}, {label:'Num2', id:'n2', type: 'number'}, {label:'Num3', id:'n3', type: 'number'}], ['createdresolved_by_origin_chart9', 'All', 'All', 'Customer', 4475, 4058, 0], ['createdresolved_by_origin_chart9', 'All', 'All', 'OPS', 3211, 3015, 0], ['createdresolved_by_origin_chart9', 'All', 'All', 'R&D', 16824, 15597, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer B', 'Customer', 404, 378, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer B', 'OPS', 704, 677, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer B', 'R&D', 130, 107, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer C', 'Customer', 240, 228, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer C', 'OPS', 107, 102, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer C', 'R&D', 221, 204, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer A', 'Customer', 631, 560, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer A', 'OPS', 393, 353, 0], ['createdresolved_by_origin_chart9', 'All', 'Customer A', 'R&D', 975, 896, 0], ['createdresolved_by_origin_chart9', 'Product A', 'All', 'Customer', 902, 774, 0], ['createdresolved_by_origin_chart9', 'Product A', 'All', 'OPS', 728, 663, 0], ['createdresolved_by_origin_chart9', 'Product A', 'All', 'R&D', 5721, 5096, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer B', 'Customer', 37, 32, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer B', 'OPS', 106, 97, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer B', 'R&D', 47, 32, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer C', 'Customer', 23, 21, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer C', 'OPS', 16, 16, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer C', 'R&D', 12, 8, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer A', 'Customer', 78, 73, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer A', 'OPS', 64, 61, 0], ['createdresolved_by_origin_chart9', 'Product A', 'Customer A', 'R&D', 44, 36, 0], ['createdresolved_by_origin_chart9', 'Product B', 'All', 'Customer', 1351, 1189, 0], ['createdresolved_by_origin_chart9', 'Product B', 'All', 'OPS', 751, 685, 0], ['createdresolved_by_origin_chart9', 'Product B', 'All', 'R&D', 2742, 2423, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer B', 'Customer', 93, 86, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer B', 'OPS', 173, 164, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer B', 'R&D', 23, 19, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer C', 'Customer', 70, 64, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer C', 'OPS', 29, 26, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer C', 'R&D', 22, 19, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer A', 'Customer', 256, 222, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer A', 'OPS', 54, 48, 0], ['createdresolved_by_origin_chart9', 'Product B', 'Customer A', 'R&D', 580, 521, 0], ['createdresolved_by_origin_chart9', 'Product C', 'All', 'Customer', 1235, 1169, 0], ['createdresolved_by_origin_chart9', 'Product C', 'All', 'OPS', 944, 913, 0], ['createdresolved_by_origin_chart9', 'Product C', 'All', 'R&D', 7345, 7156, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer B', 'Customer', 86, 83, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer B', 'OPS', 82, 82, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer B', 'R&D', 35, 32, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer C', 'Customer', 133, 129, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer C', 'OPS', 49, 47, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer C', 'R&D', 151, 147, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer A', 'Customer', 155, 139, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer A', 'OPS', 165, 144, 0], ['createdresolved_by_origin_chart9', 'Product C', 'Customer A', 'R&D', 332, 321, 0], ['by_status_chart10', 'Product B', 'Customer C', 'Closed', 36, 0, 0], ['by_status_chart10', 'Product A', 'Customer B', 'Closed', 74, 0, 0], ['by_status_chart10', 'Product B', 'Customer B', 'Closed', 177, 0, 0], ['by_status_chart10', 'Product B', 'All', 'Closed', 2013, 0, 0], ['by_status_chart10', 'Product A', 'Customer C', 'Closed', 15, 0, 0], ['by_status_chart10', 'Product A', 'Customer A', 'Closed', 67, 0, 0], ['by_status_chart10', 'All', 'Customer C', 'Closed', 347, 0, 0], ['by_status_chart10', 'All', 'Customer A', 'Closed', 1092, 0, 0], ['by_status_chart10', 'Product C', 'Customer A', 'Closed', 551, 0, 0], ['by_status_chart10', 'Product C', 'Customer C', 'Closed', 281, 0, 0], ['by_status_chart10', 'Product C', 'Customer B', 'Closed', 182, 0, 0], ['by_status_chart10', 'Product C', 'All', 'Closed', 8582, 0, 0], ['by_status_chart10', 'All', 'All', 'Closed', 15315, 0, 0], ['by_status_chart10', 'All', 'Customer B', 'Closed', 589, 0, 0], ['by_status_chart10', 'Product A', 'All', 'Closed', 3715, 0, 0], ['by_status_chart10', 'Product B', 'Customer A', 'Closed', 403, 0, 0], ['by_status_chart10', 'All', 'All', 'Resolved', 7354, 0, 0], ['by_status_chart10', 'All', 'Customer B', 'Resolved', 573, 0, 0], ['by_status_chart10', 'All', 'Customer C', 'Resolved', 187, 0, 0], ['by_status_chart10', 'All', 'Customer A', 'Resolved', 717, 0, 0], ['by_status_chart10', 'Product A', 'All', 'Resolved', 2817, 0, 0], ['by_status_chart10', 'Product A', 'Customer B', 'Resolved', 87, 0, 0], ['by_status_chart10', 'Product A', 'Customer C', 'Resolved', 30, 0, 0], ['by_status_chart10', 'Product A', 'Customer A', 'Resolved', 103, 0, 0], ['by_status_chart10', 'Product B', 'All', 'Resolved', 2284, 0, 0], ['by_status_chart10', 'Product B', 'Customer B', 'Resolved', 92, 0, 0], ['by_status_chart10', 'Product B', 'Customer C', 'Resolved', 73, 0, 0], ['by_status_chart10', 'Product B', 'Customer A', 'Resolved', 388, 0, 0], ['by_status_chart10', 'Product C', 'All', 'Resolved', 656, 0, 0], ['by_status_chart10', 'Product C', 'Customer B', 'Resolved', 15, 0, 0], ['by_status_chart10', 'Product C', 'Customer C', 'Resolved', 42, 0, 0], ['by_status_chart10', 'Product C', 'Customer A', 'Resolved', 53, 0, 0], ['by_status_chart10', 'Product C', 'All', 'Open', 275, 0, 0], ['by_status_chart10', 'Product C', 'Customer B', 'Open', 6, 0, 0], ['by_status_chart10', 'Product C', 'Customer C', 'Open', 9, 0, 0], ['by_status_chart10', 'Product C', 'Customer A', 'Open', 45, 0, 0], ['by_status_chart10', 'All', 'Customer A', 'Open', 143, 0, 0], ['by_status_chart10', 'All', 'Customer C', 'Open', 21, 0, 0], ['by_status_chart10', 'Product A', 'Customer A', 'Open', 7, 0, 0], ['by_status_chart10', 'Product A', 'Customer C', 'Open', 2, 0, 0], ['by_status_chart10', 'Product B', 'All', 'Open', 367, 0, 0], ['by_status_chart10', 'All', 'All', 'Open', 1449, 0, 0], ['by_status_chart10', 'Product B', 'Customer B', 'Open', 15, 0, 0], ['by_status_chart10', 'Product A', 'Customer B', 'Open', 18, 0, 0], ['by_status_chart10', 'Product B', 'Customer C', 'Open', 5, 0, 0], ['by_status_chart10', 'Product A', 'All', 'Open', 632, 0, 0], ['by_status_chart10', 'Product B', 'Customer A', 'Open', 65, 0, 0], ['by_status_chart10', 'All', 'Customer B', 'Open', 60, 0, 0], ['by_status_chart10', 'Product A', 'All', 'Need Info', 187, 0, 0], ['by_status_chart10', 'Product B', 'Customer A', 'Need Info', 34, 0, 0], ['by_status_chart10', 'All', 'All', 'Need Info', 392, 0, 0], ['by_status_chart10', 'All', 'Customer B', 'Need Info', 16, 0, 0], ['by_status_chart10', 'Product B', 'All', 'Need Info', 180, 0, 0], ['by_status_chart10', 'Product A', 'Customer B', 'Need Info', 11, 0, 0], ['by_status_chart10', 'Product C', 'All', 'Need Info', 11, 0, 0], ['by_status_chart10', 'Product A', 'Customer A', 'Need Info', 9, 0, 0], ['by_status_chart10', 'Product C', 'Customer C', 'Need Info', 1, 0, 0], ['by_status_chart10', 'Product A', 'Customer C', 'Need Info', 4, 0, 0], ['by_status_chart10', 'Product C', 'Customer A', 'Need Info', 3, 0, 0], ['by_status_chart10', 'All', 'Customer A', 'Need Info', 47, 0, 0], ['by_status_chart10', 'Product B', 'Customer B', 'Need Info', 5, 0, 0], ['by_status_chart10', 'All', 'Customer C', 'Need Info', 13, 0, 0], ['by_status_chart10', 'Product B', 'Customer C', 'Need Info', 7, 0, 0]];

        // Create our data table.
        var data = google.visualization.arrayToDataTable(sampleData);

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

        var productSelect = new google.visualization.ControlWrapper({
              'controlType': 'CategoryFilter',
              'containerId': 'product_filter_div',
              'options': {
                  'filterColumnLabel': 'Product',
                  'ui' : {
                      'caption' : 'Choose Product',
                      'label' : 'Choose Product',
                      'labelStacking' : 'vertical',
                      'allowMultiple' : false,
                      'allowNone' : false,
                      'allowTyping' : false, //instead of input box, this make it as button
                  }
              },
              state: {'selectedValues': ['All']}
          });

          var customerSelect = new google.visualization.ControlWrapper({
              'controlType': 'CategoryFilter',
              'containerId': 'customer_filter_div',
              'options': {
                  'filterColumnLabel': 'Customer',
                  'ui' : {
                      'caption' : 'Choose Customer',
                      'label' : 'Choose Customer',
                      'labelStacking' : 'vertical',
                      'allowMultiple' : false,
                      'allowNone' : false,
                      'allowTyping' : false, //instead of input box, this make it as button
                  }
              },
              state: {'selectedValues': ['All']}
          });


          var dummy = new google.visualization.ChartWrapper({
                chartType: 'Table',
                containerId: 'DummyTable',
                options: {
                    sort: 'disable' // disable sorting on the dummy table to reduce the number of event handlers spawned
                },
                view: {
                   rows: [] // remove all rows from the view so it doesn't waste time rendering them in HTML
                }
            });

            // Create a column chart, passing some options
            var createdResolved_byOrigin_ColumnChart = new google.visualization.ChartWrapper({
                chartType: 'ColumnChart',
                containerId: 'createdResolved_byOrigin_chart_div',
                options: {
                    'width': '90%',
                    'height': '80%',
                    'chartArea': {
                        width: '80%',
                        height: '60%',
                    },
                    legend: {'position': 'bottom', 'textStyle': {'color': 'blue', 'fontSize': 14}},
                    colors: ['#41a1d0', '#87b77e'],
                }

            });

            // Create a pie chart, passing some options
            var bugsCreated_byStatus_pieChart = new google.visualization.ChartWrapper({
                chartType: 'PieChart',
                containerId: 'bugsCreated_byStatus_chart_div',
                options: {
                    'width': '95%',
                    'height': '95%',
                    'chartArea': {
                        width: '80%',
                        height: '75%',
                    },
                    pieSliceText: 'value',
                    legend: {'position':'bottom','alignment':'left'},
                }
            });


        // 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([productSelect, customerSelect], [dummy, createdResolved_byOrigin_ColumnChart, bugsCreated_byStatus_pieChart]);

        // Draw the dashboard.
        dashboard.draw(data);


        google.visualization.events.addListener(productSelect, 'ready', reDrawChartsFunction);
        google.visualization.events.addListener(productSelect, 'statechange', reDrawChartsFunction);
        google.visualization.events.addListener(customerSelect, 'ready', reDrawChartsFunction);
        google.visualization.events.addListener(customerSelect, 'statechange', reDrawChartsFunction);

        function reDrawChartsFunction() {
                  var productSelected = productSelect.getState();
                  var customerSelected = customerSelect.getState();

                  var dataViewFor_createdResolved_byOrigin_ColumnChart = new google.visualization.DataView(dummy.getDataTable());

                  // this line from https://developers.google.com/chart/interactive/docs/reference#DataTable_getFilteredRows
                  dataViewFor_createdResolved_byOrigin_ColumnChart
                   .setRows(dataViewFor_createdResolved_byOrigin_ColumnChart
                             .getFilteredRows([{column: 0, value: 'createdresolved_by_origin_chart9'}
                             ])
                    );
                 

                  // group the data of the filtered table and set the result in the pie chart.
                  createdResolved_byOrigin_ColumnChart.setDataTable( google.visualization.data.group(
                      // get the filtered results
                      dataViewFor_createdResolved_byOrigin_ColumnChart,
                      [3],
                      [{'column': 4, 'aggregation': google.visualization.data.sum, 'type': 'number'}
                      ,{'column': 5, 'aggregation': google.visualization.data.sum, 'type': 'number'}],
                  ));

                  // setView is to decide which column indexes or rows considered for charting
                  // here dummyTable view is used so 0 is pkey, 1 is created_count and 2 is resolved_count
                  // https://stackoverflow.com/questions/46219896/google-visualization-dashboard-with-filter-and-dataview

                  createdResolved_byOrigin_ColumnChart.setView({'columns': [0, 1, 2]})
                 
                  // redraw the pie chart to reflect changes
                  createdResolved_byOrigin_ColumnChart.draw();

                  var dataViewFor_bugsCreated_byStatus_pieChart = new google.visualization.DataView(dummy.getDataTable());
                 
                  dataViewFor_bugsCreated_byStatus_pieChart
                   .setRows(dataViewFor_bugsCreated_byStatus_pieChart
                             .getFilteredRows([{column: 0, value: 'by_status_chart10'}
                             ])
                    );

                  bugsCreated_byStatus_pieChart.setDataTable( google.visualization.data.group(
                      // get the filtered results
                      dataViewFor_bugsCreated_byStatus_pieChart,
                      [3],
                      [{'column': 4, 'aggregation': google.visualization.data.sum, 'type': 'number'}]
                  ));

                  //index from filtered dummy table
                  bugsCreated_byStatus_pieChart.setView({'columns': [0, 1]})
                 
                  // redraw the pie chart to reflect changes
                  bugsCreated_byStatus_pieChart.draw();
          } //END function reDrawChartsFunction()

      } //END function drawDashboard()
    </script>
  </head>

  <body>
    <!--Div that will hold the dashboard-->
    <div id="dashboard1_div">
        <div id="product_filter_div" style="width: 145px; height: 50px; display: inline-block;"></div>
        <div id="customer_filter_div" style="width: 145px; height: 50px; display: inline-block;"></div>
        <div id="DummyTable" style="display: none;" ></div>
        <div id="createdResolved_byOrigin_chart_div" style="width: 600px; height: 400px;"></div>
        <div id="bugsCreated_byStatus_chart_div" style="width: 450px; height: 350px;"></div>
    </div>
  </body>
</html>



Reply all
Reply to author
Forward
0 new messages