0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-08-15

スケジュール

前提条件

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

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

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
      }
    }
  }
}

新たにクエリを二つ用意します。

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と合わせてこういうことできるんですね。知らなかった。

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
グラフの切り替えができるようになりました。

あとがき

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

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?