BETA

Laravel6+Vue.jsの環境でvue-chart.jsを使う(2)

投稿日:2020-02-08
最終更新:2020-02-08

Laravel6+Vue.jsの環境でvue-chart.jsを使うの続き。前回は固定データでのチャート作成でしたが、今回はControllerから受け取ったデータをオブジェクトとしてvue-chart.jsに渡してチャートを描画する、をやっていこうと思います。

先に完成後のコードを添付し、その後、解説です。

チャート表示時のページ

全体コード

Route

Route::get('/', '[email protected]');  

Controller

<?php  

namespace App\Http\Controllers;  

use Illuminate\Http\Request;  

class DebugController extends Controller  
{  
    public function index()  
    {  
        // chart_dataはオブジェクト形式でvue-chart.jsに渡すため、json化する   
        $data = [  
            'chart_data' => json_encode([  
                'labels' => [1,2,3,4,5],  
                'datasets' => array([  
                    'label' => 'チャート1',  
                    'data' => [500,25,250,300,100],  
                    'borderColor' => 'rgba(75,192,192,1)',  
                    'backgroundColor' => 'rgba(0, 0, 0, 0)',  
                    'pointBackgroundColor' => 'rgba(75,192,192,1)',  
                    'pointHitRadius' => 10  
                ],[  
                    'label' => 'チャート2',  
                    'data' => [1,10,50,100,200],  
                    'borderColor' => '#006400',  
                    'backgroundColor' => 'rgba(0, 0, 0, 0)',  
                    'pointBackgroundColor' => '#006400',  
                    'pointHitRadius' => 10  
                ])]),  
                'msg' => 'チャート描画準備完了。表示します!'  
        ];  
        return view('debug.index', $data);  
    }  
}  

※説明簡素化のため、今回はModelは使いません。

Blade

<!DOCTYPE html>  
<html lang="ja">  
<head>  
    <title>Index</title>  
    <link href="{{ mix('css/app.css') }}" rel="stylesheet" type="text/css">  
    <meta name="csrf-token" content="{{ csrf_token() }}">  
</head>  
<body>  
    <h1>チャートテストページ</h1>  
    <p>{{ $msg }}</p>  
    <div id="app" style="width:50%">  
        <line-chart :chart-data="{{ $chart_data }}"></line-chart>  
    </div>  

<script src="{{ mix('js/app.js') }}"></script>  
</body>  
</html>  

Vue

<script>  
import { Line } from 'vue-chartjs'  

export default {  
    extends: Line,  
    props: {  
        chartData:{  
            type: Object,  
            default: null  
        }  
    },  
    data: () => ({  
       options: {  
            responsive: true,  
            maintainAspectRatio: false,  
            scales: {  
                yAxes: [{  
                    display:true,  
                    scaleLabel: {  
                        display: true,  
                        labelString: 'たて'  
                    },  
                    ticks: {  
                        beginAtZero: true,  
                        suggestedMin: 0,  
                        suggestedMax: 90  
                    }  
                }],  
                xAxes: [{  
                    display:true,  
                    scaleLabel: {  
                        display: true,  
                        labelString: 'よこ'  
                    },  
                }]  
            }  
        }  
    }),  
    mounted(){  
        this.renderChart(this.chartData, this.options)  
    }  
}  
</script>  

app.js

Vue.component('line-chart', require('./components/LineChart.vue').default);  

解説

1. ControllerからBladeにデータを渡す。

Controllerに書いた下記の部分です。

$data = [  
    'chart_data' => json_encode([  
        'labels' => [1,2,3,4,5],  
        'datasets' => array([  
            'label' => 'チャート1',  
            'data' => [500,25,250,300,100],  
            'borderColor' => 'rgba(75,192,192,1)',  
            'backgroundColor' => 'rgba(0, 0, 0, 0)',  
            'pointBackgroundColor' => 'rgba(75,192,192,1)',  
            'pointHitRadius' => 10  
        ],[  
            'label' => 'チャート2',  
            'data' => [1,10,50,100,200],  
            'borderColor' => '#006400',  
            'backgroundColor' => 'rgba(0, 0, 0, 0)',  
            'pointBackgroundColor' => '#006400',  
            'pointHitRadius' => 10  
        ])]),  
        'msg' => 'チャート描画準備完了。表示します!'  
];  
return view('debug.index', $data);  

ここでは、
・チャート描画に必要なチャートのデータ(今回は2本分のチャートのデータ)とチャートラベルをchart_dataに。
・メッセージ情報をmsgに。
入れて、Bladeに渡してます。(msgは無くても良い。)

json_encodeしている理由は、Vue側で、チャート描画のためのインプットのデータを、オブジェクトとして受け取りたいからです。配列にして渡すと、配列の中身それぞれをvue-chartのパラメーターに入力し直さないといけなくなりコードが長くなりそうなのでオブジェクトとしてそのまま渡すため、ここでjson化しておきます。

2. BladeからVueに渡す。

Bladeに書いた下記の部分です。

<line-chart :chart-data="{{ $chart_data }}"></line-chart>  

v-bindの省略記法を使いながら、Controllerから受け取った$chart_dataをchart-dataに入れます。変数の記法はハイフンを使うケバブケースにする必要があります。→chart-data

3. Vueコンポーネント内で受け取る

Vueに書いた下記の部分です。

props: {  
    chartData:{  
        type: Object,  
        default: null  
    }  

propsの中に書くことでBladeからの値を受け取ります。なお、受け取る時は区切りの文字が大文字となるキャメル記法にする必要があります。→chartData

4. vue-chartのレンダーメソッドの引数に当てる。

Vueに書いた下記の部分です。

mounted(){  
    this.renderChart(this.chartData, this.options)  
}  

thisで自身を指すのでthis.chartDataとして代入します。

※optionsについては今回は固定にしましたが、chartdata同様にコントローラーから持ってきて代入できるはずです。なおoptionsで指定したパラメータは自作アプリの方からそのまま持ってきているので、今回のテストレベルでは不要なのも混じっているかもしれません。

※vueには<template>の記述を入れていませんが、vue-chart.jsの公式ガイドに下記の記述があるためです。

5. npm run devを実行する。

npm run devを実行して、ページを確認しに行くと、最初に示したようなチャートが表示されます。

おわり

公式ガイドのvue-chart.js(propsを使用したチャート)を参考に作りました。
初心者の自分としては、このガイドを初めて見た時に、LaravelからVue.jsにどうやってデータを渡せば良いんだろう?Objectとして渡すには?で悩んだことがあったので記事にしました。

そもそものvueを理解せずにいきなりvue-chart.jsで作ろうとして1回挫折して、vueを使わないchart.jsに逃げてたんですが、vue-chart.jsでも同じチャートを作れるようになれて良かったです。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

あろはの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう