ChartJS memory usage - php

So I've experienced some problems with one of my PHP pages using ChartJS, when I load my charts (Pie/Bar), with a good amount of data, then the google tab on revisit can not respond / say out of memory or something like that. I've read that it should be possible to make ChartJS be garbage-collected by calling .destroy(), but that removes my chart, so I don't know how that should be done?
Is there a proper way to create a chart, and then do some kind of clean-up after, and still show the chart on the webpage?
This is the function for barChart
**function barChart(barChartVal) {
const color = new chartColor();
new Chart(document.getElementById("chart-area-last-5-runs"), {
type: 'bar',
data: {
labels: [barChartVal[5][0], barChartVal[5][1], barChartVal[5][2], barChartVal[5][3], barChartVal[5][4]],
datasets: [{
data: [barChartVal[0][0], barChartVal[0][1], barChartVal[0][2], barChartVal[0][3], barChartVal[0][4]],
label: 'Passed',
backgroundColor: color.green(),
}, {
data: [barChartVal[1][0], barChartVal[1][1], barChartVal[1][2], barChartVal[1][3], barChartVal[1][4]],
label: 'Failed',
backgroundColor: color.red(),
}, {
data: [barChartVal[2][0], barChartVal[2][1], barChartVal[2][2], barChartVal[2][3], barChartVal[2][4]],
label: 'Error',
backgroundColor: color.yellow(),
}, {
data: [barChartVal[3][0], barChartVal[3][1], barChartVal[3][2], barChartVal[3][3], barChartVal[3][4]],
label: 'Not Run',
backgroundColor: color.blue(),
}, {
data: [barChartVal[4][0], barChartVal[4][1], barChartVal[4][2], barChartVal[4][3], barChartVal[4][4]],
label: 'Not Applicable',
backgroundColor: color.black(),
}]
},
options: {
scales: {
xAxes: [{
stacked: true,
ticks: {
display: false //this will remove only the label
}
}],
yAxes: [{ stacked: true }]
},
tooltips: {
/* tooltip text made smaller to longer labels fit */
mode: 'index',
intersect: false,
titleFontSize: 14,
bodyFontSize: 13,
bodySpacing: 0,
titleSpacing: 0,
xPadding: 2,
yPadding: 2,
cornerRadius: 2,
titleMarginBottom: 2
},
hover: {
mode: 'index',
intersect: false
},
animation: false, //No animations
parsing: false,
normalized: true
}
});
}**

Yes you can do something like that, you can transform the chart to an image and display that, then you can delete your chart which will free up the memory. Downside of this will be that its not interactable anymore:
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'orange'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
backgroundColor: 'pink'
}
]
},
options: {
animation: false
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chartContainer = document.getElementById('chartJSContainer');
const chartImage = document.getElementById('chartImage');
const chart = new Chart(ctx, options);
const base64Chart = chart.toBase64Image();
// Set image source to chart image
chartImage.src = base64Chart;
// Destroy chart and remove canvas
chart.destroy();
chartContainer.remove();
<body>
<img id="chartImage">
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>

Related

How to add charts to mail body in PHP

I need to add a chart to my auto generated mail in PHP, after following the documentation from https://quickchart.io/documentation/ I have initiated a method as follows,
$chartConfig_datavolume = "{
type: 'line',
data: {
labels: [$date_array2_new],
datasets: [
{
backgroundColor: 'rgb(2, 39, 107)',
borderColor: 'rgb(2, 39, 107)',
data: [$value_array2_datavolume],
fill: false,
}
],
},
options: {
title: {
display: true,
text: 'Total Volume',
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
max: 5000 ,
min: 3000
}
}]
},
},
}";
$chartUrl_datavolume = 'https://quickchart.io/chart?w=400&h=200&c=' . urlencode($chartConfig_datavolume);
$messagenew.=nl2br(" \r\n \r\n");
$messagenew.= "Please see chart below:<br><br><img src=\"$chartUrl_datavolume\">";
This code will generate a chart as I need but the issue is with the scale,
scales: {
yAxes: [{
ticks: {
max: 5000 ,
min: 3000
}
}]
},
When I remove this part, the chart is generating but when I add this part chart is not generating. But with the editor used in quickchart, I could generate a chart with this part as well. Can someone help me to solve this issue.
Note: I am using this script in my RHEL 8 server and PHP 7.2.24 is installed on it

