1

I'm trying to draw a barchart with chart range filter with the script and code bellow, but i'm getting 2 errors 1-One or more participants failed to draw()× 2-The filter cannot operate on a column of type string. Column type must be one of: number, date, datetime or timeofday. Column role must be domain, and correlate to a continuous axis

for the second error, the data is clear as you see in the code below

<div id="dashboard" class="container-fluid" style="height:100%">

        <div id="chart_div" style="height:99%"></div>

        <div id="filter-range" style="height:1%"></div>

</div>
<script type="text/javascript">
       google.charts.load('current', { packages: ['corechart', 'controls'] });
       google.charts.setOnLoadCallback(drawChart);

       function drawChart() {
           var data = google.visualization.arrayToDataTable([
               ['Name', 'Donuts eaten', 'Donuts eaten'],
               ['Michael', 5, 6],
               ['Elisa', 7, 6],
               ['Robert', 3, 7],
               ['John', 2, 8],
               ['Jessica', 6, 9],
               ['Aaron', 1, 20],
               ['Margareth', 8, 8]
           ]);

           var rangeFilter = new google.visualization.ControlWrapper({
               controlType: 'ChartRangeFilter',
               containerId: 'filter-range',
               options: {
                   filterColumnIndex: 0,
                   ui: {
                       chartType: 'ColumnChart',
                       chartOptions: {
                           height: 40,
                           colors: ['#ff7900', '#50be87'],
                           chartArea: {
                               width: '100%',
                               height: '100%',
                               top: 0,
                               left: 0,
                               right: 0,
                               bottom: 0
                           }
                       }
                   }
               }
           });

           var chart = new google.visualization.ChartWrapper({
               chartType: 'ColumnChart',
               containerId: 'chart_div',
               options: {
                   width: '100%',
                   height: 450,
                   legend: {
                       alignment: 'end',
                       position: 'top'
                   },
                   animation: {
                       duration: 500,
                       easing: 'in',
                       startup: true
                   },
                   chartArea: {
                       top: 36,
                       left: 36,
                       right: 18,
                       bottom: 36
                   },
                   isStacked: true,
                   bar: { groupWidth: '95%' },
                   colors: ['#ff7900', '#50be87']
               }
           });

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

           dashboard.bind(rangeFilter, chart);
           dashboard.draw(data);
       }
   </script>```

1 Answers1

0

the main issue is from error #2.
the chart range filter will not operate on a string column, in this case, the 'Name' column.
because the purpose is to filter on a range of values; number, date, etc...

filterColumnIndex: 0  // <-- index for 'Name' column

as a work around, we can change the first column to be numeric.
then use object notation to set the numeric value (v:), and the formatted value (f:).

{v: 1, f: 'Michael'}

this will correct the error and the tooltip shown when hovering the column.
Michael will appear, instead of 1.

in order to get the names to appear under the columns,
we need to add the ticks option to the hAxis,
using the same object notation.

var ticks = [
  {v: 1, f: 'Michael'},
  ...
];

then reference in the options...

hAxis: {
  ticks: ticks
}

next, ColumnChart is not a valid chartType option for the range filter.
valid types include: 'AreaChart', 'LineChart', 'ComboChart' or 'ScatterChart'
as such, we can use 'ComboChart', then set seriesType to 'bars'

        chartType: 'ComboChart',
        chartOptions: {
          seriesType: 'bars',
          ...

as for the animation option, when using option: startup: true
on a dashboard, there is a bug that causes an error to be thrown.
a workaround for this involves drawing the chart with initial column values of zero, then on the 'ready' event,
add the real data and draw again. this will cause the chart to animate.

finally, since we have hard-coded the ticks option for our labels to appear.
they will prevent the range filter from properly filtering the chart.
so we have to listen for the 'statechange' event, and reset the ticks that should be shown from the newly filtered data.

see following working snippet...

google.charts.load('current', {
  packages: ['corechart', 'controls']
}).then(drawChart);

function drawChart() {
  // create data
  var dataRows = [
    [{v: 1, f: 'Michael'}, 5, 6],
    [{v: 2, f: 'Elisa'}, 7, 6],
    [{v: 3, f: 'Robert'}, 3, 7],
    [{v: 4, f: 'John'}, 2, 8],
    [{v: 5, f: 'Jessica'}, 6, 9],
    [{v: 6, f: 'Aaron'}, 1, 20],
    [{v: 7, f: 'Margareth'}, 8, 8]
  ];
  
  // create x-axis ticks from dataRows
  var ticks = dataRows.map(function (row) {
    return row[0];
  });
  
  // create rows with zero values for initial draw
  var initialData = dataRows.map(function (row) {
    return [row[0], 0, 0];  // initial value does not have to be zero, but needs to be different from real value in order to animate
  });
  
  // create data table with initial data
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'Name');
  data.addColumn('number', 'Donuts eaten');
  data.addColumn('number', 'Donuts eaten');
  data.addRows(initialData);

  // range filter
  var rangeFilter = new google.visualization.ControlWrapper({
    controlType: 'ChartRangeFilter',
    containerId: 'filter-range',
    options: {
      filterColumnIndex: 0,
      ui: {
        chartType: 'ComboChart',
        chartOptions: {
          seriesType: 'bars',
          height: 40,
          colors: ['#ff7900', '#50be87'],
          chartArea: {
            width: '100%',
            height: '100%',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0
          }
        }
      }
    }
  });

  // chart
  var chart = new google.visualization.ChartWrapper({
    chartType: 'ColumnChart',
    containerId: 'chart_div',
    options: {
      width: '100%',
      height: 450,
      legend: {
        alignment: 'end',
        position: 'top'
      },
      animation: {
        duration: 500,
        easing: 'in',
        //startup: true  // <-- bug prevents from working
      },
      chartArea: {
        top: 36,
        left: 36,
        right: 18,
        bottom: 36
      },
      isStacked: true,
      bar: {
        groupWidth: '95%'
      },
      colors: ['#ff7900', '#50be87'],
      hAxis: {
        ticks: ticks
      }
    }
  });

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

  // dashboard ready event (1 time only for startup animation)
  google.visualization.events.addOneTimeListener(dashboard, 'ready', function () {
    // add real data, re-draw to initiate animation
    data.removeRows(0, data.getNumberOfRows());
    data.addRows(dataRows);
    dashboard.draw(data);
  });

  // filter state change event (reset ticks from filtered data)
  google.visualization.events.addListener(rangeFilter, 'statechange', function () {
    // get filtered data table from chart
    var filterData = chart.getDataTable();
    
    // re-build ticks from filtered data
    ticks = [];
    for (var i = 0; i < filterData.getNumberOfRows(); i++) {
      ticks.push({
        v: filterData.getValue(i, 0),
        f: filterData.getFormattedValue(i, 0)
      });
    }
    
    // update chart with new ticks
    chart.setOption('hAxis.ticks', ticks);
    
    // re-draw chart
    chart.draw();
  });

  // bind, draw
  dashboard.bind(rangeFilter, chart);
  dashboard.draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard" class="container-fluid" style="height:100%">
  <div id="chart_div" style="height:99%"></div>
  <div id="filter-range" style="height:1%"></div>
</div>
WhiteHat
  • 59,912
  • 7
  • 51
  • 133