我想使用 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 和 yearmonth 但是在得到查询的输出后,我发现不是 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 使用数组而不是模型

Laravel 5 选择查询将我的链接变成奇怪的格式

将我的查询集 obj 作为参数传递时芹菜引发错误

如何将数组从 Laravel Blade 传递到 Laravel 6/Vue 2.6 中的 Vue 组件。*

Laravel 5.2 - 如何将我的 Web 应用程序发布到 GitHub?