File

projects/ng2-google-charts/src/lib/google-charts-loader.service.ts

Index

Methods

Constructor

Public constructor(localeId: string, googleChartsSettings: GoogleChartsSettings)
Parameters :
Name Type Optional
localeId string No
googleChartsSettings GoogleChartsSettings No

Methods

Public Async load
load(settings?: GoogleChartsSettings)
Parameters :
Name Type Optional
settings GoogleChartsSettings Yes
Returns : Promise<void>
declare var google: any;

import { Injectable, EventEmitter, LOCALE_ID, Inject, Optional } from '@angular/core';
import { GoogleChartsSettings } from './google-charts-interfaces';

interface InternalGoogleChartsSettings extends GoogleChartsSettings {
  callback?(): any;
}

@Injectable({
  providedIn: 'root'
})
export class GoogleChartsLoaderService {

  private googleScriptLoadingNotifier: EventEmitter<boolean>;
  private googleChartLoadingNotifier: EventEmitter<void>;
  private googleScriptIsLoading: boolean;
  private googleChartIsLoading: boolean;
  private loadGoogleChartsScriptPromise: Promise<void>;
  private loadedPackages: string[] = [];
  private loaded = false;

  public constructor(
    @Inject(LOCALE_ID) localeId: string,
    @Inject('googleChartsSettings') @Optional() private googleChartsSettings: GoogleChartsSettings,
  ) {
    const defaultSettings: GoogleChartsSettings = {
      googleChartsVersion: '50',
      language: localeId,
    };
    this.googleChartsSettings = {...defaultSettings, ...this.googleChartsSettings};

    this.googleScriptLoadingNotifier = new EventEmitter();
    this.googleChartLoadingNotifier = new EventEmitter();
    this.googleScriptIsLoading = false;
    this.googleChartIsLoading = false;

    this.loadGoogleChartsScriptPromise = new Promise((resolve, reject) => {
      if (typeof google !== 'undefined' && google.charts) {
        resolve();
      } else if (!this.googleScriptIsLoading) {

        this.googleScriptIsLoading = true;

        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://www.gstatic.com/charts/loader.js';
        script.async = true;
        script.defer = true;
        script.onload = () => {
          this.googleScriptIsLoading = false;
          this.googleScriptLoadingNotifier.emit(true);
          resolve();
        };
        script.onerror = () => {
          this.googleScriptIsLoading = false;
          this.googleScriptLoadingNotifier.emit(false);
          reject();
        };
        document.getElementsByTagName('head')[0].appendChild(script);

      } else {
        this.googleScriptLoadingNotifier.subscribe((loaded: boolean) => {
          if (loaded) {
            resolve();
          } else {
            reject();
          }
        });
      }
    });
  }

  public async load(settings?: GoogleChartsSettings): Promise<void> {
    await this.loadGoogleChartsScriptPromise;

    await new Promise((resolve) => {

      if (this.googleChartIsLoading) {
        this.googleChartLoadingNotifier.subscribe(() => {
          this.doLoad(resolve, settings);
        });

        return;
      }

      this.doLoad(resolve, settings);

    });
  }

  private doLoad(resolve: (value?: unknown) => void, settings?: GoogleChartsSettings) {
    settings = {...this.googleChartsSettings, ...settings}

    if (!settings.packages && this.loaded) {
      resolve();
      return;
    }

    if (settings.packages) {
      let pkgs = settings.packages.filter(p => this.loadedPackages.indexOf(p) < 0);

      if (pkgs.length == 0 && this.loaded) {
        resolve();
        return;
      }

      settings.packages = pkgs;
    }

    const _settings: InternalGoogleChartsSettings = settings;
    _settings.callback = () => {
      this.googleChartIsLoading = false;
      if (_settings.packages !== undefined) {
        this.loadedPackages = this.loadedPackages.concat(_settings.packages);
      }
      this.loaded = true;
      this.googleChartLoadingNotifier.emit();
      resolve();
    };

    this.googleChartIsLoading = true;
    google.charts.load(settings.googleChartsVersion, _settings);
  }
}

results matching ""

    No results matching ""