2020年12月7日 星期一

vue-chart.js 及 Chart.js 在 Vue 中製作圖表

 Chart.js 是個可以方便製作圖表的 JavaScript library,可以在 HTML 中產生一個 canvas 物件產生

圖表。這篇以線圖舉例。


首先先 npm 安裝

npm install vue-chartjs chart.js --save


 Chart.js 的基本寫法是 new Chart,綁定一個 ID,裡面有三個參數:圖表類型( examle: line )、

資料內容 ( data )、選項( option ),HTML 中的 canvas 物件可以直接設定大小,但今天用 Vue,

所以要看看有什麼不同。


首先用 Vue 渲染的 canvas 是不能有 template 的,意味著通常要用 components 方式載入,不然整個畫面只有圖,使用 .vue 或 .js 檔案皆可,筆者比較習慣用 .vue。先製作空白圖表的 components。

在components 資料夾下新增 Chart.vue


import { 圖表種類 } in 'vue-chartjs';
extends: 圖表種類,
使用 mounted 得到資料後繪圖,圖表種類已經 import 過了,所以剩下 data、option 兩個參數。
一張圖表可以輸入不同的資料匯出不同的線圖,所以用 props 讓空白的表接收父組件的數據。

接下來回到父組件:

import 子組件 + components 子組件

import Chart from '../components/Chart.vue';
components: {
    Chart,
  },

template 放入組件的部分:

<template>
  <div>
    <div class="container">
      <div class="row">
        <div class="col-6">
          <chart v-if="loaded"
            :chartdata="chartdata"
            :options="options">
          </chart>
        </div>
      </div>
    </div>
  </div>
</template>


筆者有用 bootstrap 框架,這樣可以控制子組件,也就是圖表的大小,將 data 與 option 傳入組件,
為什麼要加上 v-if ?因為組件得到數據之後,"不會"重新繪圖
所以要透過確認有得到數據才繪圖。


json 格式的 data,沒有 API ,用 json-server 模擬從 API 得到資料,npm install -g json-server,用 VSCode ctrl+`打開終端機,然後 json-server --watch 想要觀測的檔案,沒取名照教學是db.json,npm install --save axios vue-axios 用來串接 API,別忘了 main.js 要加入 Vue.use(VueAxios, axios) 。


資料格式:

 data() {
    return {
      chartdata: {
        labels: [],
        datasets: [
          {
            label: '0050',
            fill: false,
            backgroundColor: 'rgba(188,96,147,1)',
            borderColor: 'rgba(212,85,49,1)',
            pointBackgroundColor: 'rgba(41,56,69,1)',
            data: [],
          },
        ],
      },
      options: {
        title: {
          display: true,
          fontSize: 24,
          text: '2020/11 0050 價格走勢',
        },
      },
      loaded: false,
    };
  },


chartdata 與 option 都必須是物件,chartdata 裡面就是 data,有兩個屬性,第一個 lebal 是 x 軸的值,是陣列,而 y 軸的值放在 datasets 的 data 下面。

將 json server 的數據陣列加入,並在 create 階段載入:

created() {
    this.getData();
  },
  methods: {
    getData() {
      const api = 'http://localhost:3000/0050';
      this.$http.get(api).then((res) => {
        this.chartdata.labels = res.data[0].Date;
        this.chartdata.datasets[0].data = res.data[0].Price;
        this.loaded = true;
        this.$forceUpdate();
      }).catch((error) => {
        if (error) {
          console.log(error);
        }
      });
    },
  },


中間有混入一個 loaded ,就是剛剛提到的拿來判斷是否收到數據,啟動子組件的繪圖。

最後就是剩下看文件找適合的選項把標題跟圖表畫的美美的。


附上 json 的結構,這個表是從證交所下載 .csv 並手動重製,x 軸為時間,y 軸為當天價格:



 


參考資料:

https://www.chartjs.org/

https://vue-chartjs.org/

https://dylan237.github.io/json-server.html

沒有留言:

張貼留言