Kayleigh
Kayleigh

Reputation: 33

Handling select event from Google Charts in Angular 6 (without wrapper such as ng2-google-charts!)

I'm using Google Charts with Angular 6 without a wrapper such as ng2-google-charts. I've implemented it succesfully based on this tutorial: http://anthonygiretti.com/2017/10/12/using-google-charts-in-angular-4-project-part-2/

However, now I want to add an event listener for click events inside the chart. For example when you click on a bar, it needs to run some function.

So, according to the Google Chart docs I need to add a listener like so:

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

So I added:

google.visualization.events.addListener(chartFunc(), 'select', this.mySelectHandler);

However, mySelectHandler doesn't run when I click on for example a bar in the chart.

I've looked at this very similar question. But the answer didn't work for me.

These are the services that build the chart:

import { Injectable } from '@angular/core';
import { GoogleChartsBaseService } from './google-charts-base.service';
import { ChartConfigModel } from '../../models/chart-config.model';

declare var google: any;

@Injectable({
  providedIn: 'root'
})
export class ChartService extends GoogleChartsBaseService {

  constructor() { super(); }

  public buildChart(elementId: string, data: any[], config: ChartConfigModel): void {
    const chartFunc = () =>  new google.visualization.ComboChart(document.getElementById(elementId));

    this.buildGoogleChart(data, chartFunc, config);
  }
}

declare const google: any;

export class GoogleChartsBaseService {

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

  public mySelectHandler() {
    console.log('hi');
  }

  protected buildGoogleChart(data: any[], chartFunc: any, options: any): void {
    const func = (chartFunc, options) => {
      const datatable = google.visualization.arrayToDataTable(data);
      const formatter = new google.visualization.DateFormat({ pattern: 'MMM d, yyyy | H:mm' });
      google.visualization.events.addListener(chartFunc(), 'select', this.mySelectHandler);
      formatter.format(datatable, 0);
      chartFunc().draw(datatable, options);
    };
    const callback = () => func(chartFunc, options);
    google.charts.setOnLoadCallback(callback);
  }
}

Upvotes: 3

Views: 1404

Answers (1)

Jip
Jip

Reputation: 153

Seems like you did most of it right. It's just that your chartFunc always returns a new instance of the google.visualization.ComboChart. So basically you're attaching the event listener to one chart and clicking on another.

Try to store the chart you get from chartFunc in a variable and use that to attach the event listener and also draw the data.

Try something like this:

declare const google: any;

export class GoogleChartsBaseService {

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

  public mySelectHandler() {
    console.log('hi');
  }

  protected buildGoogleChart(data: any[], chartFunc: any, options: any): void {
    const func = (chartFunc, options) => {
      const datatable = google.visualization.arrayToDataTable(data);
      const formatter = new google.visualization.DateFormat({ pattern: 'MMM d, yyyy | H:mm' });
      const myChart = chartFunc();
      google.visualization.events.addListener(myChart, 'select', this.mySelectHandler);
      formatter.format(datatable, 0);
      myChart.draw(datatable, options);
    };
    const callback = () => func(chartFunc, options);
    google.charts.setOnLoadCallback(callback);
  }
}

Upvotes: 3

Related Questions