📊

Vue2 / Vue3 でも Chart.js 3 を使いたい

2021/09/19に公開

Chart.js 3 について

Chart.js 3 は、 Canvas を用いたグラフ描画ライブラリとして人気の高い Chart.js の最新バージョンで、 2021年4月にリリースされました。

v3 は従来の v2 と比べ、以下のような大きな改善が行われています。

  • webworkers を用いた並列レンダリングなどによるパフォーマンスの劇的向上
  • 細分化されたモジュールを必要十分に import することによるツリーシェイキングの有効化
  • moment など、日付操作用のライブラリへの依存の撤廃
  • CSSインジェクションの廃止
  • 膨大な数のバグフィックス

ただし、多くの破壊的変更を含んでいるため、移行の際は注意が必要です。

https://www.chartjs.org/docs/next/getting-started/v3-migration.html

Vue における Chart.js

vue-chartjs は、Chart.js の Vue ラッパーのデファクトスタンダードとして長らく利用されてきました。

しかし、 vue-chartjs の Vue3 及び Chart.js 3 のサポートは難航しており、現状でのマイグレーションは困難となっています。

https://github.com/apertureless/vue-chartjs/issues/695#issuecomment-841803779
https://github.com/apertureless/vue-chartjs/issues/699

特に Chat.js 3 については、その多くの仕様変更、改善へ対応することだどれほど難しいかを、メンテナが語っており、すぐに安定して利用できるようになる見込みはなさそうです。

https://github.com/apertureless/vue-chartjs/issues/695#issuecomment-841803779

vue-chart-3 について

vue-chart-3 は、 vue-chartjs を新たに書き直すことで、これらの問題を解決するパッケージです。

https://github.com/victorgarciaesgi/vue-chart-3

役割は vue-chartjs と概ね同じですが、以下のような特徴を持ちます。

  • Vue2/Vue3 の両サポート
  • Chart.js 3 をサポート
  • TypeScript によるリプレイス
  • CompositionAPI での Hooks の提供 (執筆時点ではα)

軽く使ってみた限り、vue-chartjs の機能に深く依存する使い方をしていない限りはすんなり使えるのではないかと感じたため、簡単なサンプルを紹介します。

Vue3 + TypeScript + Chart.js 3 の例

プロジェクト作成

Vue3 は Vite ですぐに環境を構築できます。

$ yarn create vite
✔ Project name: … vue-3-chartjs-3
✔ Select a framework: › vue
✔ Select a variant: › vue-ts

$ cd vue-3-chartjs-3/
$ yarn install
$ yarn dev

chart.js / vue-chart-3 をインストール

yarn add chart.js@^3.1.0 vue-chart-3

PieChart / LineChart の描画

ここでは、円グラフ(PieChart) と折れ線グラフ(LineChart) を例に、サンプルデータを描画してみます。

src/App.vue
<script lang="ts">
import { Chart, ChartData, registerables } from "chart.js";
import { defineComponent } from "vue";
import { PieChart, LineChart } from "vue-chart-3";

// 使用するモジュールの宣言
// ここでは便宜上、全てのモジュールを使用する registerables を使用しているが、
// 必要十分なモジュールのみを宣言することで、ツリーシェイキングを行うことができる
Chart.register(...registerables);

export default defineComponent({
  components: {
    PieChart,
    LineChart,
  },
  setup() {
    // PieChart 用のデータ
    const pieData: ChartData<"pie"> = {
      labels: ["Red", "Blue", "Yellow"],
      datasets: [
        {
          label: "My First Dataset",
          data: [300, 50, 100],
          backgroundColor: [
            "rgb(255, 99, 132)",
            "rgb(54, 162, 235)",
            "rgb(255, 205, 86)",
          ],
          hoverOffset: 4,
        },
      ],
    };

    // LineChart 用のデータ
    const lineData: ChartData<"line"> = {
      labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
      datasets: [
        {
          label: "My First Dataset",
          data: [65, 59, 80, 81, 56, 55, 40],
          fill: false,
          borderColor: "rgb(75, 192, 192)",
          tension: 0.1,
        },
      ],
    };

    return { pieData, lineData };
  },
});
</script>

<template>
  <div class="wrapper">
    <PieChart :chartData="pieData" />
    <LineChart :chartData="lineData" />
  </div>
</template>

<style scoped>
.wrapper {
  display: flex;
}
</style>

実行結果

円グラフ、折れ線グラフともに描画できていることが確認できます。

Vue2 + JavaScript + Chart.js 3 の例

プロジェクト作成

Vite だとデフォルトで Vue3 が使われるので、 vue-cli のデフォルト設定を使ってプロジェクトを作成します。

$ npx vue create vue2-chartjs-3
$ cd vue-2-chartjs-3/

chart.js / vue-chart-3 / compositionAPI をインストール

Vue3 の場合に加え、 Vue2 では CompositionAPI のプラグインが必要になるため、あわせてインストールします。

yarn add chart.js@^3.1.0 vue-chart-3  @vue/composition-api

PieChart / LineChart の描画

Vue3 の場合と同様のコードを Vue2 で書くと以下のようになります。

src/App.vue
<template>
  <div id="app">
    <PieChart :chartData="pieData" />
    <LineChart :chartData="lineData" />
  </div>
</template>

<script>
import { Chart, registerables } from "chart.js";
import { PieChart, LineChart } from "vue-chart-3";
Chart.register(...registerables);

export default {
  components: {
    PieChart,
    LineChart,
  },
  computed: {
    pieData() {
      return {
        labels: ["Red", "Blue", "Yellow"],
        datasets: [
          {
            label: "My First Dataset",
            data: [300, 50, 100],
            backgroundColor: [
              "rgb(255, 99, 132)",
              "rgb(54, 162, 235)",
              "rgb(255, 205, 86)",
            ],
            hoverOffset: 4,
          },
        ],
      };
    },
    lineData() {
      return {
        labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
        datasets: [
          {
            label: "My First Dataset",
            data: [65, 59, 80, 81, 56, 55, 40],
            fill: false,
            borderColor: "rgb(75, 192, 192)",
            tension: 0.1,
          },
        ],
      };
    },
  },
};
</script>

<style scoped>
#app {
  display: flex;
}
</style>

実行結果

Vue3 の場合と同様の結果が得られたことが確認できました。

まとめ

本記事では、 vue-chartjs の代わりに vue-chart-3 を用いることで、 Vue3 や Chart.js 3 の組み合わせが実現できることを確認しました。

サンプルコードでは最小限のグラフ描画のみ記載しましたが、他にも vue-chartjs で出来ていたリアクティブな data/options の同期ももちろん可能であるため、シンプルなユースケースの範囲であればすんなり移行できるのではないかと感じました。

GitHubで編集を提案

Discussion