Angular2 + Google Charts. How to integrate Google Charts in Angular2?
Asked Answered
G

4

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.

Girth answered 31/5, 2016 at 9:52 Comment(2)
did you try anything?Peevish
Can you put down the code that you tired?Halfcocked
G
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>
Girth answered 1/6, 2016 at 12:23 Comment(9)
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)?Borges
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 for all the charts available.Girth
Thanks a lot for this answer. Do you know how to make the chart responsive? Thanks!Eurasian
I would keep the base component off any specific chart method. I think createbarchart should be in the children classes.Baccarat
and also, I had to add template: '<ng-content></ng-content>' in the @component declaration of GoogleChartComponentBaccarat
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.Uam
Is it possible to implement the google map chart like the second last image in the below link?cloud.githubusercontent.com/assets/11042288/25892861/…Chrysalid
Great share. ThanksAtrice
what is the advantage of GoogleChartComponent ? We can use EvolutionComponent with declare var google:any;Expiration
S
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.

Sullen answered 1/11, 2017 at 10:20 Comment(0)
H
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).

Hadfield answered 22/8, 2017 at 7:28 Comment(1)
awesome. this is the best way, imho.Boozy
P
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.

Prussiate answered 6/5, 2018 at 3:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.