Laravel中双PHP数组渲染散点图异常:单数据时日期轴不显示
问题:Laravel中Chart.js散点图单数据点时日期轴无内容
在Laravel项目中,通过两个PHP数组(一个为2023/06/06格式的日期数组,一个为浮点数数组)渲染Chart.js散点图。实现流程为:控制器用compact传递数组到视图,Blade文件中将数组转为JS变量,再构建散点图。但当两个数组各仅含一个元素时,图表显示异常,日期轴无内容,需修复以正常展示。
现有代码
控制器代码
$list = $this->GetDaysList($tableprofitname); $profitlist = $this->profitlist($tableprofitname); return view('history', compact('list', 'results', 'profit', 'income_item', 'income_price', 'income_amount', 'expense_price', 'expense_item', 'expense_amount', 'profitlist'));
Blade视图JS转换代码
<script> var datearray = {!! json_encode($list) !!}; var results = {!! json_encode($results) !!}; var profitlist = {!! json_encode($profitlist) !!}; if(results == true){ var profit = {!! json_encode($profit) !!}; var income_item = {!! json_encode($income_item) !!}; var income_amount = {!! json_encode($income_amount) !!}; var income_price = {!! json_encode($income_price) !!}; var expense_item = {!! json_encode($expense_item) !!}; var expense_amount = {!! json_encode($expense_amount) !!}; var expense_price = {!! json_encode($expense_price) !!}; } </script>
Chart.js代码
var valuesforchart = []; for (var i = 0; i < datearray.length; i++) { valuesforchart.push({ x: datearray[i], y: profitlist[i] }); } new Chart("myChart", { type: "scatter", data: { datasets: [ { pointRadius: 4, pointBackgroundColor: "red", data: valuesforchart, }, ], }, options: { legend: { display: false }, scales: { x: { type: "time", time: { unit: "day", // 按天显示日期 }, }, }, }, });
测试数据
datearray[0] = "2023/06/06"profitlist[0] = -254672.00
问题原因
- 单数据点时,Chart.js的时间轴无法自动计算合理的刻度范围,导致轴内容不显示;
- 直接传入字符串格式的日期,可能存在Chart.js解析不兼容的问题。
修复方案
修改后的Chart.js代码
var valuesforchart = []; for (var i = 0; i < datearray.length; i++) { // 将字符串日期转为标准JS Date对象 var dateObj = new Date(datearray[i]); valuesforchart.push({ x: dateObj, y: profitlist[i] }); } // 初始化X轴配置 var xAxisOptions = { type: "time", time: { unit: "day", displayFormats: { day: 'YYYY/MM/DD' // 指定日期显示格式 } }, title: { display: true, text: '日期' // 添加轴标题 } }; // 处理单数据点的轴范围:手动设置日期前后各一天的范围 if (valuesforchart.length === 1) { var singleDate = new Date(valuesforchart[0].x); xAxisOptions.min = new Date(singleDate.setDate(singleDate.getDate() - 1)); singleDate = new Date(valuesforchart[0].x); xAxisOptions.max = new Date(singleDate.setDate(singleDate.getDate() + 1)); } new Chart("myChart", { type: "scatter", data: { datasets: [ { pointRadius: 4, pointBackgroundColor: "red", data: valuesforchart, }, ], }, options: { legend: { display: false }, scales: { x: xAxisOptions, y: { title: { display: true, text: '利润' // 添加Y轴标题 } } }, }, });
可选后端优化
在控制器中提前将日期转为ISO格式,减少前端解析压力:
// 转换日期为ISO格式 $list = array_map(function($date) { return \Carbon\Carbon::createFromFormat('Y/m/d', $date)->toIso8601String(); }, $this->GetDaysList($tableprofitname));
内容的提问来源于stack exchange,提问作者AliveUser
相关产品推荐
相关产品推荐

