JavaScriptライブラリのChart.jsを利用するとブラウザ上に美しいグラフを簡単に描写することができます。

日々の業務活動から発生したデータを保存している外部サービスやバックエンドから取得したデータを使ってブラウザ上にグラフ/チャートとして描写したいという要望もあるかと思います。そのような時にどうやって情報を取得し、グラフに描写するのか知りたいと思った時に活用できるのが本文書です。

axiosライブラリを利用しAPI経由で外部サービスまたはバックエンドからデータを取得し、Vue.jsを使って取得したデータを処理し、Chart.jsでグラフを描く手順を確認します。

Chart.jsでグラフを描くためには、グラフの元になるデータの準備またaxiosやVue.jsといった技術の基礎知識も必要となります。

Chart.js単体よりもVue.js+Axiosとの組み合わせた使用方法の説明に重点を置いているためChart.jsに関するグラフの見栄えの設定の説明は行っておりません。
fukidashi

axiosを利用を使って情報を取得する場合は情報を取得できる環境を事前に準備しておく必要があります。

Chart.jsでグラフを描く

まずはChart.jsを使ってシンプルなグラフを描いてみます。任意のディレクトリを作成してそのディレクトリにindex.htmlファイルを作成します。

Chart.js, Vue.js, axiosに使用するライブラリはすべてcdnから読み込みます。そのため動作確認のための特別な環境は必要ありません。デスクトップにindex.htmlを作成して実行しています。
fukidashi

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Chart.js+Vue.js+Axios</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  </head>
  <body>
    <div style="width: 600px">
      <canvas id="myChart"></canvas>
    </div>
    <script>
      const ctx = document.getElementById('myChart').getContext('2d');
      const myChart = new Chart(ctx, {
        type: 'line',
        data: {
          labels: ['2024年1月', '2024年2月', '2024年3月', '2024年4月'],
          datasets: [
            {
              label: '四半期の売上数の遷移',
              data: [120, 190, 34, 58],
            },
          ],
        },
      });
    </script>
  </body>
</html>

実行すると下記のような線グラフを作成することができました。線の色や背景の色は何も設定しなければ、10行前後で綺麗なグラフを描くことができます。

上記のコードをhtmlファイルを作成し、コピー&ペーストするたけで下記のグラフが描けます。配色についてはChart.jsのマニュアルを見て確認すれば簡単に色付けすることができます。
fukidashi
Chart.jsのみを利用したサンプルグラフ
Chart.jsのみを利用したサンプルグラフ

Chart.js + vue.jsでグラフを描く

vue.jsライブラリの追加

vue.jsを使ってグラフを描きます。cdnからvue.jsを読み込むためにscriptタグを追加します。


<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

divタグにid=”app”を追加します。


<div id="app" style="width:600px">
  <canvas id="myChart"></canvas>
</div>

vue.jsのライフサイクルフックのmounted完了後にChart.jsによるグラフの描写を実行します。Vue.jsのバージョン3のOptions APIでコードを記述しています。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Chart.js+Vue.js+Axios</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  </head>
  <body>
    <div id="app" style="width: 600px">
      <canvas id="myChart"></canvas>
    </div>
    <script>
      const { createApp } = Vue;

      createApp({
        mounted() {
          const ctx = document.getElementById('myChart').getContext('2d');
          new Chart(ctx, {
            type: 'line',
            data: {
              labels: ['2024年1月', '2024年2月', '2024年3月', '2024年4月'],
              datasets: [
                {
                  label: '四半期の売上数の遷移',
                  data: [120, 190, 34, 58],
                },
              ],
            },
          });
        },
      }).mount('#app');
    </script>
  </body>
</html>

vue.jsを使ってもブラウザには同じグラフが描写されます。

Chart.jsのみを利用したサンプルグラフ

Composition APIを利用して記述した場合は以下のように記述することができます。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Chart.js+Vue.js+Axios</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app" style="width: 600px">
      <canvas id="myChart"></canvas>
    </div>
    <script>
      const { createApp, onMounted } = Vue;

      createApp({
        setup() {
          onMounted(() => {
            const ctx = document.getElementById('myChart').getContext('2d');
            new Chart(ctx, {
              type: 'line',
              data: {
                labels: ['2024年1月', '2024年2月', '2024年3月', '2024年4月'],
                datasets: [
                  {
                    label: '四半期の売上数の遷移',
                    data: [120, 190, 34, 58],
                  },
                ],
              },
            });
          });
        },
      }).mount('#app');
    </script>
  </body>
</html>

クリックイベントによるグラフ描写

ただグラフを描写するだけならはVue.jsを使う必要がないので、ページに動きを出すためにVue.jsのクリックイベントでグラフが描写できるように変更します。ライフサイクルフックのmountedを削除して、新たにmethodsを追加しdispalyGraphを追加します。


const { createApp } = Vue;

createApp({
  methods: {
    displayGraph() {
      const ctx = document.getElementById('myChart').getContext('2d');
      new Chart(ctx, {
        type: 'line',
        data: {
          labels: ['2024年1月', '2024年2月', '2024年3月', '2024年4月'],
          datasets: [
            {
              label: '四半期の売上数の遷移',
              data: [120, 190, 34, 58],
            },
          ],
        },
      });
    },
  },
}).mount('#app');

