How can I display the product sales per month using a Line Graph? - laravel-5

$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();
This is the line graph:
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}}}}],
}
}
});
I tried to use a for loop to make an array for the data but there's still no visible data, or maybe I don't have enough data in database?

you can change your yValue in js like:
var yValues = #json($data);
Works like a charm

Related

how to display multiple sum with chart js and laravel?

I have three table
Table drics
Table country_dric
Table Countries
I just display country name with sum legal from table drics.
I want to display sum column legal, illegal, applicant and mandatory from table drics with country name.
How to display the sum of each column from table drics?
my controller
$drics =DB::table('countries')
->join('country_dric','countries.id','country_dric.country_id')
->join('drics','drics.id','country_dric.dric_id')
->select('name',\DB::raw('sum(legal) as sum'))->groupby('name')
->whereYear('drics.created_at', $year)->get();
$dric_title=[];
$dric=[];
foreach ($drics as $key => $value) {
$dric_title[$key]=$value->name;
$dric[$key]=$value->sum;
}
return view('home.home', compact(' 'dric', 'dric_title'));
js Code
<script>
var ctx = document.getElementById('dric').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: #json($dric_title),
datasets: [{
label: '# ',
data: #json($dric),
backgroundColor: "rgba(0,31,68,0.8)",
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
Try this
Your controller:
$drics =DB::table('countries')
->join('country_dric','countries.id','country_dric.country_id')
->join('drics','drics.id','country_dric.dric_id')
->select('name',\DB::raw('sum(legal) as legal_sum')
,\DB::raw('sum(ilegal) as ilegal_sum')
,\DB::raw('sum(applicant) as applicant_sum')
,\DB::raw('sum(mandatory) as mandatory_sum'))->groupby('name')
->whereYear('drics.created_at', $year)->get();
$dric_title=[];
$dric=[];
foreach ($drics as $key => $value) {
$dric_title[$key]=$value->name;
$dric['legal'][$key]=$value->legal_sum;
$dric['ilegal'][$key]=$value->ilegal_sum;
$dric['applicant'][$key]=$value->applicant_sum;
$dric['mandatory'][$key]=$value->mandatory_sum;
}
return view('home.home', compact(' 'dric', 'dric_title'));
js code:
<script>
var ctx = document.getElementById('dric').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: #json($dric_title),
datasets: [{
label: 'Legal',
data: #json($dric['legal']),
backgroundColor: "rgba(0,31,68,0.8)",
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}, {
label: 'Ilegal',
data: #json($dric['ilegal']),
backgroundColor: "rgba(0,31,68,0.8)", // Change the color to make it different
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}, {
label: 'Applicant',
data: #json($dric['applicant']),
backgroundColor: "rgba(0,31,68,0.8)", // Change the color to make it different
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}, {
label: 'Mandatory',
data: #json($dric['mandatory']),
backgroundColor: "rgba(0,31,68,0.8)", // Change the color to make it different
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
You can use #foreach loop if you want too

how to fix this error Array to string conversion in laravel and chartjs?

i want to get sum men learning and women learning from learnings table and display to chart with group by province name.
Error:
Array to string conversion (View: C:\xampp\htdocs\project\resources\views\chart\index.blade.php)
my controller
$learnings =DB::table('provinces')
->join('learning_province','provinces.id','learning_province.province_id')
->join('learnings','learnings.id','learning_province.learning_id')
->select('title',\DB::raw('sum(men_learned + women_learned) as sum'))
->groupby('title')->whereYear('provinces.created_at', $year)->get();
$title = [];
$learning= [];
foreach ($learnings as $key => $value) {
$title[$key]=$value->title;
$learning[$key]=$value->sum;
}
return view('home.home', compact('learning', 'title'));
how to display sum men and women with group by province name in this script
my script
<script>
var ctx = document.getElementById('lineChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [{!!$title!!}],
datasets: [{
label: '# ',
data: [{!!$learning!!}],
backgroundColor: ["#3e95cd"],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
However, instead of manually calling json_encode, you may use the #json Blade directive. The #json directive accepts the same arguments as PHP's json_encode function.
Please like this json_encode in laravel blade
<script>
var ctx = document.getElementById('lineChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: #json($title),
datasets: [{
label: '# ',
data: #json($learning),
backgroundColor: ["#3e95cd"],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>

i want the line graph to start at 12:00AM and end at 11:59pm in chart js

i want my chart start at 12:00am and only draw the points when data avaiable. In most of my case data starts at 06:00am. now i want the chart look likes this.
i had generate the label from the created_at provide by the query. so, the label are equavalent to all the created_at present. My chart looks like this.
i want my label to start at 12:00Am but graph from the first created_at point. or null value can be replaced as 0.
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script>
let labels = {!! $labels !!};
Chart.defaults.scale.gridLines.drawOnChartArea = false;
Chart.defaults.global.title.display = true;
Chart.defaults.global.tooltips.intersect = false;
Chart.defaults.global.elements.point.radius = 0;
Chart.defaults.scale.ticks.maxTicksLimit = 21;
Chart.defaults.scale.ticks.maxRotation = 0;
Chart.defaults.scale.ticks.minRotation = 0;
Chart.defaults.global.defaultFontColor = "#bfbfbf";
var outdoor = new Chart(document.getElementById("outdoor").getContext('2d'), {
type: 'line',
showScale: false,
data: {
labels: labels,
datasets: [{
data: {{$activeGraph->pluck('status')}},
label: "Active Status",
borderColor: "#00F",
fill: false,
borderWidth: 1,
}]
},
options: {
title: {
text: 'Outdoor Temperature and Due Point'
},
customLine: {
color: 'black'
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {
maxRotation: 0,
minRotation: 0
}
}]
}
},
</script>
my laravel code
$activeGraph = ActiveGraph::where('device_id', $id)->get();
$labels = $activeGraph->map(function ($model) {
return [$model->created_at->format('M-d') ,$model->created_at->format('h:i A')];
});
return view('devices.chart',compact('labels','activeGraph'))->with('device', $device);

How to solve Chart js mismatched x-axes label and value dynamically in Laravel?

I have encountered a problem using chart js when applying it dynamiccally, which means I get a data from my database and output a bar graph using Chart JS. I found this example which works when a value is 0, but on my situation some data on a specific year cannot be found yet on my database, which leads to a null value. How can I set this empty or null value to zero so that I can achieve this example https://jsfiddle.net/17mw40rx/1/. I want also to show my JS code which I copied from the same sample and applied it to my project. The script works fine but when a year data is missing let say no record found in 2002 and 2005, the data are filled automatically by a wrong year data. I hope you understand my problem. Please I need help from someone about this.
JS Script
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.js"></script>
<script>
var year = ['2000','2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017','2018','2019','2020'];
var female = <?php echo $female; ?>;
var male = <?php echo $male; ?>;
var entranceDataset = {
label: 'Female',
type: 'bar',
yAxesID : "y-axis-1",
data: female,
backgroundColor: 'rgba(0, 204, 0, 0.2)',
borderColor: 'rgba(0, 204, 0,1)',
borderWidth: 1
};
var dataset = [];
dataset.push(entranceDataset);
var exitDataset = {
label: 'Male',
type: 'bar',
yAxesID : "y-axis-1",
data: male,
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
};
dataset.push(exitDataset);
var ctx = $('#enrollcanvas');
mainThroughputChart = new Chart(ctx, {
type: 'bar',
data: {
labels: year,
datasets: dataset
},
options: {
scales: {
xAxes : [{
gridLines : {
display : false
},
scaleLabel: {
display: true,
labelString: 'Year'
}
}]
},
}
});
</script>
Laravel Controller and query
$female = Enroll::select(DB::raw("SUM(tot_enroll) as count"))
->orderBy(DB::raw('sy'))
->groupBy(DB::raw("(sy)"))
->where('gender','=', 'Female')
->get()->toArray();
$female = array_column($female, 'count');
$male = Enroll::select(DB::raw("SUM(tot_enroll) as count"))
->orderBy(DB::raw('sy'))
->groupBy(DB::raw("(sy)"))
->where('gender','=', 'Male')
->get()->toArray();
$male = array_column($male, 'count');
return view('home')
->with('female',json_encode($female,JSON_NUMERIC_CHECK))
->with('male',json_encode($male,JSON_NUMERIC_CHECK));
Blade Page
<canvas id="enrollcanvas" name="enrollcanvas" height="280" width="600"></canvas>
Actual Bar Chart Result
Database Table where the bar chart is based from
I think the problem with mismatched data of $female and $male with JS year variable.
var year = ['2000','2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017','2018','2019','2020'];
var female = <?php echo $female; ?>;
var male = <?php echo $male; ?>;
Pass the '0' if $female OR $male doesn't have value for each year(Let's say 2000). So your $female and $male should be like:
var year = ['2000','2001','2002','2003', '2004'...];
var female = ['0','34', '0','65', '54',...];
var male = ['0','75', '0','34', '0',...];
Update
Try this below code with full snippet of controller side. Replace enroll with your database table name into this query.
$rsltEnrollData = DB::table('enroll')->selectRaw('sy as sy, gender, SUM(tot_enroll) as count')
->groupBy('sy')
->orderBy('sy')
->get();
$arrFemale = array();
$arrMale = array();
$arrYearData = array();
foreach($rsltEnrollData as $key => $objEnrollData){
if(!isset($arrYearData[$objEnrollData->sy])){
$arrYearData[$objEnrollData->sy]['Male'] = 0;
$arrYearData[$objEnrollData->sy]['Female'] = 0;
}
$arrYearData[$objEnrollData->sy][$objEnrollData->gender] = $objEnrollData->count;
$arrFemale = $arrYearData[$objEnrollData->sy]['Female'];
$arrMale = $arrYearData[$objEnrollData->sy]['Male'];
}
Debug
foreach($rsltEnrollData as $key => $objEnrollData){
print('<pre style="color:red;">');
print_r($objEnrollData);
print('</pre>');
}
exit;
this is a snippet of the script in my project. maybe a little different, but maybe someone needs it. and hope it helps in configuring chart js with laravel and database
JAVASCPT
$(document).ready(function() {
var statistics_chart = document.getElementById("myChart").getContext('2d');
fetch("{{url('chart')}}")
.then(response =>response.json())
.then(json=>{
var myChart = new Chart(statistics_chart, {
type: 'line',
data: {
labels: json.labels,
datasets: json.dataset,
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
gridLines: {
// display: false,
drawBorder: false,
color: '#f2f2f2',
},
ticks: {
beginAtZero: true,
stepSize: 10000,
}
}],
xAxes: [{
gridLines: {
display: false,
tickMarkLength: 15,
}
}]
},
}
});
})
});
Controller
public function chart()
{
$data = Kas::select([
DB::raw("SUM(debit) as total_debit"),
DB::raw("SUM(kredit) as total_kredit"),
DB::raw("MONTH(created_at) as bln"),
// DB::raw("YEAR(created_at) as year")
])
->whereYear('created_at', 2022)
->groupBy([
'bln'
])
->orderBy('bln')
->get();
$arrBln = [1 => 'Jan','Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'];
$totalD = $totalK = [];
foreach ($data as $tot) {
$totalD[$tot->bln] = $tot->total_debit;
$totalK[$tot->bln] = $tot->total_kredit;
}
foreach ($arrBln as $month =>$name){
if(!array_key_exists($month, $totalD)){
$totalD[$month]= 0;
}
if(!array_key_exists($month, $totalK)){
$totalK[$month]= 0;
}
}
ksort($totalD);
ksort($totalK);
return[
'labels' => array_values($arrBln),
'dataset' => [
[
'label' => 'Pemasukan',
'data' => array_values($totalD),
'borderWidth'=> 2,
'backgroundColor'=> 'rgba(63,82,227,.8)',
'borderWidth' => 0,
'borderColor' =>'transparent',
'pointBorderWidth' => 0,
'pointRadius' => 3.5,
'pointBackgroundColor' => 'transparent',
'pointHoverBackgroundColor' => 'rgba(63,82,227,.8)',
],
[
'label' => 'Pengeluaran',
'data' => array_values($totalK),
'borderWidth'=> 2,
'backgroundColor' => 'rgba(254,86,83,.7)',
'borderWidth' => 0,
'borderColor' =>'transparent',
'pointBorderWidth'=> 0,
'pointRadius'=> 3.5,
'pointBackgroundColor'=> 'transparent',
'pointHoverBackgroundColor'=> 'rgba(254,86,83,.8)',
],
]
];
}

include two series from database in a highchart chart

I would like to include a series to my existing chart.
daytime = new Highcharts.Chart({
chart: {
renderTo: 'daytime_div',
defaultSeriesType: 'areaspline',
events: {
load: getData()
}
},
plotOptions: {
series: {
fillOpacity: 0.1,
lineWidth: 4,
marker: {
radius: 5,
lineWidth: 1,
lineColor: "#FFFFFF"
}
}
},
tooltip: {
formatter: function () {
var s = [];
$.each(this.points, function (i, point) {
s.push('<span style="font-size:10px;">' + point.key + '</span><br/><strong>' + point.series.name + '</strong> : ' + point.y + '</span>');
});
return s.join('<br/>');
},
shared: true,
useHTML: true
},
credits: false,
title: false,
exporting: false,
legend: {
itemDistance: 50,
itemStyle: {
color: '#333'
}
},
xAxis: {
labels: {
staggerLines: 2
}
},
yAxis: {
gridLineColor: "#e7e7e7",
title: {
text: ''
},
labels: {
x: 15,
y: 15,
style: {
color: "#999999",
fontSize: "10px"
}
},
},
series: [{
name: 'Daily',
color: "#b18eda",
data: ddata
}]
});
function getData() {
$.ajax({
url: '...',
type: "POST",
contentType: "application/json; charset=utf-8",
data: data,
success: function (f) {
var categories = [];
var series_data = [];
$.each(f.d, function (i, e) {
categories.push(e.hour);
series_data.push(parseInt(e.numa));
});
daytime.xAxis[0].setCategories(categories);
daytime.series[0].setData(series_data);
},
cache: false
});
}
The data I get from my database looks like this:
hour, numa
12 AM 1
1 AM 0
2 AM 0
3 AM 0
4 AM 0
This shows one line in the chart which is fine. I would like to add a second line that will come from a different query. The second line data will look like:
hour, numa
12 AM 0
1 AM 12
2 AM 3
3 AM 2
4 AM 2
Does anyone knows how could I include this into my second series? I have seen the sample in high charts on how to add more series. Static is pretty simple but getting the data dynamically make it more complicated to figure it out.
I am trying to find a way to add 2 series to my getData() function. Any idea will be appreciate it thanks.
It is explained clearly in the fiddle of the document which you shared on how to add multiple series.
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}, {
name: 'Berlin',
data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
}, {
name: 'London',
data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
}]
You can pass multiple series in array and the chart can be generated.
EDIT-1
If data from different series use this fiddle.
var myComments=["First input","second comment","another comment","last comment"]
var dataValues = [29.9, 71.5, 194.1, 129.2];
var dataValues2 = [194.1, 95.6, 194.1, 29.9];
var categories = ['Jan', 'Feb', 'Mar', 'Apr'];
var n=['tooltip1','tooltip2','tooltip3','tooltip4'];
$(function () {
$('#container').highcharts({
chart: {},
tooltip: {
formatter: function () {
var serieI = this.series.index;
var index = categories.indexOf(this.x);
var comment = myComments[index];
return '-->'+comment;
}
},
xAxis: {
categories: categories
},
series: [{
data: dataValues
}, {
data: dataValues2
}]
});
});
which results in the below graph
Well you can use $.when() and load there all your ajax and in $.then() initialise chart. Second solution is prepare your query to database and return all data in single json.

Resources