如何用折线图展示月度产品销量?图表无数据问题排查
问题:Laravel+Chart.js月度销量折线图无数据展示
我想用折线图展示产品月度销量,已编写Laravel后端代码获取销售数据:
$monthlySales = OrderProduct::selectRaw('sum(amount) as total_sales, month(created_at) as month, year(created_at) as year') ->groupBy('month', 'year') ->get(); $labels = $monthlySales->pluck('month')->toArray(); $data = $monthlySales->pluck('total_sales')->toArray();
前端使用Chart.js绘制折线图的代码:
var xValues = ['January','Febuary','March','April','May','June','July','August','September','October','November','December']; var yValues = [{{$data}}]; new Chart("myChart", { type: "line", data: { labels: xValues, datasets: [{ fill: false, lineTension: 0, backgroundColor: "rgba(0,0,255,1.0)", borderColor: "rgba(0,0,255,0.1)", data: yValues }] }, options: { legend: {display: false}, scales: { yAxes: [{ticks: {min: 0, max:{{$sales}}}}], } } });
尝试用for循环处理数据数组,但图表仍无可见数据,怀疑是数据库数据不足,或是代码存在问题?
问题分析与解决方案
核心问题点
- 数据格式错误:前端
yValues = [{{$data}}]会把PHP数组渲染成[[100,200,...]]这种二维数组,Chart.js仅支持一维数组作为数据源,导致无法识别。 - 缺失无销量月份数据:后端仅返回有销量的月份记录,比如1月、3月有数据,2月无数据时,
$data只有2个值,但前端x轴是12个月份,数据长度不匹配,图表无法正常渲染。 - 未限定年份范围:若数据库存在跨年数据,分组后会出现同月份不同年份的记录,导致数据逻辑混乱。
- 未定义变量报错:前端
max:{{$sales}}中的$sales变量后端未传递,会引发JS语法错误,阻断图表渲染。
修正后的后端代码
限定查询当前年份数据,并生成12个月的完整数据集,无销量月份填充0:
$currentYear = date('Y'); // 获取当前年各月销量,按月份作为键名 $monthlySales = OrderProduct::selectRaw('sum(amount) as total_sales, month(created_at) as month') ->whereYear('created_at', $currentYear) ->groupBy('month') ->pluck('total_sales', 'month') ->toArray(); // 生成1-12月的完整数据,无销量月份设为0 $data = []; for ($month = 1; $month <= 12; $month++) { $data[] = isset($monthlySales[$month]) ? $monthlySales[$month] : 0; } // 计算销量最大值,给y轴留10%余量避免数据顶到边界 $maxSales = max($data) > 0 ? max($data) * 1.1 : 10;
修正后的前端代码
用json_encode正确传递数组,修复月份拼写错误,替换未定义变量:
var xValues = ['January','February','March','April','May','June','July','August','September','October','November','December']; var yValues = {!! json_encode($data) !!}; new Chart("myChart", { type: "line", data: { labels: xValues, datasets: [{ fill: false, lineTension: 0, backgroundColor: "rgba(0,0,255,1.0)", borderColor: "rgba(0,0,255,0.1)", data: yValues }] }, options: { legend: {display: false}, scales: { yAxes: [{ticks: {min: 0, max: {{$maxSales}}}}], } } });
验证步骤
- 后端用
dd($data)确认生成了12个元素的数组,无销量月份为0。 - 查看页面源码,确认
yValues是一维数组格式(如[0,150,200,...])。 - 检查浏览器控制台,确认无JS语法或变量未定义错误。
内容的提问来源于stack exchange,提问作者Tatsumi Kazuki
相关产品推荐
相关产品推荐

