3
votes

I'm having troubles with Google Charts Scatterplot when plotting two series and a ChartRangeFilter attached to it.

My Datatable looks like that:

var paretoScatterData = new google.visualization.DataTable();
paretoScatterData.addColumn('number', "Nodecollisions");
paretoScatterData.addColumn('number', "Linkcollisions");
paretoScatterData.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
paretoScatterData.addColumn( {'type': 'string', 'role': 'style'} );
paretoScatterData.addColumn('number', 'Paretofront');
paretoScatterData.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
paretoScatterData.addColumn( {'type': 'string', 'role': 'style'} );

I added following data to the table:

paretoScatterData.addRows(
[[0,1,"asd","fill-color:green", null, null, null],
[0,2,"asd","fill-color:green", null, null, null],
[0,3,"asd","fill-color:green", null, null, null],
[0,4,"asd","fill-color:green", null, null, null],
[0,5,"asd","fill-color:green", null, null, null],
[5,null,null,null, 0, "asd", "fill-color: red"],
[4,null,null,null, 0, "asd", "fill-color: red"],
[3,null,null,null, 0, "asd", "fill-color: red"],
[2,null,null,null, 0, "asd", "fill-color: red"],
[1,null,null,null, 0, "asd", "fill-color: red"]]) ;

The scatter plot renders perfectly, drawing "standard points" in green and "pareto points" in red. I have attached a ChartRangeFilter to the Scatterplot, everything in a dashboard ofc. If i filter for filterColumnIndex: 0 the Scatterplot still renders perfectly, showing both, the "normal points" and the "pareto points". If i filter for filterColumnIndex: 1 the "pareto points" disappear.

Both outputs for filterColumnIndex: 0 and filterColumnIndex: 1

What can i do to filter the vertical axis with a ChartRangeFilter and still showing my "pareto points" and the "normal points"?

Here's a jsfiddle for this.

Hope anybody can help me with that, i would be really grateful :).

P.S. this are of course fictional data, so don't care bout the values for the pareto points..

1

1 Answers

1
votes

the range filter affects the entire table, not just a series.
since the values for the "pareto points" in column 1 are null,
they will never fall into the filter's range.

as such, you would need to draw the chart and control independently,
then re-draw the chart when the control changes.

use getFilteredRows to build a DataView with the rows to be displayed.

see following example...

google.charts.load('current', {
  callback: function () {
    var paretoScatterData = new google.visualization.DataTable();
    paretoScatterData.addColumn('number', "Nodecollisions");
    paretoScatterData.addColumn('number', "Linkcollisions");
    paretoScatterData.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
    paretoScatterData.addColumn( {'type': 'string', 'role': 'style'} );
    paretoScatterData.addColumn('number', 'Paretofront');
    paretoScatterData.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
    paretoScatterData.addColumn( {'type': 'string', 'role': 'style'} );

    paretoScatterData.addRows(
      [[0,1,"asd","fill-color:green", null, null, null],
      [0,2,"asd","fill-color:green", null, null, null],
      [0,3,"asd","fill-color:green", null, null, null],
      [0,4,"asd","fill-color:green", null, null, null],
      [0,5,"asd","fill-color:green", null, null, null],
      [5,null,null,null, 0, "asd", "fill-color: red"],
      [4,null,null,null, 0, "asd", "fill-color: red"],
      [3,null,null,null, 0, "asd", "fill-color: red"],
      [2,null,null,null, 0, "asd", "fill-color: red"],
      [1,null,null,null, 0, "asd", "fill-color: red"]]
    );

    var paretoScatterOptions = {
      height: 270,
      dataOpacity: 0.4,
      tooltip: {
        textStyle: {},
        isHtml: true,
        trigger: 'both'
      },
      series: {
        1: { dataOpacity: 0.8, lineWidth: 4, color: '#a6bddb', targetAxisIndex: 1},
      },
      colors:['blue','green', 'red'],
      vAxis: {
        title: "Nodecollisions",
      },
      hAxis: {
        title: "Linkcollisions",
      },
    };

    var paretoScatterChart = new google.visualization.ChartWrapper({
      chartType: 'ScatterChart',
      containerId: 'paretoScatter',
      dataTable: paretoScatterData,
      options: paretoScatterOptions
    });
    paretoScatterChart.draw();

    var metricsControl2 = new google.visualization.ControlWrapper({
      controlType: 'ChartRangeFilter',
      containerId: 'paretoMetricControl2',
      dataTable: paretoScatterData,
      options: {
        filterColumnIndex: 1
      }
    });
    google.visualization.events.addListener(metricsControl2, 'statechange', function () {
      var paretoScatterView = new google.visualization.DataView(paretoScatterData);
      var rowsFound = paretoScatterData.getFilteredRows([{
        column: 1,
        test: function (value, row, column, table) {
          return ((table.getValue(row, column) === null) ||
                  ((table.getValue(row, column) >= metricsControl2.getState().range.start) &&
                   (table.getValue(row, column) <= metricsControl2.getState().range.end)));
        }
      }]);
      paretoScatterView.setRows(rowsFound);
      paretoScatterChart.setDataTable(paretoScatterView);
      paretoScatterChart.draw();
    });
    metricsControl2.draw();
  },
  packages:['corechart', 'scatter', 'controls']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="paretoDash">
  <div id="paretoMetricControl1" style="width:50%; float: left"></div>
  <div id="paretoMetricControl2" style="width:50%; float: left"></div>
  <div style="clear: both"></div>
  <div id="paretoScatter" class="chartContainer">
</div>