Firestore, Angular and Highcharts

Firestore highcharts angular

 

In this tutorial, we will learn how to visualize real-time database updates using Firestore and the official Highcharts Angular wrapper. The entire project is in this GitHub link.

We will cover the following points in this article:

  1. Setup a Cloud Firestore project.
  2. Setup an Angular project with Firestore.
  3. Integrate Highcharts with Angular and Firestore.

Setup a Cloud Firestore project

  1. The first thing to do is to create a project, and here are the steps to do that: Login to https://console.firebase.google.com
  2. Click on Add project.
  3. Create a database.
  4. Select “start in test mode”.
  5. Create a collection for the database to have multiple documents to store the data.
  6. Add documents to the collection.
  7. Add your Angular App name to Firestore. Be sure to select Web as we are using the web for now
    .
  8. By registering Angular App Name into Firestore, we will be able to access all key capabilities out of the box.
  9. Get the Configuration details and use the firebaseConfig object in the angular app.

Setup an Angular project with Firestore

To set up an Angular project, follow the instructions in this link.
By the way, don’t forget to run the following command ng add @angular/fire when you are done with creating the Angular project, and here the reasons why you should do it:

  1. To list out all Firebase project. From that, we can choose our project for further configuration and development.
  2. To create a Firebase.json configuration file that lists your project configuration.
  3. To create a .firebaserc file that stores your project aliases.
  4. To update angular.json file.

Once the setup is done, it is time to add Firebase configuration object into the environment (see below):

export const environment = {
  production: false,
  firebaseConfig: {
    apiKey: "AIzaSyBaGUX7iwBRthIKOE_uhyzs1aPEuKPlEAE",
    authDomain: "firestore-angular-highcharts.firebaseapp.com",
    databaseURL: "https://firestore-angular-highcharts.firebaseio.com",
    projectId: "firestore-angular-highcharts",
    storageBucket: "firestore-angular-highcharts.appspot.com",
    messagingSenderId: "669023523724",
    appId: "1:669023523724:web:43f04e6a2ce0a92c01fca9",
    measurementId: "G-ZD6C3CEC85"
  }
};

The last step in this sec HighchartService to interact with Cloud Firestore API (see below):

import {
  Injectable
} from '@angular/core';
import {
  Observable
} from 'rxjs';
import {
  AngularFirestore,
  AngularFirestoreCollection
} from "@angular/fire/firestore";
import {
  map
} from "rxjs/operators";
@Injectable({
  providedIn: 'root'
})
export class HighchartService {
  private rateCollection: AngularFirestoreCollection < chartModal > ;
  rates$: Observable < chartModal[] > ;
  constructor(private readonly firestoreservice: AngularFirestore) {
    this.rateCollection = firestoreservice.collection < chartModal > ('ChartData');
    // .snapshotChanges() returns a DocumentChangeAction[], which contains
    // a lot of information about "what happened" with each change. If you want to
    // get the data and the id use the map operator.
    this.rates$ = this.rateCollection.snapshotChanges().pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data() as chartModal;
        const id = a.payload.doc.id;
        return {
          id,
          ...data
        };
      }))
    );
  }
}
export interface chartModal {
  currency: string,
    rate: number
}

Integrate Highcharts with Angular and Firestore

To visualize the data update on our project using Highcharts, we need to include Highcharts Angular wrapper. It allows us to access the highcharts library. highchats-angular is the official angular wrapper.
To install highcharts-angular and the Highcharts library, just run the following instruction: npm install highcharts-angular highcharts.
To use those packages, first, you have to import them. So, in the app.module.ts file, we import the module HighchartsChartModule from the highcharts-angular package.
Also, we import AngularFirestoreModule and initializeApp with firebaseConfig (see below):

  import {
    BrowserModule
  } from "@angular/platform-browser";
  import {
    NgModule
  } from "@angular/core";
  import {
    HighchartsChartModule
  } from "highcharts-angular";
  import {
    AppRoutingModule
  } from "./app-routing.module";
  import {
    AppComponent
  } from "./app.component";
  import {
    AngularFireModule
  } from "@angular/fire";
  import {
    environment
  } from "src/environments/environment";
  import {
    AngularFireAnalyticsModule
  } from "@angular/fire/analytics";
  import {
    AngularFirestoreModule
  } from "@angular/fire/firestore";
  @NgModule({
    declarations: [AppComponent],
    imports: [
      BrowserModule,
      AppRoutingModule,
      HighchartsChartModule,
      AngularFireAnalyticsModule,
      AngularFirestoreModule,
      AngularFireModule.initializeApp(environment.firebaseConfig),
    ],
    providers: [],
    bootstrap: [AppComponent],
  })
  export class AppModule {}

Let’s walk through what we are doing in app.component.ts.

Importing Highcharts from import * as Highcharts from “highcharts”; .
Importing service and modal from highchart.service.
On ngOnInit() we are subscribing the emitting values from filestore database and pushing new values to chartdata array and then Calling getChart() and initializing chart data.

import {
  Component,
  OnInit
} from "@angular/core";
import {
  HighchartService,
  chartModal
} from "./highchart.service";
import * as Highcharts from "highcharts";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent implements OnInit {
  title = "Firestore-Angular-Highcharts";
  items$: chartModal[];
  Highcharts: typeof Highcharts = Highcharts;
  chardata: any[] = [];
  chartOptions: any;
  constructor(private highchartservice: HighchartService) {}
  ngOnInit() {
    this.highchartservice.rates$.subscribe((assets) => {
      this.items$ = assets;
      if (this.items$) {
        this.items$.forEach((element) => {
          this.chardata.push(element.rate);
        });
        this.getChart();
      }
    });
  }
  getChart() {
    this.chartOptions = {
      series: [{
        data: this.chardata,
      }, ],
      chart: {
        type: "bar",
      },
      title: {
        text: "barchart",
      },
    };
  }
}

The last step to do in this project is to go to app.component.html to add highcharts-chart directive and some property binding to initialize the chart data and options:

<highcharts-chart *ngIf="chartOptions"
  [Highcharts]="Highcharts"
  [options]="chartOptions"
  style="width: 100%; height: 400px; display: block;">
</highcharts-chart>

And here is the final result:
As you can see on the GIF below, the bar chart gets the data from the database hosted on Firebase. When a new value is added to the database using the Firebase UI, the chart’s data is updated and displayed.

Likewise in the below example, we are plotting a Line chart with new values to the same line chart.

 

Well, that is it. Now, you know how to update a real-time database using Firestore, and how to visualize the update with Highcharts.