Vue.js + Chart.js でグラフを作成してみました


Javascript のフレームワークである Vue.js でグラフを作成したいと思ってたところ、vue-chartjs という便利なライブラリがあるようだったので、実際に使って試してみました。


*今回作成するもの

















*参考



*環境

  • MacOS
  • vue-cli 2.9.6
  • vue-chartjs 3.4.0


*プロジェクト作成

Vue.js でアプリを構築する際は、 vue-cli を使うと簡単に雛形を作成することができます。この便利ツールである vue-cli を使ってプロジェクトを作成したいのでインストールします。
$ sudo npm install -g vue-cli

下記コマンドを実行して Vueプロジェクトを作成します。
プロジェクト名やテストの設定などを質問されますが、今回は基本的にデフォルトのまま Enter か Yes にしました。実際は自分の必要な設定のみで大丈夫です。
$ vue init webpack vue-project

? Project name vue-project
? Project description A Vue.js project
? Author XXXXX
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm

作成したディレクトリに移動します。
下記コマンドを実行してアプリケーションを起動します。
$ cd vue-project/
$ npm run dev

ビルドが正常に完了したら下記URLにアクセスします。
Vue の画面が表示されます。
http://localhost:8080














*Chartライブラリをインストール

下記コマンドを実行してライブラリをインストールします。
今回は vue-chartjs しか使いませんが、念のため他のライブラリもインストールしました。
$ npm install chart.js chartkick hchs-vue-charts vue-chartjs vue-chartkick

+ chart.js@2.7.3
+ vue-chartjs@3.4.0
+ vue-chartkick@0.5.0
+ hchs-vue-charts@1.2.8
+ chartkick@3.0.1


*CSSフレームワークを追加

CSSフレームワークであるBulmaを追加しました。
プロジェクトフォルダ直下にあるindex.htmlに下記を追加します。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue-project</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css">    <-- 追加
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


*ルートを追加

今回は4種類のグラフを作成するので、そのグラフごとにファイルを分けます。
src/componentsに下記ファイルを作成します。中身はまだ空っぽの状態です。
  • Home.vue     <-- 初期画面
  • VueChartJS.vue  <-- グラフ4種類を表示する画面
  • LineChart.vue   <-- VueChartJS.vue の中の折れ線グラフ
  • BarChart.vue   <-- VueChartJS.vue の中の棒グラフ
  • BubbleChart.vue  <-- VueChartJS.vue の中のバブルチャート
  • Reactive.vue    <-- VueChartJS.vue の中のリアクティブな折れ線グラフ

画面を追加したので、その画面にアクセスするためのURLとなるルートを/src/router/index.js に追加します。mode: 'history'の設定がないとURLにシャープ(#)が含まれてしまうので追加が必要です。
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import VueChartJS from '@/components/VueChartJS'
import VueChartKick from '@/components/VueChartKick'
import VueCharts from '@/components/VueCharts'

Vue.use(Router)

export default new Router({
  mode: 'history',    <-- 追加
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      <!-- 追加 -->
      path: '/chartjs',
      name: 'VueChartJS',
      component: VueChartJS
    }
  ]
})


*ホーム画面を作成

Home.vue を下記に編集します。
グラフを表示する画面へのリンクがある初期表示用の画面です。
<template>
  <section class="hero">
    <div class="hero-body">
      <div class="container">
        <h1>Creating Beautiful Charts Using Vue.js Wrappers For Chart.js</h1>
        <ul>
          <li><router-link to="/chartjs">vue-chartjs</router-link></li>
        </ul>
      </div>
    </div>
  </section>
</template>

<script>
export default {
  name: 'home'
}
</script>

<style scoped>
.hero {
  width: 100%;
  height: 10%;
}
.container {
  display: flex;
  align-items: center;
  align-content: center;
  justify-content: center;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
</style>












*チャート画面を作成

グラフ4種類を表示する画面を作成します。
VueChartJS.vue を下記に編集します。まだグラフは描画されていない状態です。
<template>
  <section class="container">
    <ul>
      <li><router-link to="/">Home</router-link></li>
      <li><router-link to="/chartjs">vue-chartjs</router-link></li>
    </ul>
    <h1>Demo examples of vue-chartjs</h1>
    <div class="columns">
      <div class="column">
        <h3>Line Chart</h3>
      </div>
      <div class="column">
        <h3>Bar Chart</h3>
      </div>
    </div>
    <div class="columns">
      <div class="column">
        <h3>Bubble Chart</h3>
      </div>
      <div class="column">
        <h3>Reactivity - Live update upon change in datasets</h3>
      </div>
    </div>
  </section>
</template>
<script>
import LineChart from '@/components/LineChart'
import BarChart from '@/components/BarChart'
import BubbleChart from '@/components/BubbleChart'
import Reactive from '@/components/Reactive'

export default {
  name: 'VueChartJS',
  components: {
    LineChart,
    BarChart,
    BubbleChart,
    Reactive
  }
}
</script>

<style scoped>
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

下記URLにアクセスするか、ホーム画面のリンクをクリックするとチャート画面を表示することができます。
http://localhost:8080/chartjs











*折れ線グラフを作成

LineChartJS.vueを下記に編集します。
<script>
import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  props: ['data', 'options'],
  mounted () {
    this.renderChart({
      labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
      datasets: [
        {
          label: 'Data',
          backgroundColor: '#f87979',
          borderWidth: 1,
          data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11]
        }
      ]
    })
  }
}
</script>

