我想使用 Laravel 7 将我的查询输出传递到 jQuery 图表 js
Posted
技术标签:
【中文标题】我想使用 Laravel 7 将我的查询输出传递到 jQuery 图表 js【英文标题】:I want to pass the my query output into jQuery chart js using Laravel 7 【发布时间】:2021-07-09 15:33:27 【问题描述】:我想在折线图中显示每个月的注册学生人数。我从查询中得到了结果,但我不明白如何在折线图 js 文件中传递值。请帮助解决此问题。我附上了输出的代码和屏幕截图。
我想将查询输出 dat一个计数值传递给 jQuery data: [0, 4, 9, 18, 21, 34, 20, 35, 45, 53, 49 , 60],
app.js
(function ($)
"use strict"; // Chart
if ($('#report-line-chart').length)
var ctx = $('#report-line-chart')[0].getContext('2d');
var myChart = new chart_js__WEBPACK_IMPORTED_MODULE_1___default.a(ctx,
type: 'line',
data:
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
label: '# of total',
data: [0, 4, 9, 18, 21, 34, 20, 35, 45, 53, 49, 60],
borderWidth: 2,
borderColor: '#3160D8',
backgroundColor: 'transparent',
pointBorderColor: 'transparent'
]
,
options:
legend:
display: false
,
scales:
xAxes: [
ticks:
fontSize: '12',
fontColor: '#777777'
,
gridLines:
display: false
],
yAxes: [
ticks:
fontSize: '12',
fontColor: '#777777',
callback: function callback(value, index, values)
return value;
,
gridLines:
color: '#D8D8D8',
zeroLineColor: '#D8D8D8',
borderDash: [2, 2],
zeroLineBorderDash: [2, 2],
drawBorder: false
]
);
)($s);
我的控制器查询
<?php
$arr["eachMonthRegister"] = DB::table('students')->select(DB::raw('count(id) as `data`'), DB::raw('YEAR(created_at) year, MONTH(created_at) month'))
->groupby('year','month')
->get();
return view('home')->with($arr);
?>
我的查询输出
【问题讨论】:
您的答案存在一些格式问题。尝试改进它。使用`
括号表示路径和代码片段。不要使用过多的 bold 字体。 ;)
【参考方案1】:
其实你做得对,但我在你的代码中添加了一些部分。
- 控制器
$result = DB::table('students')->select(DB::raw('count(id) as `data`'),
DB::raw('YEAR(created_at) year, MONTH(created_at) month'))
->groupby('year','month')
->orderby('month) // I added this line
->get();
$output = [];
foreach ($result as $entry)
if (isset($output[$entry->month]))
$output[$entry->month] += $entry->data;
else
$output[$entry->month] = $entry->data;
$lineChartData= array_values($output);
return view('home')->with($lineChartData);
// $lineChartData will be like below
// [0, 4, 9, 18, 21, ...]
- home.blade
<script>
var lineChartData = @json($lineChartData)
// [0, 4, 9, 18, 21, ...]
</script>
- app.js
.
..
...
datasets: [
label: '# of total',
data: lineChartData,
另一个注意事项:您似乎不需要从 DB 返回的year
。如果是这样,您可以更改如下代码并提高代码的性能和速度:
- 控制器
$result = DB::table('students')->select(DB::raw('count(id) as `data`'),
DB::raw(MONTH(created_at) month'))
->groupby('month')
->orderby('month)
->get();
// same as top codes
...
【讨论】:
非常感谢你,这个工作完美:-)【参考方案2】:我遇到了类似的问题,就像你昨天遇到的一样,并且解决了!因此,我将向您和其他面临此问题的人讲述我的完整方法。
问题一:
和你一样,我也想过 groupBy 和 year
和 month
但是在得到查询的输出后,我发现不是 groupBy 可以解决我们的问题。因为,groupBy 只会对同一月或同一年的值进行分组/收集/计数。因此,我们不会像一年中的每个月那样直接获得 12 个值(特别是对于没有值的月份不会给我们 0,但我们的情况需要 0)。所以,我必须创建自己的查询,如下所示。它将为您提供当年每 12 个月的直接 12 个值!:
解答查询:
$months = ['01','02','03','04','05','06','07','08','09','10','11','12'];
$group_by_month = [];
// note that this foreach() will loop through exactly 12 times!
foreach($months as $key => $month)
$group_by_month[$key] = DB::table('students')
->whereBetween('created_at',[date('Y').'-'.$month.'-01',date('Y').'-'.$month.'-31'])
->get()
->count();
$data['group_by_month_this_year'] = $group_by_month;
return view('home',$data); // in your home you can access $group_by_month_this_year
问题2:
我遇到的第二个问题(可能你也会遇到)是返回的数据是索引数组,但我们需要没有索引的数组,所以json_encode
会有所帮助,因为@directive 的缩写形式是@json
。因此,在您的数据中添加这一行:
data: @json($group_by_month_this_year)
注意: 就我而言,我需要current and previous year
的数据,所以我为您添加了current year
的代码。如果您想通过start to end
进行操作,请告诉我,我会尝试更新答案。
【讨论】:
【参考方案3】:您可以使用以下方式实现折线图。
我将使用来自下一个 URL 的简单折线图来减少代码。 https://www.chartjs.org/docs/latest/charts/line.html
1。 Laravel /routes/web.php 和 welcome.blade.php(模板)
PHP 将解析刀片模板文件并将其转换为 HTML。
路由/web.php
...
Route::get('/', function ()
$items = DB::table('students')
->select(DB::raw("count(id) as `data`, year || '-' || month as month"))
->groupBy('year','month')
->get();
$values = $items->pluck('data'); // ["6","6","6","6","12"]
$months = $items->pluck('month'); // ["2015-10","2015-11","2015-12","2016-1","2016-10"]
return view('welcome', ['values'=> $values, 'months' => $months]);
);
资源/视图/welcome.blade.php
...
<head>
...
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body class="antialiased">
<div>
<canvas id="myChart"></canvas>
</div>
...
<script>
var values = !! json_encode($values) !!;
var labels = !! json_encode($months) !!;
console.log("this is from welcome.blade.php",values,labels);
const data =
labels: labels,
datasets: [
label: 'My First dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: values,
]
;
const config =
type: 'line',
data,
options:
;
var myChart = new Chart(
document.getElementById('myChart'),
config
);
</script>
</body>
php 将解析这个刀片模板并转换下一个代码
var values = !! json_encode($values) !!;
var labels = !! json_encode($months) !!;
到
var values = ["6","6","6","6","12"];
var labels = ["2015-10","2015-11","2015-12","2016-1","2016-10"];
2。 Laravel /routes/web.php 和 /public/js/custom.js ajax 请求
浏览器将获取 HTML,然后调用 AJAX。回调后,chart js 会被渲染成标签和值。
路由/web.php
...
Route::get('/', function ()
return view('welcome');
);
Route::get('/ajax', function ()
$items = DB::table('students')
->select(DB::raw("count(id) as `data`, year || '-' || month as month"))
->groupBy('year','month')
->get();
$values = $items->pluck('data'); // ["6","6","6","6","12"]
$months = $items->pluck('month'); // ["2015-10","2015-11","2015-12","2016-1","2016-10"]
return ['values'=> $values, 'months' => $months];
);
资源/视图/welcome.blade.php
<head>
...
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
...
<script type="text/javascript" src=" URL::asset('js/custom.js') "></script>
</body>
public/js/custom.js
$.get( "/ajax", function( items )
console.log("this data is from ajax request from custom.js",items);
const data =
labels: items.months,
datasets: [
label: 'My First dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: items.values,
]
;
const config =
type: 'line',
data,
options:
;
var myChart = new Chart(
document.getElementById('myChart'),
config
);
);
【讨论】:
【参考方案4】:首先,将您的集合更改为数组,并且只获取您的集合的值
$array = $collection->toArray();
foreach($array as $a)
$result[] = $a['data'];
return view('your.view', compact('result'));
这是我的解决方案,避免使用外部 JS 文件。然后传递你的变量
方法如下:
<script>
...
datasets: [
label: '# of total',
data: !! json_encode($result) !!,
borderWidth: 2,
borderColor: '#3160D8',
backgroundColor: 'transparent',
pointBorderColor: 'transparent'
]
...
</script>
【讨论】:
【参考方案5】:您没有将数据很好地传递给视图。 with() 用于将数据闪存到会话中。
在您的控制器中尝试这样的操作:
return view('home', ['mydata' => $arr]);
您可以在视图中使用变量 $mydata
您可以传递任意数量的变量:
return view('home', ['mydata' => $arr, 'mydata2' => $arr2]);
【讨论】:
以上是关于我想使用 Laravel 7 将我的查询输出传递到 jQuery 图表 js的主要内容,如果未能解决你的问题,请参考以下文章
Php 变量未传递到 whereHas 函数 - Laravel Eloquent
Laravel API resourceCollection 使用数组而不是模型