やりたいこと
すでにMySQLに入力されているデータの数をカウントして、円グラフとして表示させたい。
環境
Laravel8
MySQL
Google Charts
やりかた
ルーティング
routes/web.php
use App\Http\Controllers\RecordUsersController;
// ユーザー投稿の一覧表示画面
Route::get('/record/user/{user_id}', [RecordUsersController::class, 'show_by_user'])->name('show_by_user_record')->middleware('auth');
モデル
カウント対象のカラムのデータ型を文字列型に変えておく。
(今回はsumをTINYINTからTINYTEXTに変更した。)
コントローラー
これまでviewにユーザー名と一覧用のデータを渡していただけだったところに、グラフ用のデータもcompact()で渡す。
app/Http/Controllers/RecordUsersController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Record;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class RecordUsersController extends Controller
{
//
public function show_by_user($id)
{
$user = Auth::user();
$id = Auth::id();
$user = User::find($id);
$records = Record::where('user_id',$user->id)->sortable()->get();
$sum180 = Record::where('sum','180')->where('user_id',$user->id)->get()->count();
$sum150 = Record::where('sum','150')->where('user_id',$user->id)->get()->count();
$sum120 = Record::where('sum','120')->where('user_id',$user->id)->get()->count();
$sum90 = Record::where('sum','90')->where('user_id',$user->id)->get()->count();
$sum60 = Record::where('sum','60')->where('user_id',$user->id)->get()->count();
$sum30 = Record::where('sum','30')->where('user_id',$user->id)->get()->count();
$sum15 = Record::where('sum','15')->where('user_id',$user->id)->get()->count();
$sum0 = Record::where('sum','0')->where('user_id',$user->id)->get()->count(); //$sum180~$sum0に各ユーザーの学習時間を代入する
if($user->id == $id){
return view('record.showbyuser', [
'user_name' => $user->name,
'records' => $records,
], compact('sum180','sum150','sum120','sum90','sum60','sum30','sum15','sum0',));
}else{
/* \Session::flash('err_msg3','閲覧権限がありません'); */
return redirect('/login');
}
}
}
ビュー
今回はページ下部に<div id="chart">
と<script>
タグ部分を追記。
resources/views/record/showbyuser.blade.php
@extends('layouts.recordlayout')
@section('content')
<div class="container mt-4">
<div class="text-4xl mb-6 mt-6">
<p>{{ $user_name }}さんの投稿一覧</p>
</div>
@if(session('err_msg3'))
<p class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative">
{{ session('err_msg3') }}</p>
@endif
<table class="table-auto">
<tr class='text-xl bg-gray-100 container mx-auto leading-10'>
<th class="text-blue-500 px-8 mx-10">@sortablelink('id', '番号')</th>
<th class="text-blue-500 px-8 mx-10">@sortablelink('date', '日付')</th>
<th class="text-blue-500 px-8 mx-10">@sortablelink('subject', '科目')</th>
<th class="text-blue-500 px-8 mx-10">@sortablelink('sum', '時間')</th>
<th class="text-blue-500 px-8 mx-10">@sortablelink('updated_at', '更新日')</th>
<th></th>
<th></th>
</tr>
@foreach ($records as $record)
<tr class='text-lg container mx-auto leading-10'>
<td class="px-8 mx-10">{{ $record->id }}</td>
<td class="px-8 mx-10">{{ $record->date }}</td>
<td class="px-8 mx-10">{{ $record->subject }}</td>
<td class="px-8 mx-10">{{ $record->sum }}</td>
<td class="px-8 mx-10">{{ $record->updated_at }}</td>
<td><button type="button" class="shadow bg-purple-500
hover:bg-purple-400 focus:shadow-outline focus:outline-none
text-white font-bold py-2 px-4 rounded" onclick="location.href='/record/edit/{{ $record->id }}'">編集</button></td>
<form method="POST" action="{{ route('delete_record', $record->id) }}" onSubmit="return checkDelete()">
@csrf
<td><button type="submit" class="shadow bg-purple-500
hover:bg-purple-400 focus:shadow-outline focus:outline-none
text-white font-bold py-2 px-4 rounded" onclick=>削除</button></td>
</form>
</tr>
@endforeach
</table>
</div>
<div id="chart" style="height:500px;width:800px;"></div>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
var sum180 = <?php echo $sum180; ?>;
var sum150 = <?php echo $sum150; ?>;
var sum120 = <?php echo $sum120; ?>;
var sum90 = <?php echo $sum90; ?>;
var sum60 = <?php echo $sum60; ?>;
var sum30 = <?php echo $sum30; ?>;
var sum15 = <?php echo $sum15; ?>;
var sum0 = <?php echo $sum0; ?>;
google.charts.load('current', {packages: ['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart(){
var data=google.visualization.arrayToDataTable([
['sum','number',],
['180', sum180],
['150', sum150],
['120', sum120],
['90', sum90],
['60', sum60],
['30', sum30],
['15', sum15],
['0', sum0],
]);
var options ={
title: '学習時間の内訳',
is3D: true,
};
var chart = new google.visualization.PieChart(document.getElementById('chart'));
chart.draw(data, options);
}
</script>
@endsection
ハマったポイント
- arrayToDataTableに渡すデータを間違えるとグラフが表示されない(エラーは表示されない)。
- arrayToDataTableに渡す配列は要素が2つ以上必要。
- arrayToDataTableに渡す配列は1つめがstringじゃないとだめ。
- 2つめの要素は数値とし、この数値が変わることで円グラフが変化する。
- 2つめの要素をカウントするために
->count()
を使用する。