Gridsome入門 SPAを作ってみよう 【8日目 GraphQL編4】

# スケジュール
- [1日目 要件定義編](https://qiita.com/Dev-kenta/items/b5c8ea6b432fe3594282)
- [2日目 環境構築編](https://qiita.com/Dev-kenta/items/6ae251a648e04b9cf026)
- [3日目 ドーナッツグラフ編](https://qiita.com/Dev-kenta/items/9e141767c42deee743c8)
- [4日目 棒グラフ編](https://qiita.com/Dev-kenta/items/780c3cb4a4d0cf813824)
- [5日目 GraphQL編](https://qiita.com/Dev-kenta/items/1d08ef27aa877cfb6771)
- [6日目 GraphQL編2](https://qiita.com/Dev-kenta/items/e4281380da38f57495b6)
- [7日目 GraphQL編3](https://qiita.com/Dev-kenta/items/1bf6dc021ec08932233c)
- [8日目 GraphQL編4](https://qiita.com/Dev-kenta/items/fcc65b0106ba29626db7)←今ここ
- [9日目 デプロイ編](https://qiita.com/Dev-kenta/items/14ae9fdc6eec76f63ba1)

# 前提条件
- node.js v8.3以上
- yarn or npmが入っている(Document見るとyarnの方が推奨とのこと)
- Gridsomeのプロジェクトを作成している

# グラフの切り替え機能を追加

```graphql:src/pages/asset-transition/index.vue
query {
  transitionUsd: allTransitions(order:ASC) {
    edges {
      node {
        date
        asset_usd
      }
    }
  }
  transitionYen: allTransitions(order:ASC) {
    edges {
      node {
        date
        asset_yen
      }
    }
  }
}
```
新たにクエリを二つ用意します。

```vuejs:src/pages/asset-transition/index.vue
<template>
  <Layout>
    <h1>Asset transition</h1>
    <div class="switch">
      <input type="radio" id="usd" value="1" v-model="currency">
      <label for="usd">USD</label>
      <input type="radio" id="yen" value="2" v-model="currency">
      <label for="yen">円</label>
    </div>
    <bar v-show="showUsd" :currency="1" :labels="formatLabels($page.transitionUsd.edges)" :chartData="formatChartData($page.transitionUsd.edges, 1)"></bar>
    <bar v-show="!showUsd" :currency="2" :labels="formatLabels($page.transitionYen.edges)" :chartData="formatChartData($page.transitionYen.edges, 2)"></bar>
  </Layout>
</template>
<page-query>
query {
  transitionUsd: allTransitions(order:ASC) {
    edges {
      node {
        date
        asset_usd
      }
    }
  }
  transitionYen: allTransitions(order:ASC) {
    edges {
      node {
        date
        asset_yen
      }
    }
  }
}
</page-query>
<script>
import Bar from "../../components/chart/Bar";
export default {
  components: {
    Bar
  },
  data() {
    return {
      defaultCurrency: "1",
      showUsd: true
    }
  },
  methods: {
    formatLabels: function (labels) {
      return labels.map(item => item['node']['date']);
    },
    formatChartData: function (chartData, type) {
      return type == 1 ? chartData.map(item => item['node']['asset_usd']) : chartData.map(item => item['node']['asset_yen']);
    }
  },
  computed: {
    currency: {
      get () {
        return this.defaultCurrency;
      },
      set (value) {
        this.defaultCurrency = value;
        this.showUsd = value == 1 ? true : false;
      }
    }
  },
  metaInfo: {
    title: 'Hello, world!'
  }
}
</script>

<style>
.home-links a {
  margin-right: 1rem;
}
</style>
```

ラジオボタンを追加して、グラフの切り替え機能を追加します。
v-modelを使って選択した値を元にグラフの表示・非表示を切り替えています。
```get()```　と```set()```をcomputedで使うことによってv-modelと合わせてこういうことできるんですね。知らなかった。

```vuejs:src/components/chart/Bar.vue
<script>
import { Bar } from 'vue-chartjs'
export default {
  extends: Bar,
  name: 'bar',
  props: ['labels','chartData','currency'],
  data () {
    return {
      chartLabel: this.setGraphLabel(),
      options: {
        tooltips: {
          callbacks: {
            label: function(tooltipItem, data) {
              const currentData = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
              return this.currency == 1 ? '$' + currentData : currentData + '円';
            }.bind(this)
          }
        },
        scales: {
          yAxes: [
            {
              ticks: {
                min: 0,
                max: this.upperData()
              }
            }
          ]
        }
      }
    }
  },
  mounted () {
    this.renderChart(
        {
          labels: this.labels,
          datasets: [
            {
              backgroundColor: this.setGraphColor(),
              data: this.chartData,
              label: this.chartLabel,
            }
          ]
        },
        this.options)
  },
  methods: {
    upperData: function () {
      const maxData = Math.max.apply(null, this.chartData) * 1.2;
      return parseInt(maxData, 10);
    },
    setGraphLabel: function () {
      return this.currency == 1 ? 'Asset transition/USD' : 'Asset transition/円';
    },
    setGraphColor: function () {
      return this.currency == 1 ? 'rgba(137,255,255,1)' : 'rgba(221,238,170,1)';
    }
  }
}
</script>
```

次にグラフのcomponentで新たに追加した```currency```の値を元に、グラフのラベルや色を変える処理を追加しました。
```tooltips.callbacks.label```でthisでアクセスしようとして上手くいかずハマりました。。
原因はthisでアクセスしようとしたのがcomponent自体で無く、グラフ自体にアクセスしてしまっていたためでした。なので```.bind(this)```として渡してあげることでvueのcomponentにアクセスすることが出来ました。
こちらの記事が大変参考になりました。
https://tadaken3.hatenablog.jp/entry/vue-scope-this

# 出来上がったグラフがこちら
![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402204/d2067f3f-d27f-08c6-1b94-58a43207cf7d.gif)
グラフの切り替えができるようになりました。

# あとがき
長かった9連休も明日で終わり。
休み明けに普通に働けるかしらん。。

明日は最後なのでデプロイ編。AWS S3にデプロイしようかなと思いましたが、Netlifyの方がシンプルに出来そうなので迷い中。どうしよう。