How Can I Tell If I Clicked the Background of a Google Graphs ScatterChart?

Viewed 41

I have a google scatterchart that I want to change the color of a point if I click on it, and to reset the points to their original color if I don't click on any point (e.g. if I click on the background).

From what I see on the api, clicking the background should fire a select event that returns a null selection. However, my select handler only ever gets called if I click on a point, not if I click on the graph's background. (I can tell by looking at the console output --- it should print "A" if my handler fires --- as well as the graph.) Clicking anywhere other than on a point doesn't fire the handler at all.

How can I get if I'm clicking on a non-point part of the graph or not?

function makeGraph(row_data, x_axis_title, y_axis_title) {

    var data = new google.visualization.DataTable();

    data.addColumn('number', x_axis_title);
    data.addColumn('number', y_axis_title); // Required to be a number
    data.addColumn( {'type': 'string', 'role': 'style'} ); // Defines point style

    let pointStyle = 'point { size: 12; shape-type: circle; fill-color: #FFFFFF; color: #CCCCCC }';
    let focusedPointStyle = 'point { size: 14; shape-type: circle; fill-color: #B5D989; color: #CCCCCC }';

    for (let [index, row_data_i] of Object.entries(row_data)) {
        row_data_i[2] = pointStyle;
    }
      
    data.addRows(row_data);

    var options = {
        chart: { title: "myGraph" }
    };

    var chart = new google.visualization.ScatterChart(document.getElementById(div_id_for_graph));


    // SELECT HANDLER

    function selectHandler() {

        console.log("A");

        let selected_graph_item = chart.getSelection()[0];
        
        // Need to reset all points to standard formatting
        for (let i = 0; i < row_data.length; i++)
            data.setCell(i, 3, pointStyle);

        if (selected_graph_item === undefined) { // Didn't click on a point, but on blank graph space
            pass;
        }
        
        else {   
            data.setCell(selected_graph_item["row"], 3, focusedPointStyle);
        }
            
        chart.draw(data, options);  // Redraw so point coloring gets updated
    }

    // Listen for the 'select' event, and call my function selectHandler() when
    // the user selects something on the chart.

    google.visualization.events.addListener(chart, 'select', selectHandler);

    // DRAW CHART

    chart.draw(data, options);
}
1 Answers

the 'select' event is only fired when a point is selected, or un-selected.

to know if the chart background was clicked, use the 'click' event.

the click event will send properties to the event handler specifying the chart element that was clicked.
in this case, we need to ignore click events on points, as these will be handled in the select handler.

we also need to use the 'ready' event, to know when the chart has been re-drawn.
here, we save and set the chart selection, otherwise, a point cannot be un-selected.

see following working snippet...

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

function makeGraph(row_data, x_axis_title, y_axis_title) {
  var data = new google.visualization.DataTable();

  data.addColumn('number', 'x_axis_title');
  data.addColumn('number', 'y_axis_title'); // Required to be a number
  data.addColumn( {'type': 'string', 'role': 'style'} ); // Defines point style

  let pointStyle = 'point { size: 12; shape-type: circle; fill-color: #FFFFFF; color: #CCCCCC }';
  let focusedPointStyle = 'point { size: 14; shape-type: circle; fill-color: #B5D989; color: #CCCCCC }';

  data.addRows([
    [0, 0, pointStyle],
    [1, 1, pointStyle],
    [2, 2, pointStyle]
  ]);

  var options = {
    backgroundColor: '#002855',
    title: "myGraph"
  };

  var chart = new google.visualization.ScatterChart(document.getElementById('chart'));

  var selection = [];


  // READY HANDLER
  function readyHandler() {
    if (selection.length > 0) {
      chart.setSelection(selection);
    }
  }

  // SELECT HANDLER
  function selectHandler() {
    // reset all points to standard formatting
    for (let i = 0; i < data.getNumberOfRows(); i++) {
      data.setCell(i, 2, pointStyle);
    }

    selection = chart.getSelection();
    if (selection.length > 0) {
      data.setCell(selection[0].row, 2, focusedPointStyle);
    }

    chart.draw(data, options);  // Redraw so point coloring gets updated
  }

  // CLICK HANDLER
  function clickHandler(sender) {
    if (sender.targetID.indexOf('point') === -1) {
      // reset all points to standard formatting
      for (let i = 0; i < data.getNumberOfRows(); i++) {
        data.setCell(i, 2, pointStyle);
      }
      selection = [];
      chart.draw(data, options);  // Redraw so point coloring gets updated
    }
  }

  google.visualization.events.addListener(chart, 'ready', readyHandler);
  google.visualization.events.addListener(chart, 'click', clickHandler);
  google.visualization.events.addListener(chart, 'select', selectHandler);

  chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

Related