如何在Angular中使用來自REST API的資料整合Chart.js?

如何在Angular中使用來自REST API的資料整合Chart.js?

圖表是以易於理解和分析的格式直觀地顯示大量資料集的一個好方法。它們是顯示兩個或多個資料集之間存在的關係的好方法。

存在不同型別的圖表,其中一些包括條形圖、折線圖、餅圖、雷達圖等。

在這篇文章中,你將利用一個名為Angular的前端框架以及一個名為Chart.js的JavaScript庫來顯示一個名為Coinranking的加密貨幣平臺的資料。你還將利用Coinranking的API,將加密貨幣的列表及其價格視覺化。

先決條件

要跟上本教程,請確保你熟悉下面列出的技術的基本知識:

    • HTML
    • JavaScript
    • TypeScript
  • npm

如何安裝和建立Angular應用程式

首先,你需要使用以下步驟安裝和設定Angular:

Step 1: 安裝NPM(Node Package Manager)

要安裝npm,你需要下載Node.js。這可以通過Node.js網站完成。

Node.js是一個開源的跨平臺伺服器環境,可以在Windows、Linux、Unix、macOS等系統上執行。它允許我們利用npm將Chart.js等庫安裝到我們的Angular應用程式中。

Step 2: 安裝Angular CLI(命令列介面)

一旦Node.js安裝完畢,你現在可以通過終端/命令列使用以下命令將Angular下載到你的機器中:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install -g @angular/cli
npm install -g @angular/cli
npm install -g @angular/cli

為了確認Angular已經被安裝,你可以通過執行 ng v 命令來檢視版本,這將給我們帶來以下結果:

Angular CLI版本

Angular CLI版本

Step 3: 建立一個新的Angular專案

現在Angular已經安裝完畢,你現在可以通過在終端執行以下命令來建立一個新專案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ng new ng-chart --routing=false --style=css
cd ng-chart
code .
ng new ng-chart --routing=false --style=css cd ng-chart code .
ng new ng-chart --routing=false --style=css
cd ng-chart
code .

通過上面的命令,我們已經用 ng new 命令建立了一個新的Angular專案,禁用了路由,並將樣式格式設為CSS。

接下來,使用 cd 命令導航到專案目錄,並在Visual Studio Code中開啟該專案。

你不需要為這個專案生成一個新的元件。你將使用Angular CLI建立的兩個預設檔案  app.component.ts 和 app.component.hmtl –來渲染圖表。這些檔案都在你專案的 app 目錄下。

app.component.html 檔案包含一些你需要去掉的模板程式碼。Chart.js庫現在可以被整合到你的應用程式中。

如何在Angular中整合Chart.js

要將chart.js庫新增到Angular應用程式中,你需要在終端中執行以下命令:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm i chart.js
npm i chart.js
npm i chart.js

為了確認chart.js已經被安裝,你可以檢查你的專案中的 package.json 檔案。你應該在 dependencies 物件中看到chart.js的版本,如下圖所示:

Chart.js版本

Chart.js版本

現在你可以在你的專案中的 app.component.ts 檔案中匯入chart.js庫,如下圖所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import Chart from 'chart.js/auto';
import Chart from 'chart.js/auto';
import Chart from 'chart.js/auto';

接下來,建立一個名為 chart 的變數,並將其設定為一個空陣列:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
chart: any = []
chart: any = []
chart: any = []

導航到chart.js文件的入門頁面,抓取帶有靜態資料的模板程式碼,並將其貼上到 ngOnInit 生命週期鉤子中:

注意:Angular的 ngOnInit 生命週期鉤子在元件初始化後會被觸發一次。也就是說,它只在Angular元件發生第一次變化檢測時被呼叫。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export class AppComponent {
title = 'ng-chart';
chart: any = [];
constructor() {}
ngOnInit() {
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
}
}
export class AppComponent { title = 'ng-chart'; chart: any = []; constructor() {} ngOnInit() { this.chart = new Chart('canvas', { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [ { label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1, }, ], }, options: { scales: { y: { beginAtZero: true, }, }, }, }); } }
export class AppComponent {
title = 'ng-chart';
chart: any = [];
constructor() {}
ngOnInit() {
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
}
}

