Angular2 + Google Charts. How to integrate Google

2020-02-08 18:55发布

问题:

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.

回答1:

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>


回答2:

//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.



回答3:

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).



回答4:

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.