Angular ng2-chart Example

Photo by Serpstat from Pexels

This example we will build a chart using the historical data from a traded stock. This demo uses ng-charts from ng2-charts and a free API call from https://financialmodelingprep.com.

So you will need to run the following:

npm install --save ng2-charts
npm install --save chart.js

From your Angular application add a new service.

ng generate component services/stock-fmp

The code for the stock API service.

import { Injectable } from '@angular/core';
import { tap, catchError, concatMap, shareReplay } from 'rxjs/operators';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
export interface StockPriceResult {
  date?: Date;
  price?: any;
}
@Injectable({
  providedIn: 'root'
})
export class StockFmpService {
  errorMessage: any;
  day: any;
  constructor(private http: HttpClient, private shared: SharedService) { }
  getStockPriceHistory(ticker: string, dataSeriesType: string, fromDate: 
    string, toDate: string) {
    full/${ticker}? 
   serietype=${dataSeriesType}&from=${fromDate}&to=${toDate}`);
     return this.http.get<StockPriceResult> 
   (`${this.shared.baseFinancialURL}/api/v3/historical-price-full/${ticker}? 
    serietype=${dataSeriesType}&from=${fromDate}&to=${toDate}`);
  }
}

Create the chart component with

ng generate ng2-charts-schematics:line my-line-chart

This will generate a line chart component. Now you just have to make a couple of modifications to it.

Under the export class componentname implements Oninit {

Add the following

  @Input() lineChartData: any;
  @Input() lineChartLabels: any;

Remove the hard coded data and labels below

// REMOVE THIS CODE
 public lineChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
 public lineChartOptions: ChartOptions = {
   responsive: true,
 };
// REMOVE THIS CODE

Code for the component

import { Component, OnInit } from '@angular/core';
import { StockFmpService } from './../services/stock-fmp.service';
import { HttpErrorResponse } from '@angular/common/http';

To declare the lineChartArr I had to do the following in order to avoid the error (Snapshot Below)

   
 public lineChartDataArr: ChartDataSets[] = [
      { data: [], label: '' },
    ];
    public lineChartLabelArr: any = [];
 ngOnInit(): void {
   this.obsSubscribe = this.financeAPI.getStockPriceHistory('AAPL', 
   'line', fromDate, today)
        .subscribe((data) => {
          const labelArr =  data['historical'].map(data => data.date);
          const dataArr =  data['historical'].map(data => data.close);
          this.lineChartLabelArr = labelArr;
          this.lineChartDataArr = [{ data: dataArr, label: 'AAPL Price 
          History' }];      
    },
    (err: HttpErrorResponse) => {
      console.log(err);
    });
  }

In your component HTML file send the data to the chart component

<app-line-chart [lineChartData]="lineChartDataArr" [lineChartLabels]="lineChartLabelArr"></app-line-chart>

Issue #1

Error when using any = [] for the chart data array.

public lineChartDataArr: any = [] 

VS

public lineChartDataArr: ChartDataSets[] = [
  { data: [], label: '' },
];

LineChartComponent.html:6 ERROR TypeError: Cannot set property ‘data’ of undefined
at BaseChartDirective.push../node_modules/ng2-charts/fesm5/ng2-charts.js.BaseChartDirective.propagateDataToDatasets (ng2-charts.js:911)
at BaseChartDirective.push../node_modules/ng2-charts/fesm5/ng2-charts.js.BaseChartDirective.ngDoCheck (ng2-charts.js:348)
at checkAndUpdateDirectiveInline (core.js:21779)
at checkAndUpdateNodeInline (core.js:29989)
at checkAndUpdateNode (core.js:29951)
at debugCheckAndUpdateNode (core.js:30585)
at debugCheckDirectivesFn (core.js:30545)
at Object.eval as updateDirectives
at Object.debugUpdateDirectives as updateDirectives
at checkAndUpdateView (core.js:29933)