Laravel中如何向Chart.js传递数据?图表不显示问题解决
解决Laravel控制器向Chart.js传递数据无显示的问题
当前问题分析
你的代码存在几个关键问题导致Chart无法正常渲染:
- JavaScript语法错误:脚本中
{!!$plumbing!!}g多了字母g,直接导致JS解析失败,Chart无法初始化。 - 数据变量与分类不匹配:控制器中变量名和查询的分类完全错位,比如
$pest变量实际查询的是Plumbing System分类,$plumbing查询的是Pest Infectations,导致数据对应错误。 - 潜在的加载顺序问题:如果Chart.js库在你的自定义脚本之后加载,或者脚本在DOM未就绪时执行,也会导致Canvas元素无法被找到。
分步修正方案
1. 修正控制器的变量与数据对应
将控制器中变量名和查询的category匹配,确保数据准确:
public function ViewAnalytic(){ $id = Auth::user()->id; // 变量名与查询分类一一对应 $electrical = DB::table('maintenances') ->where('landlord_id', $id) ->where('category', 'Electrical System') ->count(); $plumbing = DB::table('maintenances') ->where('landlord_id', $id) ->where('category', 'Plumbing System') ->count(); $pest = DB::table('maintenances') ->where('landlord_id', $id) ->where('category', 'Pest Infectations') ->count(); $structural = DB::table('maintenances') ->where('landlord_id', $id) ->where('category', 'Structural Repairs') ->count(); $appliances = DB::table('maintenances') ->where('landlord_id', $id) ->where('category', 'Electrical Appliances') ->count(); $others = DB::table('maintenances') ->where('landlord_id', $id) ->where('category', 'Others') ->count(); return view('analytic.analytic-page', compact( 'total_num', 'vacant', 'rented', 'user', 'paid', 'unpaid', 'electrical', 'plumbing', 'pest', 'structural', 'appliances', 'others' )); }
2. 修正脚本的语法错误并确保加载顺序
首先确保在自定义脚本之前引入Chart.js库,比如在视图的<head>或脚本前添加:
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
然后修正脚本中的语法错误,并确保在DOM就绪后初始化Chart:
<div class="card-body px-3 py-4-5"> <canvas id="myChart" width="200" height="200"></canvas> </div> <script> // 等待DOM加载完成后执行 document.addEventListener('DOMContentLoaded', function() { const data = { labels: [ 'Electrical System', 'Plumbing System', 'Pest Infections', 'Structural Repairs', 'Electrical Appliances', 'Others' ], datasets: [{ label: 'Maintenance Requests by Category', // 去掉多余的g,确保每个值都是数字 data: [{!! $electrical !!}, {!! $plumbing !!}, {!! $pest !!}, {!! $structural !!}, {!! $appliances !!}, {!! $others !!}], backgroundColor: [ 'rgb(255, 99, 132)', 'rgb(204, 102, 235)', 'rgb(255, 205, 86)', 'rgb(0, 204, 102)', 'rgb(102, 153, 255)', 'rgb(191, 0, 205)' ], hoverOffset: 4 }] }; const ctx = document.getElementById('myChart').getContext('2d'); new Chart(ctx, { type: 'pie', data: data, }); }); </script>
Laravel向Chart.js传递数据的正确方式
除了直接用{!! !!}输出变量,更推荐将数据打包成数组后用json_encode传递,这样更安全且避免语法错误:
优化方案:使用JSON传递数据
在控制器中打包数据:
public function ViewAnalytic(){ $id = Auth::user()->id; // 打包成关联数组 $maintenanceData = [ 'labels' => [ 'Electrical System', 'Plumbing System', 'Pest Infectations', 'Structural Repairs', 'Electrical Appliances', 'Others' ], 'values' => [ DB::table('maintenances')->where('landlord_id', $id)->where('category', 'Electrical System')->count(), DB::table('maintenances')->where('landlord_id', $id)->where('category', 'Plumbing System')->count(), DB::table('maintenances')->where('landlord_id', $id)->where('category', 'Pest Infectations')->count(), DB::table('maintenances')->where('landlord_id', $id)->where('category', 'Structural Repairs')->count(), DB::table('maintenances')->where('landlord_id', $id)->where('category', 'Electrical Appliances')->count(), DB::table('maintenances')->where('landlord_id', $id)->where('category', 'Others')->count(), ] ]; return view('analytic.analytic-page', compact( 'total_num', 'vacant', 'rented', 'user', 'paid', 'unpaid', 'maintenanceData' )); }
然后在视图中直接解析JSON:
<script> document.addEventListener('DOMContentLoaded', function() { const maintenanceData = {!! json_encode($maintenanceData) !!}; const data = { labels: maintenanceData.labels, datasets: [{ label: 'Maintenance Requests by Category', data: maintenanceData.values, backgroundColor: [ 'rgb(255, 99, 132)', 'rgb(204, 102, 235)', 'rgb(255, 205, 86)', 'rgb(0, 204, 102)', 'rgb(102, 153, 255)', 'rgb(191, 0, 205)' ], hoverOffset: 4 }] }; const ctx = document.getElementById('myChart').getContext('2d'); new Chart(ctx, { type: 'pie', data: data, }); }); </script>
这种方式的优势在于:
- 避免单个变量传递的繁琐,尤其数据量较大时更清晰;
json_encode会自动处理数据格式,避免JS语法错误;- 代码更整洁,便于维护。
内容的提问来源于stack exchange,提问作者Wesley
相关产品推荐
相关产品推荐

