Rude Dawg
Rude Dawg

Reputation: 88

Google Chart: how to set initial selection with listener for interactive

I have some code I am trying to manipulate into my environment and can't get this last piece. I want to have the chart draw with an initial value selected to begin with BUT I also want to leave the listener for user selected values. I tried using an initialization variable to flag first load and subsequent clicks but that didn't seem to work.

Any assistance is greatly appreciated.

Date.prototype.getWeekNumber = function(){
    var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
    var dayNum = d.getUTCDay() || 7;
    d.setUTCDate(d.getUTCDate() + 4 - dayNum);
    var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
    return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};

function(response) {

        var i;

        google.charts.load("current", {packages:["calendar"]});
        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            var dataTable = new google.visualization.DataTable();
            dataTable.addColumn({ type: 'date', id: 'Date' });
            dataTable.addColumn({ type: 'number', id: 'Changes' });

            for(var i=0; i < response.d.Rows.length; i++){
                var row = [new Date(response.d.Rows[i][0]),response.d.Rows[i][1]];
                dataTable.addRow(row);
            }

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

            var options = {
                title: 'Total Alerts Triggered By Day',
                calendar: { cellSize: 25 },
                colorAxis: {colors:['#86ce76','#d61007']},
            };

            <!--Event listener starting code-->
            function selectHandler() {
                <!-- Do Some Code -->
            }

            google.visualization.events.addListener(chart, 'select', selectHandler);
            <!--End event listener-->

            <!--My Test-->
            if !(response){

            var weekNumber = (new Date()).getWeekNumber();
            var dayOfWeek = 0; <!--(new Date()).getDay();-->
            chart.setSelection([{'row':dayOfWeek,'column':weekNumber}]);
        }

        chart.draw(dataTable, options);

So the Listener works but the initial value that i would like (select the current date in the chart) does not work.

Upvotes: 2

Views: 1609

Answers (2)

jfaldmo
jfaldmo

Reputation: 26

Rude Dawg, I am trying to do the same thing and ironically enough for the same code you provided on github. I believe I have it working now. Here is the code I am using to do it. Hopefully you can match this code snippet up with your code


google.visualization.events.addOneTimeListener(chart, 'ready', function () {
    selectHandler([{date: (new Date).getTime()}]);
});         


<!--Event listener starting code-->
function selectHandler(initialDate) {
    var selectedItem;
    var selection = initialDate || chart.getSelection();
    if (initialDate) {
      selectedItem = {"row":0};
    } 
    else if (selection.length > 0) {
      console.log(new Date(selection[0].date));
      selectedItem = selection[0];
    }

    if (selectedItem) {

The key is to just pass which row you want to initialize the other graphs with.

Upvotes: 1

WhiteHat
WhiteHat

Reputation: 61230

chart method setSelection does not work properly on the calendar chart, see issue #: 2614

if you use setSelection, it will only accept a row index.

[{"row":0,"column":null}]

not a reference to a date, as seen when a date is selected by the user.

[{"date":1530748800000}]

the problem here, it will get stuck, and there is no way to remove the initial selection.
when a date is actually selected by the user, getSelection will then return two selections,
the initial value set using setSelection and the value selected by the user.

[{"row":0,"column":null},{"date":1543536000000,"row":3}]

the row index is included in the selection, if the date is present in the data table.

see following working snippet,
an initial selection is set on the chart's 'ready' event.
select a date manually, to see the selection and the "stuck" value.

note: when an initial value has been set, the 'select' event will fire on the first 'mouseover'.

google.charts.load('current', {
  packages:['calendar']
}).then(function () {

  var response = {d: {Rows: [
    ['11/27/2018', 5],
    ['11/28/2018', 10],
    ['11/29/2018', 15],
    ['11/30/2018', 20]
  ]}};

  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({type: 'date', id: 'Date'});
  dataTable.addColumn({type: 'number', id: 'Changes'});

  for (var i = 0; i < response.d.Rows.length; i++){
    var row = [new Date(response.d.Rows[i][0]), response.d.Rows[i][1]];
    dataTable.addRow(row);
  }

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

  var options = {
    title: 'Total Alerts Triggered By Day',
    //calendar: {cellSize: 25},
    colorAxis: {colors: ['#86ce76', '#d61007']},
  };

  function selectHandler() {
    var selection = chart.getSelection();
    console.log('length', selection.length);
    if (selection.length > 0) {
      console.log(JSON.stringify(selection));
    }
  }

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

  google.visualization.events.addOneTimeListener(chart, 'ready', function () {
    chart.setSelection([{row: 0}]);
  });

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


rather than using setSelection to set an initial value,
add an argument to the select handler, which is received when calling manually,
it won't be present when the user selects a date.

function selectHandler(initialDate) {
  var selection = initialDate || chart.getSelection();
  if (selection.length > 0) {
    console.log(new Date(selection[0].date));
  }
}

then you can call the select handler on the ready event.

see following working snippet...

google.charts.load('current', {
  packages:['calendar']
}).then(function () {

  var response = {d: {Rows: [
    ['11/27/2018', 5],
    ['11/28/2018', 10],
    ['11/29/2018', 15],
    ['11/30/2018', 20]
  ]}};

  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({type: 'date', id: 'Date'});
  dataTable.addColumn({type: 'number', id: 'Changes'});

  for (var i = 0; i < response.d.Rows.length; i++){
    var row = [new Date(response.d.Rows[i][0]), response.d.Rows[i][1]];
    dataTable.addRow(row);
  }

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

  var options = {
    title: 'Total Alerts Triggered By Day',
    //calendar: {cellSize: 25},
    colorAxis: {colors: ['#86ce76', '#d61007']},
  };

  function selectHandler(initialDate) {
    var selection = initialDate || chart.getSelection();
    if (selection.length > 0) {
      console.log(new Date(selection[0].date));
    }
  }

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

  google.visualization.events.addOneTimeListener(chart, 'ready', function () {
    selectHandler([{date: (new Date).getTime()}]);
  });

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


UPDATE

from github, try replacing...

var selectedItem = initialDate || chart.getSelection()[0];
if (selectedItem.length > 0) {
  console.log(new Date(selectedItem[0].date));
}

with...

var selectedItem;
var selection = initialDate || chart.getSelection();
if (selection.length > 0) {
  console.log(new Date(selection[0].date));
  selectedItem = selection[0];
}

you shouldn't use --> chart.getSelection()[0]

because the select handler will fire both when something is selected and unselected.
when unselected, chart.getSelection()[0] will throw an error because the selection will be empty.

Upvotes: 0

Related Questions