Highcharts diffent color # Temperature Line

I have a question about highcharts: How can I display my temperature line in red above 0°C and blue below 0°C ? My code currently looks like this:
Highcharts.chart('temperature', {
title: {
text: ''
},
chart: {
type: 'combo-multi-axes',
alignTicks: false,
zoomType: 'x',
animation: true,
events: {
load: function() {
fetchLatestData(this);
}
}
},
yAxis: 1,
name: 'Temperatur',
color: '#de1312',
type: 'spline',
zIndex: 10,
],
Use color and negativeColor properties:
series: [{
...,
color: 'red',
negativeColor: 'blue'
}]
Live demo: http://jsfiddle.net/BlackLabel/9hnef5x2/
API Reference:
https://api.highcharts.com/highcharts/series.line.negativeColor
https://api.highcharts.com/highcharts/series.line.color

Where is my error when trying to display this graph with Chart.js?

Within my Laravel project I am implementing the chart.js library trying to visualize a bar graph.
Which should show all work orders in finished status that were assigned to users with the operator role.
When you want to graph, simply no data is displayed, it is an empty graph.
This is my ReportController controller with this method public function getChart () I do my query
public function getChart(Request $request)
{
$_orders = DB::table('users')
->join('orders','orders.user_id','=','users.id')
->join('model_has_roles', 'users.id', '=', 'model_has_roles.model_id')
->select('users.id','users.name', DB::raw('COUNT(orders.id) as orders_by_user'), 'model_has_roles.role_id as rol')
->where('model_has_roles.role_id', '2');
$_orders->groupBy('orders.user_id', 'users.id', 'users.name', 'model_has_roles.role_id');
$orders=$_orders->get();
return ['orders' => $orders];
}
This is the result of my query: as it is observed I have what I need username and the number of orders completed per user.
{
"orders": [
{
"id": 4,
"name": "Luis",
"orders_by_user": 2,
"rol": 2
},
{
"id": 6,
"name": "Jose",
"orders_by_user": 1,
"rol": 2
},
{
"id": 7,
"name": "Miguel",
"orders_by_user": 1,
"rol": 2
}
]
}
Here is an important question: is the JSON structure returned by my query correct? With this result can I graph?
This is my report.js file for the graph:
With the renderChart() method:
I make the graph, through the data obtained in my ajax call.
With the getChartData () method:
I make my ajax call.
function renderChart(data, labels) {
var ctx = document.getElementById("orders").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'ordenes',
data: data,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderWidth: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
title: {
display: true,
text: "Ordenes en estado terminado"
},
}
});
}
function getChartData() {
$.ajax({
url: '/admin/reports/getChart',
type: 'GET',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
dataType: 'json',
success: function (data) {
// console.log(data);
var data = [];
var labels = [];
for (var i in data) {
data.push(data[i].orders_by_user);
labels.push(data[i].name);
}
renderChart(data, labels);
},
error: function (data) {
console.log(data);
}
});
}
$("#renderBtn").click(
function () {
getChartData();
}
);
In other words I am looking to optimize my query using eloquent, so that it returns a valid JSON response for chart.js.
Dump those data obtained through an ajax call and draw
Could you help me find and solve my error?
UPDATED 1
Just in case if any error arises change my for: for (var i in data) to this: for (var i in response)
So it looks like this:
for (var i in response) {
data.push(response[i].orders_by_user);
labels.push(response[i].name);
}
I think that I am not accessing correctly the data that I get from my query to later graph.
In the console I see the following information:
{orders: Array(3)}
orders: Array(3)
0: {id: 4, name: "Luis", orders_by_user: 2, rol: 2}
1: {id: 6, name: "Jose", orders_by_user: 1, rol: 2}
2: {id: 7, name: "Miguel", orders_by_user: 1, rol: 2}
length: 3
__proto__: Array(0)
__proto__: Object
Orders is my array, so how can I just access orders_by_user and name and correctly pass it to my data.push and labels.push
try something like this but it doesn't work:
data.push(response[i].orders.orders_by_user);
labels.push(response[i].orders.name);

