11

I want to integrate Google Charts in my Angular2 application. What is the way to do this? Is there any examples available?

I tried to load the package like Google Charts is demoed but I had problems with the loading. I tried angular2-google-chart... but did not manage to get it to work.

Thanks for your help.

BuckBazooka
  • 881
  • 1
  • 10
  • 18

4 Answers4

26

Here is how I solved it.

import { Component} from '@angular/core';
import { GoogleChartComponent} from './ChartComponent.js';

@Component({
  selector: 'evolution',
  template: `
    <div class="four wide column center aligned">
        <div id="chart_divEvolution" style="width: 900px; height: 500px;"></div>
    </div>
  `
})
export class EvolutionComponent extends GoogleChartComponent {
  private options;
  private data;
  private chart;
  constructor(){
    console.log("Here is EvolutionComponent")
  }

  drawGraph(){
    console.log("DrawGraph Evolution...");  
    this.data = this.createDataTable([
      ['Evolution', 'Imports', 'Exports'],
      ['A', 8695000, 6422800],
      ['B', 3792000, 3694000],
      ['C', 8175000, 800800]
    ]);

    this.options = {
      title: 'Evolution, 2014',
      chartArea: {width: '50%'},
      hAxis: {
        title: 'Value in USD',
        minValue: 0
      },
      vAxis: {
        title: 'Members'
      }
    };

    this.chart = this.createBarChart(document.getElementById('chart_divEvolution'));
    this.chart.draw(this.data, this.options);
  }
}

import { Component, OnInit} from '@angular/core';
declare var google:any;
@Component({
  selector: 'chart'
})
export class GoogleChartComponent implements OnInit {
  private static googleLoaded:any;

  constructor(){
      console.log("Here is GoogleChartComponent")
  }

  getGoogle() {
      return google;
  }
  ngOnInit() {
    console.log('ngOnInit');
    if(!GoogleChartComponent.googleLoaded) {
      GoogleChartComponent.googleLoaded = true;
      google.charts.load('current',  {packages: ['corechart', 'bar']});
    }
    google.charts.setOnLoadCallback(() => this.drawGraph());
  }

  drawGraph(){
      console.log("DrawGraph base class!!!! ");
  }

  createBarChart(element:any):any {
      return new google.visualization.BarChart(element);
  }

  createDataTable(array:any[]):any {
      return google.visualization.arrayToDataTable(array);
  }
}

Now all you need to do is add this to your index.html

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
BuckBazooka
  • 881
  • 1
  • 10
  • 18
  • Hey thanks for your answer. However I do have couple of questions- 1. In your example, you have used BarChart, but where I can find list of chart types supported other than BarChart, LineChart, BubbleChart, ScatterChart and PieChart? 2. Does Google supports multiple charts like Bar, Line and Bubble chart on same canvas (similar to any trading website eg. Google Finance or Yahoo Finance)? – Sanket Jun 12 '16 at 09:41
  • I'm happy if this was useful. I used the above class in my projects as a based class for other subclass which actually use the other chart type. Look at the doc at [Google Charts](https://developers.google.com/chart/) for all the charts available. – BuckBazooka Jun 13 '16 at 07:26
  • Thanks for reference :) – Sanket Jun 13 '16 at 08:29
  • Thanks a lot for this answer. Do you know how to make the chart responsive? Thanks! – Alex Fuentes Nov 30 '16 at 14:36
  • 1
    I would keep the base component off any specific chart method. I think createbarchart should be in the children classes. – Sebas Jan 31 '17 at 08:08
  • and also, I had to add `template: ''` in the @component declaration of GoogleChartComponent – Sebas Jan 31 '17 at 08:21
  • hello @BuckBazooka, I have used this code and implemented map. It worked well but I am not able use handler and get the selected marker details. I need to perform action once user selects any marker. – Akash Jain May 02 '17 at 06:30
  • Is it possible to implement the google map chart like the second last image in the below link?https://cloud.githubusercontent.com/assets/11042288/25892861/5c489e74-3593-11e7-8384-d6e48c6b2bf1.png – Sanjay Kumar N S Nov 10 '17 at 06:55
  • Great share. Thanks – muasif80 Mar 01 '18 at 02:21
  • what is the advantage of GoogleChartComponent ? We can use EvolutionComponent with declare var google:any; – canbax Jun 10 '19 at 11:03
5
//in index.html add
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

33.5KB loaded from google servers to your app.

now add

declare var google:any;

to your component and add your google chart code in ngOnInit.

import { Component, OnInit } from '@angular/core';
declare var google:any;

@Component({
  selector: 'app-charts',
  templateUrl: './charts.component.html',
  styleUrls: ['./charts.component.css']
})
export class ChartsComponent implements OnInit {

constructor() { 

}

ngOnInit() {

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

  function drawChart() {

    var data = google.visualization.arrayToDataTable([
      ['Task', 'Hours per Day'],
      ['Work',     11],
      ['Eat',      2],
      ['Commute',  2],
      ['Watch TV', 2],
      ['Sleep',    7]
    ]);

    var options = {
      title: 'My Daily Activities'
    };

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

    chart.draw(data, options);
  }
}

}

additional 35.8KB loaded from google servers when 'corechart' is loaded.

add this to your components html

<div id="piechart" style="width: 900px; height: 500px;"></div>

A better approach would be to use ViewChild instead of document.getElementById('piechart') in component ts file.

George Itty
  • 61
  • 1
  • 2
2

This solution is suited if you are using routing. You can create a Resolver that will initialize and resolve the google object, which you can inject into your component.

First you need to add the below line to the end of index.html

// index.html
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

Then you need to create a Resolver say, named GoogleChartResolver.

// shared/google-chart.resolver.ts
declare const google: any;

@Injectable()
export class GoogleChartResolver implements Resolve<any>{

  private static googleChartLoaded: boolean = false;
  constructor() {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

    if(GoogleChartResolver.googleChartLoaded){
      return Observable.of(google);
    } else {
      return Observable.create(function (observer: Observer<any>) {

        google.charts.load('current', {packages: ['corechart', 'bar']});
        google.charts.setOnLoadCallback(() => {
          observer.next(google);
          observer.complete();
          GoogleChartResolver.googleChartLoaded = true;
        });
      });
    }
  }
}

For every route and component you need an instance of google, you can add the below lines. You need to add the GoogleChartResolver to the list of Observables to be resolved for the route,

// app-routing.module.ts
{path: 'my-path', component: MyComponent, resolve: {google: GoogleChartResolver}}

In the MyComponent you can inejct ActivatedRoute and get the instance of google from the snapshot

// my.component.ts
private google: any;

constructor(private route: ActivatedRoute) {}

ngOnInit() {
  this.google = this.route.snapshot.data.google;
  drawChart(this.google)
}

All the dependent resources for the Google charts will be loaded during the first time you try to resolve the Resolver (here, the first time you visit /my-path). On subsequent resolutions, already resolved object is returned (no resource fetch required). Also this approach loads all Chart packages at once. If you need to optimize further, you can load different chart packages using different resolvers, but that may be an overkill, a solution for this will be, instead of creating Resolver classes, you can achieve route resolve functionality using method reference (say create a static method in a service which does the same thing).

Jos
  • 2,015
  • 1
  • 17
  • 22
1

If you are asking for component like using please refer below ng2-google-charts. https://www.npmjs.com/package/ng2-google-charts . It internally uses the loader.js google library to render library. You can use configuration for the charts through inputs.

Nikhil_k
  • 59
  • 2