vuejs(ts) でグラフ(chartjs)を表示してみよう

vuejs(ts) でグラフ(chartjs)を表示してみよう
世の中にはデータを渡せばグラフ(チャート)を描画してくれるjsっていう便利なものがありまして、chartjs, D3, google chart, TradingViewなどいろいろあります。
今回はお手軽っぽい`chartjs`を`vue-chartjs`を利用して試してみました。

- https://vue-chartjs.org/
- https://www.chartjs.org/

# 適当にvueにサンプルを作ります。

今回はtypescriptを使うようにcreateしています。

```zsh
~/tmp/chartjs/tekitou master
❯ node --version
v11.10.0


~/tmp/chartjs/tekitou master
❯ cat package.json
{
  "name": "tekitou",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "vue": "^2.6.6",
    "vue-class-component": "^6.0.0",
    "vue-property-decorator": "^8.0.0",
    "vue-router": "^3.0.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-typescript": "^3.5.0",
    "@vue/cli-service": "^3.5.0",
    "typescript": "^3.2.1",
    "vue-template-compiler": "^2.5.21"
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

```

# vue-chartjsを入れます。

chart.jsも入れないといけないのでご注意を。
特に理由がなければvue-chartjsを利用して良いかと思います。

```zsh
❯ npm install vue-chartjs chart.js
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ chart.js@2.8.0
+ vue-chartjs@3.4.2
added 6 packages from 10 contributors and audited 21138 packages in 5.047s
found 0 vulnerabilities
```

おっと。@typesも必要ですね。

```
❯ npm install @types/chart.js -D
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ @types/chart.js@2.7.50
added 1 package from 14 contributors and audited 21139 packages in 4.805s
found 0 vulnerabilities

```

# チャート用のコンポーネントをHomeに追加します。

Home.vueに余計なことはせずにミニマムに追加してみます。
`<TekitouChartComponent>` ってのを追加しました。
でかくなってしまうので横幅をstyleで当てちゃいました。

```typescript:@/views/Home.vue
<template>
  <div class="home">
ここいらにどうでもよいチャートを表示しましょう。
<TekitouChartComponent style="width:360px;"></TekitouChartComponent>
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
import TekitouChartComponent from '@/components/TekitouChartComponent.vue';

@Component({
  components: {
    HelloWorld,
    TekitouChartComponent
  },
})
export default class Home extends Vue {}
</script>
```

# TekitouChartComponentを作ります。

親コンポーネントからchartDataとchartOptionsでデータを渡して、this.renderChartでchartjsにデータを渡す感じになります。

```typescript:@/components/TekitouChartComponent.vue
<script lang="ts">
import { Component, Mixins } from "vue-property-decorator";
import Chart from "chart.js";
import { Line, mixins } from "vue-chartjs";

@Component({})
export default class LineChartComponent extends Mixins(Line, mixins.reactiveProp) {
  // グラフ用のデータ
  private chartData: Chart.ChartData = {
    labels: ["1月", "2月", "3月", "4月", "5月"],
    datasets: [
      {
        type: "line",
        label: "花粉だめーじ",
        data: [20, 10, 30, 40, 30, 20],
        fill: true,
        borderColor: "#AAFFAA"
      }
    ]
  };

  // 表示オプションなど(今回は空
  private chartOptions: Chart.ChartOptions;

  public mounted() {
    this.renderChart(this.chartData, this.chartOptions);
  }
}
</script>
```

これでとりあえずグラフがでます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56925/f8910cc1-7652-b22a-0bc2-1542c5b4f4e6.png)



# でもこれだと。。。

実際に使うとなるとサーバとかからデータを取ってきてコンポーネントに渡すのが一般的になるので、Propで渡す感じになります。
(dev consoleでwarningの嵐です！)

1. HomeComponent から TekitouComponent呼びだす。
2. TekitouComponentでデータ取得
3. ChartComponentにPropでデータを渡す

ってのが正解です。

# まとめ

- `extends Mixins(Line, mixins.reactiveProp)` renderChart にデータとオプションを渡す。
- `chartData`に決まった型で値を渡す。labelsとdatasets
- datasetsは複数いれたりできる。
- グラフの種類も事足りる。

ということで、そんなに役にも立たない記事ですが、chartjsを試してみました。
とりあえずグラフを出したいよっていうニーズには答えてくれるかと。逆に3Dでぐりぐり動かしたい！とかっていう用途には合わないかな。
今回はVueじゃなくてもよかった。
Angularのときはd3-sharpを使ったなぁ。https://github.com/d3/d3-shape

# 補足

- D3はSVG,chartjsはcanvasを使うみたいです。
- D3はチャートだけではなくてもはや図を表示するライブラリですね。
- TradingViewはトレードに特化していて強いみたいです。ろうそくとかそーいうのが出ちゃうんだぞ。

- https://vue-chartjs.org/
- https://www.chartjs.org/

- https://d3js.org/
- https://github.com/tradingview
- https://developers.google.com/chart/