How to show values on pie or bar graph chart in php using chart.js

I want to show values on graphs. i search alot but could not find my solution.
Here is the code below:
<script>
var ctx = document.getElementById("barChart");
ctx.height = 100;
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: <?php echo json_encode($Division); ?>,
datasets: [{
label: 'Target',
data: <?php echo json_encode($TARGET_QTY); ?>,
//backgroundColor: "rgba(255, 159, 64, 0.2)",
backgroundColor: "rgb(231, 123, 126)",
borderColor: "rgb(219, 219, 219)",
borderWidth: 1
},
{
label: 'Actual',
data: <?php echo json_encode($DISPATCH_QTY); ?>,
backgroundColor: "rgb(0, 191, 255)",
borderColor: "rgb(252, 252, 252)",
borderWidth: 1
}
]
},
options: {
responsive: true,
tooltips: {
"enabled": false
},
scales: {
yAxes: [{
gridLines: {
display:false,
},
ticks: {
beginAtZero:true
}
}]
},
title: {
display: true,
// position:"bottom",
text: 'Target vs Actual Dispatch'
},
hover: {
// Overrides the global setting
mode: 'label'
},
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i)
{
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
},
/*legend: {
display: true,
// position : "bottom",
labels: {
fontColor: 'rgb(0, 0, 0)'
}
}*/
}
});
</script>
<div class="row">
<div class="col-md-12">
<div class="chart">
<canvas id="barChart" style="position: relative; height: 300px;"></canvas>
</div>
</div>
</div>
I search alot but could not show values in the bar graph. In this code value will be shown on the top of the graph but could not show on the bar. i want to show value on the bars of graph. either its a bar chart or pie chart. i use chart.js library. Please help me to get rid of this situation. Thanks in Advance.

Get current date values to own hours

I get values to MySql database everyday at each hour.
I got site with highcharts, but I cant get it to work.
I need to get current day values from MySql organized to own hours.
Here is my Highcharts code:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript">
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'chart',
defaultSeriesType: 'spline'
},
title: {
text: "Today's Values"
},
subtitle: {
text: 'Values by Hour'
},
credits: {
enabled: false
},
xAxis: {
categories: ['12AM', '1AM', '2AM', '3AM', '4AM', '5AM',
'6AM', '7AM', '8AM', '9AM', '10AM', '11AM','12PM', '1PM', '2PM', '3PM', '4PM', '5PM',
'6PM', '7PM', '8PM', '9PM', '10PM', '11PM']
},
yAxis: {
min: 0,
title: {
text: 'Values'
},
labels: {
formatter: function() {
return this.value
}
}
},
tooltip: {
valueDecimals: 2,
crosshairs: true,
shared: true,
formatter: function() {
return '$' + this.y;
}
},
plotOptions: {
spline: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 1
}
}
},
series: [{
name: 'Values',
data: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}]
});
});
</script>
Here is pic from MySql database how it looks like
chart
So, I need all values from MySql categorized to own hours at chart.
It should count values + show it at own category, any idea how to do this?
Im stuck with this beacause I dont know how to do this.
I advice to familiar with article about preprocessing data form MySQL http://docs.highcharts.com/#preprocessing-data-from-a-database
You should export your data from php as JSON, then if you would like you use categories for xAxis, you need to parse your JSON and push appropaite data to correct place.Similar with data points in series.

Categories