How to display multiple datasets by month in highchart? - php

I have a database called sales which I'm trying to display in my chart like this but can't.
id
products
earnings
created_at
1
Jasmine
50
2023-01-14 18:55:34
2
How to cook
150
2023-01-14 18:55:34
3
Jasmine
100
2023-01-14 18:55:34
4
Dictionary
200
2023-01-14 18:55:34
5
How to cook
70
2023-02-20 17:23:54
It is my first time trying to do it in chart and tried other codes from tutorials
and ended up with this result
I'm trying to display it like the first chart, but instead by month with multiple datasets where the month will contain the name of the products and its earning on that month. like this
Pardon my unsightly editing
This is the working code that I managed to follow and do, but don't know how to modify it to obtain the desired output. I tried but gets an error, so I put it back.
$now = Carbon::now();
$yr = $now->format('Y/m/d');
//monthly
{
$m= $now->format('m');
$date_start = Carbon::create(date('Y'), "1");//january start
$data=[];
$monthdata=[];
$x=0;
for ($month = $m; $x <= 7; $month++)
{
$x=$x+1;
$date = Carbon::create(date('Y'), $month);
$date_end = $date->copy()->endOfMonth();
$saledate = DB::table('sales')
->select(DB::raw('sum(earnings) as sale'))
->where('created_at', '>=', $date)
->where('created_at', '<=', $date_end)
->get();
$sum=0;
foreach ($saledate as $row)
{
$sum=$row->sale;
}
array_push($data,$sum);
array_push($monthdata,$date->format('M'));
}
$saleChart1= new UserChart;
$saleChart1->labels($monthdata);
$saleChart1->dataset('Sales', 'bar',$data )->options([
'color' => '#2596be',
]);
}
Inside my blade file,
<div class="col-lg-6 mb-5">
<div class="card card card-raised h-100 ">
<div class="card-header text-dark bg-success px-4" style="background-color:#198754 !important">
<i class="fas fa-chart-area me-1 text-white"></i>
Monthly Sales
</div>
<div class="card-body bg-white">
<div class="col-lg-12 " >
<div id="myAreaChart1" class="mt-4" style="height: 300px;">
{!! $saleChart1->container() !!}
<script src=https://cdnjs.cloudflare.com/ajax/libs/echarts/4.0.2/echarts-en.min.js charset=utf-8></script>
{!! $saleChart1->script() !!}
</div>
</div>
</div>
</div>
</div>
My UserChart class,
<?php
namespace App\Charts;
use ConsoleTVs\Charts\Classes\Chartjs\Chart;
class UserChart extends Chart
{
/**
* Initializes the chart.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
}
Please help, can't find other tutorials, all I found now are pie charts and line graphs and doesn't display similar to what I'm looking for. What should I do to achieve the desired output?

It doesn't seem like ConsoleTVs\Charts\Classes\Chartjs\Chart has that capability. However, you might be able to get ConsoleTVs\Charts\Classes\Echarts\Chart to work closer to what you'd need.
If I were you I'd change your UserChart class to
<?php
namespace App\Charts;
use ConsoleTVs\Charts\Classes\Echart\Chart;
class UserChart extends Chart
{
/**
* Initializes the chart.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
}
Then using example from https://echarts.apache.org/examples/en/editor.html?c=bar-label-rotation
you should be able to mold your data into the correct format.
It seems as though most of the setup is pushed into an option array. Some of which you can see on the class itself https://github.com/ConsoleTVs/Charts/blob/main/src/Classes/Echarts/Chart.php
You should be able to set the options with $saleChart1->options([//...]);
Happy coding :-)

Related

Laravel, Undefined Variable when trying to pass array from controller to views [duplicate]

This question already has answers here:
How to pass data to view in Laravel?
(15 answers)
Closed 6 months ago.
i'm pretty new to Laravel and still trying to figure all of this out. So basically I have an array with a list of movies that I want to pass onto my index.blade.php file. Then show that list in my index file. This is what I have currently.
Route:
Route::get('catalog', 'App\Http\Controllers\CatalogController#getIndex');
Controller:
class CatalogController extends Controller
{
private $arrayPeliculas = array(...);
public function getIndex()
{
return view('catalog.index', $this->arrayPeliculas);
}
}
Index:
<body>
#section('content')
<div class="row">
#foreach( $arrayPeliculas as $key => $pelicula )
<div class="col-xs-6 col-sm-4 col-md-3 text-center">
<a href="{{ url('/catalog/show/' . $key ) }}">
<img src="{{$pelicula['poster']}}" style="height:200px"/>
<h4 style="min-height:45px;margin:5px 0 10px 0">
{{$pelicula['title']}}
</h4>
</a>
</div>
#endforeach
</div>
#endsection
</body>
I tried doing it a different way that did sort of work
public function getIndex()
{
$arrayPeliculas = array(...);
return view('catalog.index')->with('arrayPeliculas', $arrayPeliculas);
}
But that doesn't really work for me since I have a few other functions that use this array and when the array is modified it would only be within that specific function.
I've looked for similar questions but I don't see what i'm doing wrong. Any help is appreciated, thank you.
You should use this
return view(
'catalog.index',
['arrayPeliculas' => $this->arrayPeliculas]
);
You can send the variable with compact because you defined it earlier
You should use this return view('catalog.index',compact('arrayPeliculas'));
your code should be like bellow
return view('catalog.index',compact('arrayPeliculas'));

count visitor of pages in laravel

How can i count visitor of pages in Laravel, prefer to use cache
public function IndexShow(){
Cache::put('home',0);
$counter = Cache::increment('home',1);
}
Check out this package then if google analytics is not an option for you. - https://github.com/antonioribeiro/tracker
They have thought through some things you would be seeking to do. You will end up with something like below.
//in your controller
$weeklyUsers = Tracker::users(60 * 24 * 7);
//in your blade
<div>
<span class="h4 d-block font-weight-normal mb-2">{{ $weeklyUsers }}</span>
<span class="font-weight-light"><strong>TOTAL VISITOR</strong></span>
</div>

laravel pagination returns different page

I am working on a laravel project, where I get data from an API then I want to display it on pages. I want the return to be spread out across 4 pages, each page with 10 results each. What I have so far, seems like it should work, but I am missing one piece, so any advice and help would be appreciated. So this is how it is suppose to work with code:
1) The users types in a book title in a search box.
<form method=POST action='/search'>
#csrf
<input type="text" name="search_term"/>
<input type="submit" value="Search"/>
</form>
2) there input is then sent to my controller, which queries the google books api.
class search extends Controller {
public function search(){
$current_page = LengthAwarePaginator::resolveCurrentPage();
echo $current_page;
$term = request('search_term');
$term = str_replace(' ', '_', $term);
$client = new \Google_Client();
$service = new \Google_Service_Books($client);
$params = array('maxResults'=>40);
$results = $service->volumes->listVolumes($term,$params);
$book_collection = collect($results);
$current_book_page = $book_collection->slice(($current_page-1)*10,10)->all();
$books_to_show = new LengthAwarePaginator($current_book_page,count($book_collection),10,$current_page);
return view('library.search')->with(compact('books_to_show'));
}
}
3) the results are then displayed on my blade
#extends('home')
#section('content')
#foreach($books_to_show as $entries)
<div class="row">
<div class="col-sm-auto">
<img class="w-50 img-thumbnail" src={{$entries['volumeInfo']['imageLinks']['smallThumbnail']}}/>
</div>
<div class="col-sm">
{{$entries['volumeInfo']['title']}}<br/>
#if($entries['volumeInfo']['authors']!=null)
by:
#foreach($entries['volumeInfo']['authors'] as $authors)
{{$authors}}
#endforeach
#endif
</div>
</div>
#endforeach
{{$books_to_show->links()}}
#endsection
This all works fine and as expected. I get 10 results on the view, and then I have a bar at the bottom which give shows me 4 different pages to choose from.
When I first type in a search term such as "William Shakespeare" My page url is:
localhost:8000/search
But, when I click on any of the pages my url becomes:
http://localhost:8000/?page=2
I understand that the ?page=* is how the pagination determines which page you are viewing, and that should be sent back to the controller. But, I am missing something on sending it back to the controller I think.
Still kind of fresh to this, so any advice is more then greatly appreciated.
LengthAwarePaginator accepts a 5th parameter in its constructor: an array of options.
the path option
$books_to_show = new LengthAwarePaginator($current_book_page, count($book_collection), 10, $current_page, [
// This will fix the path of the pagination links
'path' => LengthAwarePaginator::resolveCurrentPath()
]);
By the way, on a totally different matter, Laravel makes your life easier by slicing the collection for you, check it out:
$current_book_page = $book_collection->forPage($current_page, 10);
Hope it helps :)

How can I put counter in laravel?

In my leave management module I have a field , which displays count of employee took total leave and which are approved,
But unfortunately I can't get the count.
will anyone help me please???
Here is code of my view file
<div class="row">
<label class="col-md-6"><strong> Total Leave in this month </strong>/label>
<div class="col-md-6">
{{$count}}
</div>
</div>
Here is my code of controller file
public function handleLeave($id)
{
$employeeName = User::all();
$leaves = LeaveManagement::find($id);
$count = LeaveManagement::where('status', '=', 'Approved')->count();
return view('pages.leavelist', compact('leaves', 'id', 'count', 'employeeName'));
}

Get Days with zero total bookings too in laravel

I have list of bookings in one table and I have another table spots that has the event info such as : date, day , event_name, price, duration etc..
I need to groupBy bookings using days, which works fine but the problem comes when there are spots without any bookings and my join query matches spots and bookings table but if there arent any bookings for a given spot then the groupby for that particular day fails.
Example : I have spots on Mon, Tue and Wed. If there are no bookings for monday, I wont get a totalbooking count a zero. I dont get anything for that day. inshort, it doesnt exist.
Why I need is because : I have a progress bar on front-end which shows no. of bookings for each day, so if no bookings for given day I endup with no progress bar.
Controller :
//This query does not return bookings for tuesday because I dont have bookings.
$days = DB::table('spots')
->join('bookings','spots.id','=','bookings.spot_id')
->where('spots.event_id','=',$id)
->select('day',DB::raw('count(bookings.spot_id) as bookingcount'))
->groupby('spots.day')
->get();
View :
#foreach($days as $day)
<div class="col-sm-6 col-md-3">
<div class="tablet tablet-stat">
<h4 class="tablet-header">{{ $day->day }}</h4>
<div id="circle">
<div class=" c100 p{{round(($day->bookingcount/$totalspace->totalspace)*100,0)}}">
<span> {{ round(($day->bookingcount/$totalspace->totalspace)*100,2) }} </span>
<div class="slice">
<div class="bar"></div>
<div class="fill"></div>
</div>
</div>
</div>
</div>
</div>
#endforeach
I am not really looking for a hack, like simply find the day that has no bookings and create another foreach loop to show those days with zero bookings. I prefer getting count as zero in my query.
Try it like this:
$days = DB::table('spots')
->leftJoin('bookings','spots.id','=','bookings.spot_id')
->where('spots.event_id','=',$id)
->select('day',DB::raw('count(bookings.spot_id) as bookingcount'))
->groupby('spots.day')
->get();
*corrected the previous answer, didn't make much sense
An outer join should do what you want.

Categories