<style scoped>
</style>

チャート画面にグラフを表示させるため、VueChartJS.vue の Line Chart の部分に<line-chart></line-chart>を追加します。この記述によってLineChart.vueが差し込まれます。
      <div class="column">
        <h3>Line Chart</h3>
        <line-chart></line-chart>   <-- 追加
      </div>

チャート画面に折れ線グラフが表示されます。



















*棒グラフを作成

BarChart.vueを下記に編集します。
<script>
import { Bar } from 'vue-chartjs'

export default {
  extends: Bar,
  mounted () {
    this.renderChart({
      labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
      datasets: [
        {
          label: 'Data',
          backgroundColor: '#7979f8',
          data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11]
        }
      ]
    })
  }
}
</script>

<style scoped>
</style>

VueChartJS.vue の Bar Chart の部分に<bar-chart></bar-chart>を追加します。
      <div class="column">
        <h3>Bar Chart</h3>
        <bar-chart></bar-chart>    <-- 追加
      </div>

チャート画面に棒グラフが表示されます。





















*バブルチャートを作成

BubbleChart.vueを下記に編集します。
<script>
import { Bubble } from 'vue-chartjs'

export default {
  extends: Bubble,
  mounted () {
    this.renderChart({
      labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
      datasets: [
        {
          label: 'Data',
          backgroundColor: '#79f8b9',
          data: [
            {
              x: 100,
              y: 0,
              r: 10
            },
            {
              x: 60,
              y: 30,
              r: 20
            },
            {
              x: 40,
              y: 60,
              r: 25
            },
            {
              x: 80,
              y: 80,
              r: 50
            },
            {
              x: 30,
              y: 100,
              r: 5
            }
          ]
        }
      ]
    })
  }
}
</script>

<style scoped>
</style>

VueChartJS.vue の Bubble Chart の部分に<bubble-chart></bubble-chart>を追加します。
      <div class="column">
        <h3>Bubble Chart</h3>
        <bubble-chart></bubble-chart>    <-- 追加
      </div>

チャート画面にバブルチャートが表示されます。





















*リアクティブ折れ線グラフを作成

Reactive.vueを下記に編集します。
VueChartJS.vueからchartData / optionsとして値を受け取って、その値をrenderChart()に渡すことによって再レンダリングして表示することができます。
<script>
import { Line, mixins } from 'vue-chartjs'

export default {
  extends: Line,
  mixins: [mixins.reactiveProp],
  props: ['chartData', 'options'],
  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}
</script>

<style scoped>
</style>

Reactive.vueに表示するためのデータをチャート画面で作成します。
VueChartJS.vueにランダムな値を作成するメソッドを追加します。
<script>
import LineChart from '@/components/LineChart'
import BarChart from '@/components/BarChart'
import BubbleChart from '@/components/BubbleChart'
import Reactive from '@/components/Reactive'

export default {
  name: 'VueChartJS',
  components: {
    LineChart,
    BarChart,
    BubbleChart,
    Reactive
  },
  <!-- ここから下を追加 -->
  data () {
    return {
      dataContents: null
    }
  },
  created () {
    this.fillData()
  },
  methods: {
    fillData () {
      this.dataContents = {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        datasets: [
          {
            label: 'Data reractive',
            backgroundColor: '#f8b979',
            data: [this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum(), this.getRandomNum()]
          }
        ]
      }
    },
    getRandomNum () {
      return Math.floor(Math.random() * (50 - 5 + 1)) + 5
    }
  }
}
</script>

Reactive.vueにデータを渡すための処理を html 部分に追加します。
また、再レンダリングするためのボタンも追加します。
      <div class="column">
        <h3>Reactivity - Live update upon change in datasets</h3>
        <reactive :chart-data="dataContents"></reactive>
        <button class="button is-primary" @click="fillData()">Ramdomize</button>
      </div>

ボタンを押すごとにデータが書き換えられます。




















*所感

Vue.js は書き方が簡単で日本語のドキュメントも充実していると実感はしていましたが、グラフ描画に便利なライブラリも用意されていたので非常に使いやすいフレームワークだと感じました。
リアクティブなグラフも簡単に作成することができたので、必要な場面で使っていきたいと思います。
また、他にも vue-chartkick などのライブラリがあるので試してみたいと思います。


1 Response to "Vue.js + Chart.js でグラフを作成してみました"