在上面的程式碼中,在資料物件中,有一個 labels 鍵,它包含一個有不同值的陣列。在這之下,你有一個 datasets 陣列,其中包含一個物件。

在這個物件中,有一個叫做 data 的陣列,裡面有不同的數字值。這些值代表將在瀏覽器中的圖表上顯示的資料。

在圖表顯示在瀏覽器中之前,你還需要抓取 <canvas></canvas> html標籤,並將其貼上到  app.component.html 檔案中,如下所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<div>
<canvas id="canvas">{{chart}}</canvas>
</div>
<div> <canvas id="canvas">{{chart}}</canvas> </div>
<div>
<canvas id="canvas">{{chart}}</canvas>
</div>

注意:在 app.component.html 檔案中,<canvas> 標籤有一個叫做 canvas 的 id 。這必須與 app.component.ts 檔案中 new Chart 物件前的括號內的值相同。如果這兩個名字不一樣,圖表將不會顯示。

現在你可以通過在終端執行 ng serve --open 命令來編譯和服務該專案。你應該有以下結果:

用靜態資料顯示圖表

用靜態資料顯示圖表

如何整合REST API

要整合REST API,請使用此連結前往Coinranking網站。你應該看到一個類似這樣的頁面:

Coinranking網站

Coinranking網站

首先點選 “Get API Key” 按鈕。你將被引導到一個頁面,在那裡你可以建立一個賬戶,並有機會獲得API金鑰。

複製API金鑰並開啟Angular專案中的 environment.ts 檔案。在該物件中,建立一個名為 API_KEY 的變數,並貼上從CoinRanking生成的API金鑰,如下圖所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export const environment = {
production: false,
API_KEY: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
};
export const environment = { production: false, API_KEY: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', };
export const environment = {
production: false,
API_KEY: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
};

接下來,你需要複製API來獲取CoinRanking文件中的所有加密貨幣幣。

Coinranking API文件

Coinranking API文件

為了使用上面複製的API連結,你需要通過執行下面的命令建立一個Angular Service:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ng g service services/chart
ng g service services/chart
ng g service services/chart

隨著 chart.service.ts 檔案的建立,你現在可以貼上程式碼,幫助我們消費REST API,如下圖所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from 'src/environments/environment';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'X-My-Custom-Header': `${environment.API_KEY}`,
'Access-Control-Allow-Origin': '*',
}),
};
@Injectable({
providedIn: 'root',
})
export class ChartService {
private baseUrl = 'https://api.coinranking.com/v2/coins';
private proxyUrl = 'https://cors-anywhere.herokuapp.com/';
constructor(private http: HttpClient) {}
cryptoData() {
const url = `${this.proxyUrl}${this.baseUrl}`;
return this.http.get(url, httpOptions);
}
}
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { environment } from 'src/environments/environment'; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', 'X-My-Custom-Header': `${environment.API_KEY}`, 'Access-Control-Allow-Origin': '*', }), }; @Injectable({ providedIn: 'root', }) export class ChartService { private baseUrl = 'https://api.coinranking.com/v2/coins'; private proxyUrl = 'https://cors-anywhere.herokuapp.com/'; constructor(private http: HttpClient) {} cryptoData() { const url = `${this.proxyUrl}${this.baseUrl}`; return this.http.get(url, httpOptions); } }
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from 'src/environments/environment';

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'X-My-Custom-Header': `${environment.API_KEY}`,
    'Access-Control-Allow-Origin': '*',
  }),
};

@Injectable({
  providedIn: 'root',
})
export class ChartService {
  private baseUrl = 'https://api.coinranking.com/v2/coins';
  private proxyUrl = 'https://cors-anywhere.herokuapp.com/';

  constructor(private http: HttpClient) {}

