Vue.js初心者お勉強-その3- chart.jsによるグラフ表示

## 前回までのおさらい

[2つ前の記事](https://qiita.com/teraco/items/3dafff7b99065c81303e)で「こういう方針で勉強します」打ち出したのがこれ↓

1. vue.jsのチュートリアル
2. firebase + vue.jsで触ってみる
3. node.jsのチュートリアル
4. これを理解した上でfirebase + vue.js + node.jsで触ってみる
5. JavaScriptのチュートリアル
6. これを理解した上でfirebase + vue.js + node.js + JavaScriptで触ってみる

イメージ図は以下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/7c622168-0df1-a3da-65f5-472a58c7d0fb.png)

上位レイヤの技術をある程度触ってから、下位レイヤの技術に触れ、さらに上位レイヤでできる事を増やす…というやり方。

しかし、Vue.js単体とFirebaseを触ったところ、

- node.jsとJavaScriptがかなり隠蔽されている
- node.jsとJavaScriptを体系的に勉強しなくても、作りたいものが作れそう

ということで、やりたい事中心に勉強していきます(詰まったら部分部分で勉強していく)

## やりたいこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/5d5b2e89-27e3-5021-2d39-ee9a6c1cbff4.png)

※ 黒文字部分がバックエンド、青文字部分がフロントエンド。赤丸部分が今回のフロントエンドのコア

図が汚すぎるだろ、ってのは置いといて**とあるサイトの情報を取得した結果をグラフに出す**をやりたいです。バックエンドの仕組みはほぼできているので、このQiitaの一連の記事ではVue.jsを使ってフロントエンドの仕組みを作っています。

ちなみにこれだけならWordPress立ててGoogleグラフなどのサービスを埋め込めば完成ですが、

- 勉強目的
- サービス使うよりも表現の自由度高そう
- ログイン機能などをつけて拡張性高くできそう

という期待でやっています。

## 勉強プラン

- (済)Vue.js単体
- (済)Vue.js + Firebase

予定していた勉強の触りは終わってしまいました。各プロダクトについてさらに深堀してもいいですが、目的なく勉強するのはつらいので、いったんサービスの完成を目指して歩みを進めていきます。なのでやる事は

- Vue.jsでのグラフ表示(chart.js)

です。

## Vue.js + chart.js = vue-chartjs

一番有名なグラフ表示用ライブラリがchart.jsということで、ひとまずこれを使ってやってみます。

参考にした記事はこちら。

1. [Vue.jsでカッコいいグラフを手軽に作るChart.jsのラッパー3つ - WPJ](https://www.webprofessional.jp/creating-beautiful-charts-vue-chart-js/)
2. [Vue.js + Chart.js でグラフを作成してみました - もぐもぐプログラミング](https://mmtomitomimm.blogspot.com/2018/12/vuejs-chartjs.html)
3. [vue-chartjs馴れ初め - Qiita](https://qiita.com/muramasawani/items/6086ecfcb92034774599)

1の記事は、2の記事を写経したものですが、少し誤字があるので、両方の記事を見ていきます。3の記事はシンプルで分かりやすいですので参考まで。

また1,2の記事中では折れ線、棒グラフ、バブルチャート、動的チャートの4つを表示していますが、ここでは折れ線と棒グラフの2つだけを作成することにします。なお、今回私も写経しましたが、意味も分からず写経しているところがあるので、それは正直にこの記事中に書いていきます。

### chart.jsのインストール

vue-chartjsに加えて、chartjsのインストールも必要です。

```
npm install vue-chartjs chart.js
```

### Bulma(CSSフレームワーク)を追加

写経通りに追加します。名前くらいは聞いたことがありますが、(CDN版が公開されているので)こんな簡単に追加できるのですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/75d55872-47c1-534c-a945-2b47f71139df.png)

### TOPページ用のHome.vueとグラフ表示画面用のVueChartJS.vueを追加

src/components配下にHome.vueとVueChartJS.vueを追加します。ひとまず空でOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/5715f1c1-cf59-eab3-a2c9-e9c0768246e3.png)

こいつらはブラウザから直接表示させるようのページなので、router/index.jsも編集します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/0500a95f-72a8-2635-3b69-ce9305b95a89.png)