ボタン要素を追加し、クリックイベントを設定します。クリックボタンを押すとdisplayGraphが実行されます。


<div id="app" style="width: 600px">
    <div>
    <button @click="displayGraph">グラフ表示</button>
    </div>
    <canvas id="myChart"></canvas>
</div>

ファイルを開くとグラフ表示ボタンのみ表示されます。

クリック用ボタンを追加
クリック用ボタンを追加
ボタンをクリックするとグラフが表示
ボタンをクリックするとグラフが表示

グラフ表示ボタンをクリックするとブラウザでグラフが描写されます。


  const { createApp } = Vue;

  createApp({
    setup() {
      const displayGraph = () => {
        const ctx = document.getElementById('myChart').getContext('2d');
        new Chart(ctx, {
          type: 'line',
          data: {
            labels: ['2024年1月', '2024年2月', '2024年3月', '2024年4月'],
            datasets: [
              {
                label: '四半期の売上数の遷移',
                data: [120, 190, 34, 58],
              },
            ],
          },
        });
      };
      return { displayGraph };
    },
  }).mount('#app');

データプロパティに値を設定

ここまではグラフに使っていた値をChartインスンスの引数のオブジェクトで指定していましが、外部からグラフに利用するデータを取得することを考えてデータプロパティを追加します。


createApp({
  data() {
    return {
      labels: ['2024年1月', '2024年2月', '2024年3月', '2024年4月'],
      data: [120, 190, 34, 58],
    };
  },
  methods: {
    displayGraph() {
      const ctx = document.getElementById('myChart').getContext('2d');
      new Chart(ctx, {
        type: 'line',
        data: {
          labels: this.labels,
          datasets: [
            {
              label: '四半期の売上数の遷移',
              data: this.data,
            },
          ],
        },
      });
    },
  },
}).mount('#app');

データプロパティに変更してもボタンをクリックすると何も影響はなく先ほどと同じグラフが描写できます。


const { createApp, ref } = Vue;

createApp({
  setup() {
    let labels = ref([
      '2024年1月',
      '2024年2月',
      '2024年3月',
      '2024年4月',
    ]);
    let data = ref([120, 190, 34, 58]);

    const displayGraph = () => {
      const ctx = document.getElementById('myChart').getContext('2d');
      new Chart(ctx, {
        type: 'line',
        data: {
          labels: labels.value,
          datasets: [
            {
              label: '四半期の売上数の遷移',
              data: data.value,
            },
          ],
        },
      });
    };
    return { displayGraph };
  },
}).mount('#app');

Chart.js + vue.js + axiosでグラフを描く

axiosから取得したデータをどのようにVue.jsのデータプロパティに反映されるかを確認して、グラフを描写します。

axiosによる情報の取得

axiosを使ってサーバから情報を取得します。冒頭でも説明した通り、axiosを利用してデータを取得できるサーバ環境を事前に準備しておく必要があります。

axiosを利用するためscriptタグを追加します。


<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

axiosの使用方法については下記を参考にしてください。

本文書ではLaravelサーバを準備しており/api/saleにアクセスすると以下の情報が取得できます。


0: {month: "2024年1月", number: 120}
1: {month: "2024年2月", number: 190}
2: {month: "2024年3月", number: 34}
3: {month: "2024年4月", number: 58}

axiosを利用して取得したデータでグラフ

vue.jsのライフサイクルフックのmounted完了後 にサーバからデータを取得しデータプロパティの中にaxiosを利用して取得してきたデータを入れます。mapメソッドを利用することでthis.dataには、[‘2024年1月’, ‘2024年2月’, ‘2024年3月’, ‘2024年4月’]が保存されます。


mounted() {
    axios.get('/api/design_sum').then((response) => {
    this.data = response.data.map((sale) => sale.number);
    this.labels = response.data.map((sale) => sale.month);

    this.displayGraph();
    });
},

ページを開くと下記のように表示されます。axiosでデータを取得できる環境さえあれば簡単にChart.jsとvue.jsとaxiosを使ってグラフを描写することができます。

バックエンドから取得したデータを利用して描写したデータ
バックエンドから取得したデータを利用して描写したデータ

動作確認したコードは下記の通りです。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Chart.js+Vue.js+Axios</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app" style="width: 600px">
      <canvas id="myChart"></canvas>
    </div>
    <script>
      const { createApp } = Vue;

      createApp({
        data() {
          return {
            labels: [],
            data: [],
          };
        },
        methods: {
          displayGraph() {
            const ctx = document.getElementById('myChart').getContext('2d');
            new Chart(ctx, {
              type: 'line',
              data: {
                labels: this.labels,
                datasets: [
                  {
                    label: '四半期の売上数の遷移',
                    data: this.data,
                  },
                ],
              },
            });
          },
        },
        mounted() {
          axios.get('/api/design_sum').then((response) => {
            this.data = response.data.map((sale) => sale.number);
            this.labels = response.data.map((sale) => sale.month);

            this.displayGraph();
          });
        },
      }).mount('#app');
    </script>
  </body>
</html>