  cryptoData() {
    const url = `${this.proxyUrl}${this.baseUrl}`;
    return this.http.get(url, httpOptions);
  }
}

總結一下上面的程式碼,以下是我們所做的:

  • 我們在第2行匯入了 HttpClientHttpHeaders ,以及第3行的 environment 檔案。
  • 第5行第11行之間,我們建立了一個叫做 httpOptions 的變數。 httpOptions 變數持有一個物件,其中包含上面匯入的 HttpHeaders 配置。這裡我們設定了content-type,將 environment 檔案中的 API_KEY 變數傳遞到標頭檔案中,然後將 Access-Control-Allow-Origin 設定為萬用字元。這意味著瀏覽器應該允許來自原點的請求程式碼。
  • 第17行,我們建立了一個名為 baseUrl 的私有變數來儲存REST API,而在第28行,我們建立了一個名為 proxyUrl 的變數來儲存CORS Anywhere連結。CORS Anywhere連結是一個NodeJS代理,它在被代理的請求中新增了CORS頭資訊,並有助於在這個過程中防止CORS錯誤。
  • 第20行,我們將 HttpClient 注入到建構函式中,這使得它可以在服務中訪問。
  • 最後,我們在第22行建立了一個名為 cryptoData() 的函式。在這個函式中,有一個叫做 url 的變數。我們使用url變數來追加 proxyUrl 和 baseUrl 變數來構建我們的API。此外,在 return 語句中,我們使用 get() http方法從REST API中獲取資料。

為了使 HttpClient 工作,你需要匯入並注入 HttpClientModule 到 app.module.ts 檔案中,可以看到如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, HttpClientModule], providers: [], bootstrap: [AppComponent], }) export class AppModule {}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

正如上面所看到的,HttpClientModule 被匯入並注入了 imports 陣列中。

如何在圖表中顯示資料

為了在圖表上顯示資料,你需要前往 app.component.ts 檔案並帶入你的圖表服務檔案,如下圖所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Component } from '@angular/core';
import Chart from 'chart.js/auto';
import { ChartService } from './service/chart.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'ng-chart';
chart: any = [];
result: any;
coinPrice: any;
coinName: any;
constructor(private service: ChartService) {}
ngOnInit() {
this.service.cryptoData().subscribe((res) => {
this.result = res;
this.coinPrice = this.result.data.coins.map((coins: any) => coins.price);
this.coinName = this.result.data.coins.map((coins: any) => coins.name);
console.log(this.coinPrice);
console.log(this.coinName);
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
});
}
}
import { Component } from '@angular/core'; import Chart from 'chart.js/auto'; import { ChartService } from './service/chart.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { title = 'ng-chart'; chart: any = []; result: any; coinPrice: any; coinName: any; constructor(private service: ChartService) {} ngOnInit() { this.service.cryptoData().subscribe((res) => { this.result = res; this.coinPrice = this.result.data.coins.map((coins: any) => coins.price); this.coinName = this.result.data.coins.map((coins: any) => coins.name); console.log(this.coinPrice); console.log(this.coinName); this.chart = new Chart('canvas', { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [ { label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1, }, ], }, options: { scales: { y: { beginAtZero: true, }, }, }, }); }); } }
import { Component } from '@angular/core';
import Chart from 'chart.js/auto';
import { ChartService } from './service/chart.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'ng-chart';
  chart: any = [];
  result: any;
  coinPrice: any;
  coinName: any;

  constructor(private service: ChartService) {}

  ngOnInit() {
    this.service.cryptoData().subscribe((res) => {
      this.result = res;
      this.coinPrice = this.result.data.coins.map((coins: any) => coins.price);
      this.coinName = this.result.data.coins.map((coins: any) => coins.name);
      console.log(this.coinPrice);
      console.log(this.coinName);

      this.chart = new Chart('canvas', {
        type: 'bar',
        data: {
          labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
          datasets: [
            {
              label: '# of Votes',
              data: [12, 19, 3, 5, 2, 3],
              borderWidth: 1,
            },
          ],
        },
        options: {
          scales: {
            y: {
              beginAtZero: true,
            },
          },
        },
      });
    });
  }
}
  • 如上所述,我們首先匯入了圖表服務,並分別在第3行第17行將其注入到我們的元件中。
  • 我們建立了三個變數,分別是 resultcoinPrice, 和 coinName。這些變數將在以後的專案中用來儲存資料。
  • 在 ngOnInit() 生命週期鉤子中,我們在第 line 20 呼叫了 cryptoData() 函式,該函式返回一個被訂閱的觀察變數。這使得我們可以從過程中的資料中返回一個響應。
  • 第21行,我們使用 this 關鍵字呼叫 result 變數,並將其設定為持有資料。
  • 接下來,在第22行第23行,我們呼叫了coinPricecoinName變數,通過資料對映,並分別將硬幣價格和硬幣名稱附加到它們身上。
  • 為了在瀏覽器中看到資料的結果,我們使用 console.log() 函式來顯示資料,如下圖所示:

