I've adapted the example on this site and have managed to get to a position where I can retrieve data from my MySql database and plot it ok, but I can't format the X axis as a date time axis correctly.
linegraph.html:
<!DOCTYPE html>
<html>
<head>
<title>ChartJS - LineGraph</title>
<style>
.chart-container {
width: 1000px;
height: auto;
}
</style>
</head>
<body>
tst1
<div class="chart-container">
<canvas id="mycanvas"></canvas>
</div>
tst2
<!-- javascript -->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/Chart.js"></script>
<script type="text/javascript" src="js/linegraph.js"></script>
</body>
</html>
followersdata.php
<?php
//setting header to json
header('Content-Type: application/json');
//database
define('DB_HOST', 'localhost');
define('DB_USERNAME', 'xxxxxxxxxxxxxxxxxxxxx');
define('DB_PASSWORD', 'xxxxxxxxxxxxxxxxxxxxx');
define('DB_NAME', 'test');
//get connection
$mysqli = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
if(!$mysqli){
die("Connection failed: " . $mysqli->error);
}
//query to get data from the table
$query = sprintf("SELECT reading_time, value1 FROM Sensor");
//execute query
$result = $mysqli->query($query);
//loop through the returned data
$data = array();
foreach ($result as $row) {
$data[] = $row;
}
//free memory associated with result
$result->close();
//close connection
$mysqli->close();
//now print the data
print json_encode($data);
Example output of followersdata.php
[{"reading_time":"2020-02-24 22:38:48","value1":"1.10"},{"reading_time":"2020-02-24 22:39:18","value1":"1.10"},{"reading_time":"2020-02-24 22:39:49","value1":"1.10"},{"reading_time":"2020-02-24 22:40:19","value1":"1.10"},{"reading_time":"2020-02-24 22:40:49","value1":"1.10"},{"reading_time":"2020-02-24 22:41:19","value1":"1.10"},{"reading_time":"2020-02-24 22:41:49","value1":"1.10"},{"reading_time":"2020-02-24 22:42:19","value1":"1.10"},{"reading_time":"2020-02-24 22:42:49","value1":"1.10"},{"reading_time":"2020-02-24 22:43:19","value1":"1.10"},{"reading_time":"2020-02-24 22:43:50","value1":"1.10"},{"reading_time":"2020-02-24 22:44:20","value1":"1.10"},{"reading_time":"2020-02-24 22:44:50","value1":"1.10"},{"reading_time":"2020-02-24 22:45:20","value1":"1.10"},{"reading_time":"2020-02-24 22:45:50","value1":"1.10"},{"reading_time":"2020-02-24 22:46:21","value1":"1.10"},{"reading_time":"2020-02-24 22:46:51","value1":"1.10"},{"reading_time":"2020-02-24 22:47:21","value1":"1.10"},
linegraph.js:
$(document).ready(function(){
$.ajax({
url : "followersdata.php",
type : "GET",
success : function(data){
console.log(data);
var datetime = [];
var value1 = [];
//var twitter_follower = [];
//var googleplus_follower = [];
for(var i in data) {
datetime.push(data[i].reading_time);
value1.push(data[i].value1);
//twitter_follower.push(data[i].twitter);
//googleplus_follower.push(data[i].googleplus);
}
var chartdata = {
labels: datetime,
datasets: [
{
label: "Value1",
fill: false,
lineTension: 0.1,
backgroundColor: "rgba(59, 89, 152, 0.75)",
borderColor: "rgba(59, 89, 152, 1)",
pointHoverBackgroundColor: "rgba(59, 89, 152, 1)",
pointHoverBorderColor: "rgba(59, 89, 152, 1)",
data: value1
//},
//{
// label: "twitter",
// fill: false,
// lineTension: 0.1,
// backgroundColor: "rgba(29, 202, 255, 0.75)",
// borderColor: "rgba(29, 202, 255, 1)",
// pointHoverBackgroundColor: "rgba(29, 202, 255, 1)",
// pointHoverBorderColor: "rgba(29, 202, 255, 1)",
// data: twitter_follower
//},
//{
// label: "googleplus",
// fill: false,
// lineTension: 0.1,
// backgroundColor: "rgba(211, 72, 54, 0.75)",
// borderColor: "rgba(211, 72, 54, 1)",
// pointHoverBackgroundColor: "rgba(211, 72, 54, 1)",
// pointHoverBorderColor: "rgba(211, 72, 54, 1)",
// data: googleplus_follower
}
],
options: {
maintainAspectRatio: false,
animation: false,
legend: {display: true },
scales:{xAxes: [{type: 'time',time: {unit: 'day',displayFormats: { 'day': 'MMM D' }}}]}
}
};
var ctx = $("#mycanvas");
var LineGraph = new Chart(ctx, {
type: 'line',
data: chartdata
});
},
error : function(data) {
}
});
});
Resulting chart:
I have tried using the options
options: {
maintainAspectRatio: false,
animation: false,
legend: {display: true },
scales:{xAxes: [{type: 'time',time: {unit: 'day',displayFormats: { 'day': 'MMM D' }}}]}
}
But it doesn't seem to format the axis as MMM D, or if I try hours, as hours etc.
Where am I going wrong? How can I get the Options to work as the legend doesn't display either.
The problem in your code is that the chart options is nested inside the data object and actually ignored by Chart.js. Move it up to the next hierarchically level. Otherwise the xAxis definition looks just fine. There's also no need for explicitly parsing the date as one comment suggests since it is in a format that can be parsed by Date.
Alternatively to your xAxis definition, you can do it the following simpler way, the default display format of unit: 'day' is actually what you're looking for ('MMM D').
xAxes: [{
type: 'time',
time: {
unit: 'day'
}
}]
See below simplified example:
const data = [
{"reading_time":"2020-02-10 22:38:48","value1":"1.10"},
{"reading_time":"2020-02-11 22:39:18","value1":"1.20"},
{"reading_time":"2020-02-12 22:39:49","value1":"1.40"},
{"reading_time":"2020-02-13 22:40:19","value1":"1.10"},
{"reading_time":"2020-02-14 22:40:49","value1":"1.20"},
{"reading_time":"2020-02-15 22:41:19","value1":"1.30"}
];
new Chart("mycanvas", {
type: 'line',
data: {
labels: data.map(o => o.reading_time ),
datasets: [{
label: "Value1",
fill: false,
borderColor: "rgba(59, 89, 152, 1)",
data: data.map(o => o.value1)
}],
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'day'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<canvas id="mycanvas" height="90"></canvas>
Related
i want to loop datasets of Chart.Js using foreach in PHP, instead of looping the data once every datasets, what i get is this
My question is : how to render it properly? because i've quite frustrated by this.
Here is my controller :
$volumeTotalSAP = MonthlyPerModel::whereYear('tgl' , '=' , Carbon::now())->where('plant','=', 'SAP')->get();
if($volumeTotalSAP->isEmpty()){
$dateModelSAP[] = 'Data Tidak Ditemukan';
$modelNameSAP[] = [];
$volumeModelSAP[] = [];
$datasetSAP[] = [];
}else{
foreach ($volumeTotalSAP as $modelsap) {
$dateModelSAP[] = Carbon::parse($modelsap->tgl)->isoFormat('MMMM');
$modelNameSAP = $modelsap->model;
$volumeModelSAP = $modelsap->volume;
$datasetSAP[] = [
'label' => $modelNameSAP,
'data' => $volumeModelSAP,
'backgroundColor' => '#'.str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT),
];
}
};
Here is my script to the Chart:
var dateModelSAP = JSON.parse('{!! json_encode($dateModelSAP) !!}');
var datasetSAP = [{
label: JSON.parse('{!! json_encode($modelNameSAP) !!}'),
data: JSON.parse('{!! json_encode($volumeModelSAP) !!}'),
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)'
}];
const ctxTotalModelSAP = document.getElementById('chartTotalPerModelSAP');
var TotalModelSAP = new Chart(
ctxTotalModelSAP,
config = {
type: 'bar',
data : {
labels: dateModelSAP,
datasets: datasetSAP
},
plugins: [ChartDataLabels],
options: {
plugins: {
legend:{
position: 'bottom'
}
},
layout: {
padding : {
top: 30
}
},
responsive: true,
scales: {
x:{
stacked: true,
},
y: {
stacked: true,
beginAtZero: true
}
}
}
}
);
Any suggestions helps! Thank you!
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>
I am trying to add chart data from PHP file.
Chart is drawn when I add the values manually - data: [28,20,2,7],
But chart doesn't appear, when I add the data from PHP file.
Where am I going wrong here?
How can I add these values from PHP output?
My PHP code:
echo json_encode(array($rectotals,$recX,$recXS,$recXM));
Php file output (this looks OK):
[28,20,2,7]
Here is how i get the data:
$.getJSON("chartdata.php").then(function(chart_data1){
alert(chart_data1);
})
Alert result (This is also OK):
localhost:63342 says 28,20,2,7
My chartjs script:
<canvas id="myChart" width="400" height="340"></canvas>
<script>
$.getJSON("chartdata.php").then(function(chart_data){
alert(chart_data);
})
//setTimeout(function() { alert(db_data1); }, 2000);
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['Total', 'Size X', 'Size XS', 'Size SM],
datasets: [{
data: chart_data,
backgroundColor: [
'rgba(54, 162, 235, 1)',
'rgb(255,99,132)',
'rgba(255, 159, 64, 1)',
'rgb(255,206,86)'
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 99, 132, 1)',
'rgb(255,159,64)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 0.5,
}]
},
options: {
responsive: true,
animation: {
duration: 2800,
easing: 'easeInOutQuad',
},
layout: {
padding: {
left: 0,
right: 0,
top: 15,
bottom: 0
}
},
cutoutPercentage : 75,
legend: {
display: false,
position: 'bottom',
fullWidth: true,
}
}
});
</script>
var ctx = document.getElementById("myChart").getContext("2d");
let myChart = null;
function getConfig(chart_data){
return ({
type: "pie",
data: {
labels: ["Total", "Size X", "Size XS", "Size SM"],
datasets: [
{
data: chart_data,
backgroundColor: [
"rgb(54,162,235)",
"rgb(255,99,132)",
"rgba(255, 159, 64, 1)",
"rgb(255,192,33)"
],
borderColor: [
"rgb(255,255,255)",
"rgb(255,255,255)",
"rgb(255,255,255)",
"rgb(255,255,255)"
],
hoverBackgroundColor: ['#373739', '#373739', '#373739', '#373739'],
}
]
},
options: {
responsive: true,
animation: {
duration: 0, //2800, I remove animation time
easing: "easeInOutQuad"
},
tooltips: {
mode: 'nearest'
},
layout: {
padding: {
left: 0,
right: 0,
top: 15,
bottom: 0
}
},
cutoutPercentage: 66,
legend: {
display: false,
position: "bottom",
fullWidth: true
}
}
});
}
function getJSON(){
// emulate fetch
return new Promise(resolve => {
const chart_data = [
Math.random() * 50,
Math.random() * 50,
Math.random() * 50,
Math.random() * 50
];
resolve(chart_data)
})
}
function update(){
getJSON().then(data => {
myChart.data.datasets[0].data = data;
myChart.update();
});
}
function initializeChart() {
getJSON().then(data => {
myChart = new Chart(ctx, getConfig(data));
});
}
initializeChart();
document.getElementById('update_chart').addEventListener('click', update, false);
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div>
<button id="update_chart">Update Records</button>
</div>
<canvas id="myChart" width="50" height="40"></canvas>
</body>
</html>
Query.getJSON() makes an asynchronous HTTP request. Once the result arrives, the chart has already been created and the obtained data has no effect on the chart.
To solve this, place the chart creation inside the then callback as follows.
$.getJSON("chartdata.php").then(function(chart_data) {
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'pie',
...
});
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.
i want to chart (PHP) some info that i have on a BD oracle
I have this file to get the info in a JSON format:
more data.php
<?php
header('Content-Type: application/json');
$conn = oci_connect('*****', '*****', 'HOSTNAME_FQDN:1521/ORACLE_SID');
$graph=sprintf("select to_char(FECHA,'dd/mm/yyyy hh24:mi:ss') as Timestamp
,CPU
,BCPU
,BD_SCHEDULER
,UIO
from sginfgbp.v_grafico_oem
order by fecha desc");
$parse=oci_parse($conn,$graph);
oci_execute($parse);
$data=array();
while($row1 = oci_fetch_array($parse)){
$data[]=$row1;
}
print json_encode($data);
?>
So, when i call http://SERVERNAME/data.php
i get a JSON dataset
TIMESTAMP "03/07/2018 11:39:00"
CPU "0"
BCPU "0"
BD_SCHEDULER "0"
UIO "0"
TIMESTAMP "03/07/2018 11:38:00"
CPU "0"
BCPU "2"
BD_SCHEDULER "0"
UIO "0"
...
..
..
.
.
and so on.
How could i chart this info on a stacked area?
X axis = timestamp
Y axis = (value 1,color 1) , (value 2,color 2) , (value 3,color 3) , (value 4,color 4)
I am trying to "clone" the info on the thread:
How to make a graph using PHP from oracle
but i can not fix it.....
This is my bargraph.html (the URL that i finally call on the browser)
more bargraph.html
<!DOCTYPE html>
<html>
<head>
<title>ChartJS - BarGraph</title>
<style type="text/css">
#chart-container {
width: 640px;
height: auto;
}
</style>
</head>
<body>
<div id="chart-container">
<canvas id="mycanvas"></canvas>
</div>
<!-- javascript -->
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="js/Chart.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
more app.js
$(document).ready(function(){
$.ajax({
url: "http://localhost/psm/admin/data.php",
method: "GET",
success: function(data) {
console.log(data);
var timestamp = [];
var cpu = [];
var bcpu = [];
var bd_scheduler = [];
var uio = [];
for(var i in data) {
timestamp.push("TIMESTAMP " + data[i].TIMESTAMP);
cpu.push(data[i].CPU);
bcpu.push(data[i].BCPU);
bd_scheduler.push(data[i].BD_SCHEDULER);
uio.push(data[i].UIO);
}
var chartdata = {
labels: timestamp,
datasets : [
{
label: 'Label ONE',
backgroundColor: 'rgba(200, 200, 170, 0.65)',
borderColor: 'rgba(180, 190, 200, 0.75)',
hoverBackgroundColor: 'rgba(220, 200, 200, 1)',
hoverBorderColor: 'rgba(210, 200, 200, 1)',
data: cpu
}
{
label: 'Label DOS',
backgroundColor: 'rgba(200, 200, 200, 0.75)',
borderColor: 'rgba(200, 200, 200, 0.75)',
hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: bcpu
}
]
};
var ctx = $("#mycanvas");
var barGraph = new Chart(ctx, {
type: 'stackedArea',
data: chartdata
});
},
error: function(data) {
console.log(data);
}
});
});
You should try setting the type as "line" and the "stacked" setting in the yAxes options:
scales: {
yAxes: [{
stacked: true,
}]
},
In addition, you missed a comma "," between the 2 datasets objects.
Here's a Codepen working example of a stackedArea chart.
If you could provide the JSON response from the server, we can check if the data is suitable to work with Chart.js.