### TOPページ用のHome.vueとグラフ表示画面用のVueChartJS.vueの中身を記載。

HTMLを書いていきます。Home.vueは特に語ることないですが、VueChartJS.vueはこのステップの後も継続的に編集していきます。

```vuejs: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: 'HelloWorld',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App(Hoge)',
    };
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<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>
```

```vuejs:VueChartJS.vue
<template>
  <section class="container">
    <ul>
      <li><router-link to="/Home">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>
  </section>
</template>

<script>
</script>

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

この時点だとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/b4527ab2-b98a-916b-3493-bb1953737981.png)


### 折れ線グラフの追加

ここからが本題で、グラフ表示用ページに折れ線グラフを表示します。ざっくりやる事を記載。

#### 折れ線グラフ表示用のコンポーネントを作成

src/components配下にグラフ表示用のLineChartJS.vueを作成します。

```vuejs: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のscript領域より、LineChartJS.vueを指定して呼び出します。

##### 編集前

```vuejs:LineChartJS.vue
<script>
</script>
```

##### 編集後

```vuejs:LineChartJS.vue
<script>
import LineChart from '@/components/LineChart'
export default {
  name: 'VueChartJS',
  components: {
    LineChart
  },
}
</script>
```

#### グラフ表示用コンポーネントに、折れ線グラフを表示

VueChartJS.vueのHTML領域に折れ線グラフを表示します。これはVueChartJS.vue内に

```vuejs:VueChartJS.vue
<line-chart></line-chart>
```

と記載することで、呼び出すことができます。

```vuejs:VueChartJS.vue
<template>
  <section class="container">
    <ul>
      <li><router-link to="/Home">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>
          <line-chart></line-chart>
      </div>
      <div class="column">
        <h3>Bar chart</h3>
      </div>
    </div>
  </section>
</template>
```

結果、呼び出しに成功しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/8140d7a2-e66f-c284-3e04-a270f5f86b51.png)

折れ線グラフも同じ方法で実装します。最終的なVueChartJS.vueはこちら。

```vuejs:VueChartJS.vue
<template>
  <section class="container">
    <ul>
      <li><router-link to="/Home">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>
          <line-chart></line-chart>
      </div>
      <div class="column">
        <h3>Bar chart</h3>
          <bar-chart></bar-chart>
      </div>
    </div>
  </section>
</template>

<script>
import LineChart from '@/components/LineChart'
import BarChart from '@/components/BarChart'
export default {
  name: 'VueChartJS',
  components: {
    LineChart,
    BarChart
  },
}
</script>

<style scoped>
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/5549127b-34b0-68cf-0e6a-99f2afb5be4f.png)

## よくわからない事

なぜ、

```vuejs:VueChartJS.vue
<line-chart></line-chart>
```

を指定するとグラフが呼び出せるのか。どうやら、下の赤丸で囲んだ名前がリンクして動作しているようなのですが、それならなぜ

```vuejs:VueChartJS.vue
<LineChart></LineChart>
```

と書かないのか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/ccc8ed21-f7cc-145f-a062-f8c3a6434639.png)

…と思って、

```vuejs:VueChartJS.vue
<LineChart></LineChart>
```

で書いたらこれでも呼び出せました。どちらでも動作するけど、文化的に

```vuejs:VueChartJS.vue
<line-chart></line-chart>
```

と書くものなのでしょうか。ちょっと分かりませんな。

## 今後の予定メモ

- フロントエンド
    - (済)Vue.jsでのグラフ表示(chart.js)
    - 実際に利用予定のデータを投入し、グラフ表示
    - chart.jsを使っていろいろと表示してみる：[Chart.js samples](https://www.chartjs.org/samples/latest/)
    - Vue.js側でボタン切り替えで、さまざまな表示方法でグラフを表示する
        - グラフの期間指定
        - グラフの個数指定
- バックエンド
    - 手元に用意したデータをデータベースに投入する
    - 新規取得したデータをデータベースに追加する
- フロントエンド + バックエンド
    - バックエンドに保管したデータをフロントエンドから呼び出す
        - データの更新頻度が少ない + Read専用なので、静的に持たせて表示させる構成にするかも