控制檯上顯示的來自CoinRanking API的資料

控制檯上顯示的來自CoinRanking API的資料。

最後要做的是將上圖中看到的資料繪製成圖表。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ngOnInit() {
this.service.cryptoData().subscribe((res) => {
this.result = res;
this.coinPrice = this.result.data.coins.map((coins: any) => coins.price);
this.coinName = this.result.data.coins.map((coins: any) => coins.name);
console.log(this.coinPrice);
console.log(this.coinName);
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: this.coinName,
datasets: [
{
data: this.coinPrice,
borderColor: '#3e95cd',
label: 'Coin Price',
backgroundColor: 'rgba(93, 175, 89, 0.1)',
borderWidth: 3,
},
],
},
});
});
}
ngOnInit() { this.service.cryptoData().subscribe((res) => { this.result = res; this.coinPrice = this.result.data.coins.map((coins: any) => coins.price); this.coinName = this.result.data.coins.map((coins: any) => coins.name); console.log(this.coinPrice); console.log(this.coinName); this.chart = new Chart('canvas', { type: 'bar', data: { labels: this.coinName, datasets: [ { data: this.coinPrice, borderColor: '#3e95cd', label: 'Coin Price', backgroundColor: 'rgba(93, 175, 89, 0.1)', borderWidth: 3, }, ], }, }); }); }
ngOnInit() {
    this.service.cryptoData().subscribe((res) => {
      this.result = res;
      this.coinPrice = this.result.data.coins.map((coins: any) => coins.price);
      this.coinName = this.result.data.coins.map((coins: any) => coins.name);
      console.log(this.coinPrice);
      console.log(this.coinName);

      this.chart = new Chart('canvas', {
        type: 'bar',
        data: {
          labels: this.coinName,
          datasets: [
            {
              data: this.coinPrice,
              borderColor: '#3e95cd',
              label: 'Coin Price',
              backgroundColor: 'rgba(93, 175, 89, 0.1)',
              borderWidth: 3,
            },
          ],
        },
      });
    });
  }
  • 如上所示,我們首先用從CoinRanking API得到的幣名替換了第12行標籤中的靜態資料。
  • 接下來,我們將第15行的靜態資料替換為從CoinRanking API中得到的價格。

現在通過執行 ng serve --open 命令編譯該專案,並在瀏覽器中看到結果,如下圖所示:

圖表的最終結果

圖表的最終結果

注意:你有可能在編譯專案後遇到一個錯誤,即(Failed to load resource: the server responded with a status of 403 (Forbidden))。

你需要做的是點選控制檯中的CORS Anywhere連結,它將在一個新的標籤頁中開啟,上面有一個按鈕,寫著Request temporary access to the demo server。點選該按鈕,然後重新整理頁面。資料現在應該反映在圖表上。

小結

在本教程中,你學到了如何在Angular應用程式中安裝和整合Chart.js庫和REST API。如果你想訪問程式碼庫,你可以在GitHub上克隆這個repo

評論留言