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

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);

Related

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

$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

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>

Plot two lines on same month with different dates with Base-unit :month

I am developing a chart on Kendo-UI, where we need to plot a vertical line w.r.t dates available on the x-axis. The challenge, that I am facing is my x-axis contains BaseUnit: months. when I am plotting bands w.r.t two different dates in the same month, the system generates vertical line but captures a complete month section rather than plotting two different lines in the same month.
Sample Code:
var DateRange = [];
var PlotData = [];
var AllData = [];
function BindDates() {
for (var startmonth = 01; startmonth <= 12; startmonth++) {
for (var startday = 01; startday <= 30; startday++) {
DateRange.push(new Date("2019/" + startmonth + "/" + startday));
AllData.push(Math.floor((Math.random() * startday) * new Date().getMilliseconds()));
}
for (var Initial = 1; Initial <= 3; Initial++) {
var data = null;
if (Initial == 1) {
data = { from: new Date("2019/02/03"), to: new Date("2019/02/03"), color: "red", width: 0.1 };
}
else if (Initial == 2) {
data = { from: new Date("2019/05/03"), to: new Date("2019/05/03"), color: "green", width: 0.1 };
}
else if (Initial == 3) {
data = { from: new Date("2019/06/03"), to: new Date("2019/06/03"), color: "black", width: 0.1 };
}
PlotData.push(data);
}
}
createChart(DateRange, AllData, PlotData);
}
function createChart(datesss, alldata, PlotData) {
$("#chart").kendoChart({
title: {
text: "Chart Title"
},
legend: {
position: "bottom"
},
seriesDefaults: {
type: "area",
area: {
line: {
style: "smooth"
}
}
},
series: [
{
name: "Late",
color: "orange",
data: alldata
}, {
type: "line",
dashType: "dashDot",
name: "Est DT",
color: "grey",
data: alldata
},
{
name: "On time",
color: "blue",
data: alldata
}],
valueAxis: {
labels: {
format: "{0}"
},
line: {
visible: false
},
axisCrossingValue: -10
},
categoryAxis: {
type: "date",
categories: datesss,
baseUnit: "months",
labels: {
dateFormats: {
months: "MMM-yy"
}
},
majorGridLines: {
visible: false
},
labels: {
rotation: "auto",
},
plotBands: PlotData
},
tooltip: {
visible: true,
format: "{0}%",
template: "#= series.name #: #= value #"
}
});
}
BindDates();
$(document).ready(function () {
BindDates();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/kendo.all.min.js"></script>
<div id='chart'></div>

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)',
],
]
];
}

How to change the labels to the image (icon) in bar chart.js

Help me, please.
How to change the labels to the image (icon) in bar chart.js ?
I mean, change from this
change labels: "LifeWall_files/logo.png","Bodily Functions","Sleep"
to this
bottom icons
The easiest way to do this would be to get a font that includes these icons and then set the font family for the ticks
...
options: {
scales: {
xAxes: [{
ticks: {
fontFamily: 'FontAwesome'
}
}]
}
}
};
and then specify the appropriate character codes in your labels
labels: ["\uf24e", "\uf1b9", "\uf242", "\uf0fc", "\uf236"],
With the FontAwesome CSS, the above would give you
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterDraw hook to draw images (icons) instead of tick labels directly on the canvas using CanvasRenderingContext2D.
You'll also have to instruct Chart.js not to display the default tick labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false
}
}],
Further you need to define some padding at the bottom of the chart, otherwise you'll see only part of the images.
layout: {
padding: {
bottom: 30
}
},
Please have a look at the runnable code snippet below.
const labels = ['red vans', 'blue vans', 'green vans', 'gray vans'];
const images = ['https://i.stack.imgur.com/2RAv2.png', 'https://i.stack.imgur.com/Tq5DA.png', 'https://i.stack.imgur.com/3KRtW.png', 'https://i.stack.imgur.com/iLyVi.png'];
const values = [48, 56, 33, 44];
new Chart(document.getElementById("myChart"), {
type: "bar",
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
xAxis.ticks.forEach((value, index) => {
var x = xAxis.getPixelForTick(index);
var image = new Image();
image.src = images[index],
ctx.drawImage(image, x - 12, yAxis.bottom + 10);
});
}
}],
data: {
labels: labels,
datasets: [{
label: 'My Dataset',
data: values,
backgroundColor: ['red', 'blue', 'green', 'lightgray']
}]
},
options: {
responsive: true,
layout: {
padding: {
bottom: 30
}
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
display: false
}
}],
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>

Resources