0

I'm building a bitcoin chart by Angular 4 universal integrated with asp.net core. I made http requests from api endpoints (https://www.coindesk.com/api/) which returned the data to visualize a chart. Everytime I reload the page, the chart display is always delayed around 1-2 seconds because it pulls data from server. I want to ask other solutions to prevent this, the main purpose is to make the chart fast pre-rendering as the same as plain texts on template. Therefore, I'm thinking about storing the api data into local storage, so reloading the page pulls data from local storage that make fast rendering. Is it possible to do that?

Here are my current codes:

historical-bpi.service.ts:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class HistoricalBpiService {

  private JsonBaseUrl: string = 'https://api.coindesk.com/v1/bpi/';

  constructor(private http:Http) { }

  getBpiData(url: string){
    return this.http.get(this.JsonBaseUrl+url)
      .map(res => res.json());
  }
}

component ts:

import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { HistoricalBpiService } from '../../services/historical-bpi.service';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
import * as moment from 'moment';

@Component({
  selector: 'app-banner',
  templateUrl: './banner.component.html',
  styleUrls: ['./banner.component.scss']
})
export class BannerComponent implements OnInit {

  private isDataAvailable: boolean;

  // Define date options
  private today: string = moment().format('YYYY-MM-DD');
  private oneYearAgo: string = moment().subtract(1,'years').format('YYYY-MM-DD');
  private nineMonthsAgo: string = moment().subtract(9,'months').format('YYYY-MM-DD');

  private oneYearData: string = 'historical/close.json?start=' + this.oneYearAgo + '&end=' + this.today;
  private nineMonthsData: string = 'historical/close.json?start=' + this.nineMonthsAgo + '&end=' + this.today;      

  // API calls for the date options
  oneYear() {
    this.historicalBpiService.getBpiData(this.oneYearData)
      .subscribe(
        res => {
          this.lineChartData[0].data = Object.keys(res.bpi).map(function (key) { return res.bpi[key]; });
          this.lineChartLabels = Object.keys(res.bpi);
          this.isDataAvailable = true;
        }
      )
  }

  nineMonths() {
    this.historicalBpiService.getBpiData(this.nineMonthsData)
      .subscribe(
        res => {
          this.lineChartData[0].data = Object.keys(res.bpi).map(function (key) { return res.bpi[key]; });
          this.lineChartLabels = Object.keys(res.bpi);
        }
      )
  }      

  constructor(
    private historicalBpiService:HistoricalBpiService,
    @Inject(PLATFORM_ID) private platformId: Object
  ) {}

  // lineChart

  public lineChartData:any = [
    { data:[], label: 'BTC' }
  ];

  public lineChartLabels:Array<any> = [];

  public lineChartOptions:any = {
    responsive: true,
    maintainAspectRatio: false,
    layout: {
      padding: 0
    },        
    scales: {
      yAxes: [{
        display: false,
        scaleLabel: {
          display: false,
          labelString: 'USD'
        },            
        gridLines: {
          display: true,
          tickMarkLength: 0
        }
      }],
      xAxes: [{
        ticks: {
          display: false,
          mirror: true
        }          
      }]
    },
    elements: {
      point: {
        radius: 0
      },
      line: {
        tension: 0, // 0 disables bezier curves
      }
    },
    hover: {
      mode: 'label',
      intersect: false
    },
    tooltips: {
      mode: 'label',
      intersect: false,
      backgroundColor: 'rgb(95,22,21)'          
    }
  };
  public lineChartColors:Array<any> = [
    {
      backgroundColor: 'rgba(199,32,48,1)',
      //borderColor: 'rgb(95,22,21)',
      pointHoverBackgroundColor: 'rgba(218,208,163,1)',
      steppedLine: false
    }
  ];
  public lineChartLegend:boolean = false;
  public lineChartType:string = 'line';    

  // events
  public chartClicked(e:any):void {
    console.log(e);
  }

  public chartHovered(e:any):void {
    console.log(e);
  }

  ngOnInit(){
    if (isPlatformBrowser(this.platformId)) {
      // Default chart
      this.oneYear();
    }
  }
}

component html:

<div class="chart">
      <canvas baseChart height="360px"
        [datasets]="lineChartData"
        [labels]="lineChartLabels"
        [options]="lineChartOptions"
        [colors]="lineChartColors"
        [legend]="lineChartLegend"
        [chartType]="lineChartType"
        (chartHover)="chartHovered($event)"
        (chartClick)="chartClicked($event)">
      </canvas>
    </div>
    <div class="d-flex justify-content-end dateOptions" *ngIf="isDataAvailable">      
      <input type="radio" name="Button" class="ButtonState" checked id="9months"/>
      <label class="Button" for="9months" (click)="nineMonths()">9 Months</label>
      <input type="radio" name="Button" class="ButtonState" checked id="1year"/>
      <label class="Button" for="1year" (click)="oneYear()">1 Year</label>
    </div>
Hoàng Nguyễn
  • 1,121
  • 3
  • 33
  • 57

1 Answers1

0

According to this article What is the max size of localStorage values? there's a limitation of 10Mb per storage and values can just be stored as strings.

If you monitored your application and the calls are the bottleneck (not rendering or application start) I'd suggest to use something like PouchDB/CouchDB that provides you a local document storage. https://pouchdb.com/

Ore
  • 972
  • 2
  • 12
  • 24