43
38

More than 5 years have passed since last update.

Vue.js(ts)でvue-chartjsを使う

Posted at

はじめに

今までJSで何かしらのグラフを描画する時に、「Chart.js」を利用していたので、Vue.jsでも同様に「Chart.js」を使っていたのですが、今更ながら「vue-chartjs」というものを知って、触ってみて、想像以上に便利なものだったので、勝手にこの感動を共有していこうと思います。

作ったデモ

こんな感じのものを作りました。
vue_chartjs_demo.gif
ソースコードはgithubにあげています。
https://github.com/ryo-is/vue-demo-sample

何がよかったか

色々ありますが特に伝えたい点は以下の3点。

  • 描画ロジック自体がコンポーネントで提供されているので、datasetsoptions を渡せばグラフ描画してくれる
  • datasets を更新すると、再描画してくれる
  • TypeScriptからでも使いやすいように、型宣言ファイルなど整備されている

どう実装したか

vue-chartjsコンポーネント

グラフ描画コンポーネントのScriptはこんな感じ

script
import { Component, Mixins, Prop } from "vue-property-decorator";
import Chart from "chart.js";
import { Line, Bar, mixins } from "vue-chartjs";

@Component({})
export default class LineChartComponent extends Mixins(Line, Bar, mixins.reactiveProp) {
  @Prop() public chartData: Chart.ChartData;
  @Prop() public chartOptions: Chart.ChartOptions;

  public mounted() {
    console.log(this);
    this.renderChart(this.chartData, this.chartOptions);
  }
}

今回は棒グラフ(Bar)と折れ線グラフ(Line)を使いたいので、Mixins を利用してextendsしていきます。
また mixins.reactiveProp をextendsすることで、Propが更新かかればグラフ再描画してくれるようになります。

親コンポーネント

親コンポーネントからPropで datasetsoptions を渡していきます。

template
.chart
  .title {{ chartTitle }}
  el-row
    .chart-area
      el-button.change-value-button(type="primary" @click="createChartData()") データ変更
      lineChartComponent(:chart-data="chartData", :chart-options="chartOptions")
script
import { Component, Vue } from "vue-property-decorator";
import lineChartComponent from "@/components/chart/VueChart.vue";
import Chart from "chart.js";

const FONT_COLOR = "rgba(255, 255, 255, 1)";
const GRID_LINES_SETTING = {
  display: true,
  drawOnChartArea: false,
  color: "rgba(255, 255, 255, .5)",
  zeroLineColor: "rgba(255, 255, 255, 1)"
};

@Component({
  components: {
    lineChartComponent
  }
})
export default class ChartComponent extends Vue {
  public chartTitle: string = "Vue Chartjs Demo";
  public chartData: Chart.ChartData = {};
  public chartOptions: Chart.ChartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    legend: {
      // display: false
      onClick(event, legendItem) {
        return;
      },
      fullWidth: false,
      labels: {
        boxWidth: 20,
        fontColor: FONT_COLOR
      },
    },
    layout: {
      padding: {
        top: 20,
        left: 20,
        bottom: 20,
        right: 20
      }
    },
    scales: {
      xAxes: [
        {
          gridLines: GRID_LINES_SETTING,
          ticks: {
            autoSkip: true,
            fontColor: FONT_COLOR,
            fontSize: 14
          },
          scaleLabel: {
            display: true,
            fontColor: FONT_COLOR,
            labelString: "",
          },
        },
      ],
      yAxes: [
        {
          id: "yAxis_1",
          type: "linear",
          gridLines: GRID_LINES_SETTING,
          scaleLabel: {
            display: true,
            fontColor: FONT_COLOR,
            labelString: "湿度(%)"
          },
          ticks: {
            autoSkip: true,
            fontColor: FONT_COLOR,
            fontSize: 14,
            min: 0,
            max: 100
          },
        },
        {
          id: "yAxis_2",
          type: "linear",
          gridLines: GRID_LINES_SETTING,
          scaleLabel: {
            display: true,
            fontColor: FONT_COLOR,
            labelString: "温度(℃)"
          },
          ticks: {
            autoSkip: true,
            fontColor: FONT_COLOR,
            fontSize: 14,
            min: 0,
            max: 40
          },
          position: "right"
        }
      ],
    }
  };

  public created() {
    this.createChartData();
  }

  public createChartData() {
    this.chartData = {
      labels: ["1", "2", "3", "4", "5"],
      datasets: [
        {
          yAxisID: "yAxis_1",
          type: "line",
          label: "湿度",
          backgroundColor: "#6090EF",
          borderColor: "#6090EF",
          fill: false,
          data: this.craeteRamdomValue(100)
        },
        {
          yAxisID: "yAxis_2",
          type: "bar",
          label: "温度",
          backgroundColor: "#F87979",
          borderColor: "#F87979",
          fill: false,
          data: this.craeteRamdomValue(40)
        }
      ]
    };
  }

  public craeteRamdomValue(baseNumber: number) {
    const arr: number[] = [];
    for (let i = 0; i < 5; i++) {
      arr.push(Math.floor(Math.random() * baseNumber));
    }
    return arr;
  }
}

なんとグラフを描画するのに必要なソースコードはこれだけです。
これでグラフの描画をしてくれます。

さいごに

今までなんで頑張って素のChart.jsを使っていたんだろう…と虚しくなるくらい、「vue-chartjs」は使い勝手が良いです。
もしVue.jsのアプリでグラフを描画したいなーという瞬間があれば、「vue-chartjs」おすすめです!
ではまた!!!

43
38
1

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
43
38