Vue3 + Vue-Chart.js

上一篇文章有提到公司舊專案使用eChart 做圖表,被掃出有資安風險,現在要改用 Chart.js,我原本沒有要搭配其他把Chart.js 做成元件的套件,但後來因為某些原因還是使用了 Vue-chart.js,在這邊紀錄一下我的作法與踩的坑。

安裝

npm i vue-chartjs chart.js

父元件

我們把長條圖放在 BarChart 子元件,圖表的資料由父元件透過 props 傳入子元件,在 BarChart 子元件中做資料處理。

在下面的程式碼可以看到父元件把 chartData (可能是打 API 取回的資料,或是在父元件中處理過的資料)與 chartOptions(圖表的相關設定)傳入 BarChart 子元件。

<template>
  <!-- BarChart 子元件 -->
  <BarChart :chartData="chartData" :chartOptions="chartOptions"></BarChart>
</template>

<script>
// 引入 BarChart 子元件
import BarChart from './components/BarChart.vue';

export default {
  data() {
    return {
      // 圖表資料
      chartData: {
        labels: ['January', 'February', 'March', 'April'],
        datasets: [
					// 長條圖的 datasets 裡面是物件型別
					{
	          label: 'Red Data',
	          backgroundColor: '#f87979',
	          data: [40, 20, 12, 30]
	        }
				]
      },
      // 圖表設定
      chartOptions: {
        responsive: true,
        maintainAspectRatio: false,
      }
    };
  },
  components: {
    BarChart,
  },
  mounted() {
    console.log('parent', this.chartData)
  }
};
</script>

子元件

Vue-Chart.js 已經把 Chart.js 封裝成一個元件,不用再去取 DOM 元素跟透過 new Chart()方法生成圖表。

首先要引入與註冊,不同的圖表有不同的引入與註冊項目:

import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'
// 註冊
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)

以下面的程式碼當範例,只要把資料跟圖表的相關設定透過 v-bid 傳入 Vue-Chart.js 封裝的 Bar 圖表元件,就可以生成長條圖,資料更新後長條圖的內容也會跟著改變。

<template>
  <!-- 外層的 div 可以控制圖表的寬度與高度 -->
  <div style="width:600px;height:400px;">
    <Bar id="my-chart-id" :options="chartOptions" :data="chartData" />
  </div>
</template>

<script>
// 引入
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'
// 註冊
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)

export default {
  name: 'BarChart',
  components: { Bar },
  props: {
    chartData: Object,
    chartOptions: Object
  },
  data() {
    return {      
    }
  },  
  mounted() {    
    console.log('child', this.chartData)
  }
}
</script>

套件版本

示範範例

長條圖範例

Leave a Reply

Your email address will not be published. Required fields are marked *