I want to load the ChartJs Chart after an ajax call. But unfortunately, it showing Undefined variable errors for all ChartJS php variables.
Target:
Change the chart based on user select from the dropdown list, each selection option is basically a JSON link from where we fetch the data to show with chartjs.
What I have done so far:
Setup an AJAX call which works ok for each user select both "default"
on page load plus "on change" options.
Added Chartjs code after the successful ajax request section.
Tested all JSON codes & php data its all working ok.
All ajax return data for chartjs php variables are ok.
Issues:
Undefined variable error for all chartjs PHP variables (name,
cot_labels,
cot_values,cot_values2,cot_values3,cot_values4,cot_values5)
No data showing on chart.
Chart also not refreshing with new data when user select another option.
Here is the Javascript part:
$(document).ready(function(){
$.ajax({
url: "./url.php",
type: "POST",
data: {
cur: $("#cur").val()
},
success: function(data) {
alert(data);
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: [<?php echo '"'.$cot_labels.'"'; ?>],
datasets: [{
data: [<?php echo $cot_values; ?>],
label: "A",
borderColor: "#3e95cd",
fill: false
}, {
data: [<?php echo $cot_values2; ?>],
label: "B",
borderColor: "#8e5ea2",
fill: false
} ,
{
data: [<?php echo $cot_values3; ?>],
label: "C",
borderColor: "#085b83",
fill: false
} ,
{
data: [<?php echo $cot_values4; ?>],
label: "D",
borderColor: "#1c2925",
fill: false
} ,
{
data: [<?php echo $cot_values5; ?>],
label: "E",
borderColor: "#b9801d",
fill: false
}
]
},
options: {
title: {
display: true,
text: '<?php echo $name; ?>'
},
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
responsiveAnimationDuration: 0, // animation duration after a resize
}
});
}
});
$('#cur').on('change', function() {
$.ajax({
url: "./url.php",
type: "POST",
data: {
cur: $("#cur").val()
},
success: function(data) {
alert(data);
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: [<?php echo '"'.$cot_labels.'"'; ?>],
datasets: [{
data: [<?php echo $cot_values; ?>],
label: "A",
borderColor: "#3e95cd",
fill: false
}, {
data: [<?php echo $cot_values2; ?>],
label: "B",
borderColor: "#8e5ea2",
fill: false
} ,
{
data: [<?php echo $cot_values3; ?>],
label: "C",
borderColor: "#085b83",
fill: false
} ,
{
data: [<?php echo $cot_values4; ?>],
label: "D",
borderColor: "#1c2925",
fill: false
} ,
{
data: [<?php echo $cot_values5; ?>],
label: "E",
borderColor: "#b9801d",
fill: false
}
]
},
options: {
title: {
display: true,
text: '<?php echo $name; ?>'
},
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
responsiveAnimationDuration: 0, // animation duration after a resize
}
});
}
});
});
});
<select id="cur" name="cur">
<option value="<?php echo $euro;?>">EURO</option>
<option value="<?php echo $pound;?>">UK</option>
</select>
<canvas id="line-chart" width="800" height="450"></canvas>
Here is the PHP Part:
$euro = "URL";
$pound = "URL";
//AJAX CALL
if (isset($_POST['cur'])) {
$cur = filter_input(INPUT_POST, 'cur', FILTER_SANITIZE_STRING);
//Build arrays
$cot_label_arr = array();
$cot_value_arr = array();
$cot_value_arr2 = array();
$cot_value_arr3 = array();
$cot_value_arr4 = array();
$cot_value_arr5 = array();
$json=file_get_contents($cur);
$data = json_decode($json);
foreach ($data as $item ) {
$name = $item->name;
// echo $item->newest_available_date;
foreach($item as $value => $value_1){
if (is_array($value_1) || is_object($value_1))
{
foreach($value_1 as $value_2 ){
if (is_array($value_2) || is_object($value_2))
{
$cot_label_arr[] = date('M j Y',strtotime($value_2[0])); //pull dates
$cot_value_arr[] = $value_2[1];
$cot_value_arr2[] = $value_2[2];
$cot_value_arr3[] = $value_2[3];
$cot_value_arr4[] = $value_2[4];
$cot_value_arr5[] = $value_2[5];
}
}
}
}
}
$cot_labels = array_reverse($cot_label_arr); //reverse the data for ASC
$cot_values = array_reverse($cot_value_arr); //reverse the data for ASC
$cot_values2 = array_reverse($cot_value_arr2); //reverse the data for ASC
$cot_values3 = array_reverse($cot_value_arr3); //reverse the data for ASC
$cot_values4 = array_reverse($cot_value_arr4); //reverse the data for ASC
$cot_values5 = array_reverse($cot_value_arr5); //reverse the data for ASC
//----
$cot_labels = implode('","', $cot_labels); //comma sep
$cot_values = implode(", ", $cot_values); //comma sep
$cot_values2 = implode(", ", $cot_values2); //comma sep
$cot_values3 = implode(", ", $cot_values3); //comma sep
$cot_values4 = implode(", ", $cot_values4); //comma sep
$cot_values5 = implode(", ", $cot_values5); //comma sep
exit;
} // End of ajax call
If I use echo $cot_values; inside the ajax call, then I get to see correct data. But chartjs is not loading with it. Here is the screenshot of what I get returned for $cot_values.
Not sure why I am getting undefined data error for chartjs php variables whereas I am calling the chartjs javascript after the successful ajax call. Plus why the correct data is not loading on the chart.
UPDATE: with MLStud coding
Now no longer undefined php chartjs variable error as we are using java json data. But the chart is not loading, in the place of the chart a white blank space is showing. I have tested all data for any kind of wrong format, but it was ok.
Here is the updated coding part:
PHP:
if (isset($_POST['cur'])) {
........
$cot_labels = implode(", ", $cot_labels); //edited as it was showing date with extra ""
$cot_values = implode(", ", $cot_values); //comma sep
$cot_values2 = implode(", ", $cot_values2); //comma sep
$cot_values3 = implode(", ", $cot_values3); //comma sep
$cot_values4 = implode(", ", $cot_values4); //comma sep
$cot_values5 = implode(", ", $cot_values5); //comma sep
// New added
$result = array(
'cot_labels'=>$cot_labels,
'cot_values'=>$cot_values,
'cot_values2'=>$cot_values2,
'cot_values3'=>$cot_values3,
'cot_values4'=>$cot_values4,
'cot_values5'=>$cot_values5,
'name'=>$name
);
print_r(json_encode($result));
exit;
} // End of ajax call
Javascript + HTML :
$(document).ready(function(){
var ctx = document.getElementById("myChart").getContext('2d');
$.ajax({
url: "./url.php",
type: "POST",
data: {
cur: $("#cur").val()
},
success: function(data) {
alert(data);
var datos = JSON.parse(data);
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: datos.cot_labels, ///in this way you access the data of the returned json
datasets: [{
data: datos.cot_values,///in this way you access the data of the returned json
label: "A",
borderColor: "#3e95cd",
fill: false
}, {
data: datos.cot_values2,
label: "B",
borderColor: "#8e5ea2",
fill: false
}]
},
options: {
title: {
display: true,
text: data.name
},
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
responsiveAnimationDuration: 0, // animation duration after a resize
}
});
}
});
$('#cur').on('change', function() {
$.ajax({
url: "./url.php",
type: "POST",
data: {
cur: $("#cur").val()
},
success: function(data) {
var datos = JSON.parse(data);
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: datos.cot_labels, ///in this way you access the data of the returned json
datasets: [{
data: datos.cot_values,///in this way you access the data of the returned json
label: "A",
borderColor: "#3e95cd",
fill: false
}, {
data: datos.cot_values2,
label: "B",
borderColor: "#8e5ea2",
fill: false
}]
},
options: {
title: {
display: true,
text: data.name
},
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
responsiveAnimationDuration: 0, // animation duration after a resize
}
});
}
});
});
});
<select id="cur" name="cur">
<option value="<?php echo $euro;?>">EURO</option>
<option value="<?php echo $pound;?>">UK</option>
</select>
<canvas id="myChart" width="800" height="450"></canvas>
For more further verification here is the date format how it looks like: (when we call it after successful ajax call)
alert(datos.cot_labels);
To take the value of variables you have to access the json obtained as an answer (data) and you have to convert "val1, val2, ..." in the vector [val1, val2, ...] with split:
var ctx = document.getElementById("myChart").getContext('2d');
$.ajax({
url: "server.php",
type: "POST",
data: {
...
},
success: function(data) {
var datos = JSON.parse(data);
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: datos.cot_labels.split(','), ///in this way you access the data of the returned json
datasets: [{
data: datos.cot_values.split(','),///in this way you access the data of the returned json
label: "A",
borderColor: "#3e95cd",
fill: false
}, {
data: datos.cot_values2.split(','),
label: "B",
borderColor: "#8e5ea2",
fill: false
}]
},
options: {
title: {
display: true,
text: datos.name
},
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
responsiveAnimationDuration: 0, // animation duration after a resize
}
});
}
});
Result:
Related
I try to create a graph using Chart.js and get the data from database, but I am confused how to pass the data to an array variable in view.
This is the Controller
public function ApiLaporanBulanan()
{
$data = DB::table("transaksipenjualan")->select(DB::raw('EXTRACT(MONTH FROM tanggaltransaksi) AS Bulan, SUM(total) as Pendapatan'))
->groupBy(DB::raw('EXTRACT(MONTH FROM tanggaltransaksi)'))
->get();
return response()->json($data);
//Accessing Data
dd($data[0]->Bulan);
}
This is the script in view
<script>
var url = "{{url('laporan/pendapatanAPI')}}";
var Bulan = [];
var Pendapatan = [];
$(document).ready(function(){
$.get(url, function(response){
response.forEach(function(data){
Bulan.push(data->Bulan);
Pendapatan.push(data->Pendapatan);
});
var ctx = document.getElementById("canvas").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Bulan,
datasets: [{
label: 'Nilai Pendapatan',
data: Pendapatan,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
});
});
</script>
You can create two array in your controller.
$label = [];
$dataset = [];
and loop through your collection and push data to these arrays
foreach($data as $value){
$label[] = $value->data_field;
$dataset[] = $value->data_field;
}
And pass it to your blade and assign these array to your chart
...
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Bulan,
datasets: [{
label: 'Nilai Pendapatan',// label data
data: Pendapatan, // dataset
borderWidth: 1
}]
},
....
I made a dynamic highstock (highchart) like this example, but with data from PHP. I have tried my code, but the results did not appear. How to make dynamic highstock with PHP?
PHP code :
<?php
include("connection.php");
$data = array();
$count = 0;
$result = mysqli_query($koneksi,"SELECT * FROM data ORDER BY time ASC ") or die ("Connection error");
while($row = mysqli_fetch_array($result)) {
$x = strtotime($row['time']) * 1000;
$y = (float)$row['temperature'];
$data[] = array($x, $y);
$count++;
}
echo json_encode($data);
mysqli_close($koneksi);
?>
JSON from PHP:
[[1535981121000,40],[1535981432000,32.9],[1535981492000,32.7],[1535981552000,32.6],[1535981618000,32.6],[1535981672000,32.6],[1535981732000,32.6],[1535981793000,32.6],[1535981854000,32.6],[1535981913000,32.5],[1535981993000,32.4],[1535982034000,32.4],[1535982215000,32.4],[1535982287000,32.3],[1535982335000,32.3],[1535982396000,32.5],[1536576266000,45.2],[1536579542000,62.2],[1536653234000,30.2]]
Javascript code:
<script type="text/javascript">
var chart;
function requestData() {
$.ajax({
url: 'chartTemp.php',
success: function(point) {
var series = chart.series[0],
shift = series.data.length > 20;
// add the point
chart.series[0].addPoint(point, true, shift);
// call it again after one second
setTimeout(requestData, 1000);
},
cache: false
});
}
document.addEventListener('DOMContentLoaded', function() {
chart = Highcharts.stockChart('container', {
chart: {
events: {
load: requestData
}
},
time: {
useUTC: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: true,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: true
},
series: [{
name: 'Random data',
data: data[]
}]
});
</script>
I changed the javascript code above from this example
You are missing either,
// Set the JSON header (in .php)
header("Content-type: text/json");
Or like,
$.ajax({
method: "GET",
url: "test.js",
dataType: "json"
});
Also you have some syntax errors, at the end of javascript code add below (to confirm check in browser's console window),
)};
Your ajax call is returning all of the points in a single json, but the function you are calling looks like don't accept, so check again,
// add the point
chart.series[0].addPoint(point, true, shift);
I have this code for the Highchart column:
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
xAxis: {
type: 'category',
},
yAxis: {
min: 0,
},
...
series: [{
data: [
['Shanghai', 23.7],
['Lagos', 16.1],
['Istanbul', 14.2],
['Karachi', 14.0],
],
}]
});
});
and this file query.php:
<?php
include 'bd_cnx.php';
$sql = "SELECT
...";
$result = $conn->query($sql);
if ($result->num_rows > 0){
while($row = $result->fetch_assoc()){
$ret[] =[$row['NUME_J'], floatval($row['TOTAL'])];
}
}
echo json_encode($ret);
?>
How can I insert the returned values from query.php in the function javascript to series.data?
Thank you!
var data ;
$.ajax({
method:"POST",
url:"query.php",
data:{},
success:
function(response){
data=response;
$('#container').highcharts({
chart: {
type: 'column'
},
xAxis: {
type: 'category',
},
yAxis: {
min: 0,
},
...
series: [{
data: data,
}]
});
},
});
It's covered in the documentation, with examples. Check out their web site: - you may find even more useful ideas. BTW, remember to send the correct JSON Content-Type, or some browsers may balk.
This is one way:
$(function () {
// Get the CSV and create the chart
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=analytics.csv&callback=?', function (csv) {...
You can also get live data.
Finally, you can assign the series variable in several ways, and redraw the chart.
I'm trying to plot data from a mysql table on document load with highcharts:
the html looks like that:
function FetchData(){
//alert("Fetching");
$.ajax({
url: 'php/reports/fetch_data.php',
success: function(data) {
dataTemp = [];
for(i=0;i<data.length;i++){
dataTemp.push(data[i][0]); // '1' index for getting that temp value. '0' for date.
}
c_temperature.series[0].data = dataTemp;
for(i=0;i<data.length;i++){
dataTemp.push(data[i][1]); // '1' index for getting that temp value. '0' for date.
}
c_temperature.series[1].data = dataTemp;
}
});
function DrawCharts(){
c_temperature = new Highcharts.Chart({
chart: {
renderTo: 'dashboard',
defaultSeriesType: 'spline',
},
title: {
text: 'Temperatur'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'Value',
margin: 10
}
},
legend:{
enabled: false
},
credits:{
enabled: false
},
series: [{
name: 'Temperatur',
data: []
}]
});
$(document).ready(function() {
DrawCharts();
FetchDevices();
FetchData();
});
<body>
<div id="dashboard">
</div>
<div class="clear"></div>
</body>
And the php I call looks like that:
try {
$con = new PDO("mysql:host=$servername; dbname=$dbname", $username, $password);#
echo 'Connected</br>';
$sql = "select ZEIT,FEUCHTE,TEMPERATUR,LUX,PITCH from ".$mac.
" order by ID";
foreach($con - > query($sql) as $row) {
$x = $row['ZEIT'];
/*$x = mktime()*1000;*/
$y_h = (float) $row['FEUCHTE'];
/*$y_t=(float)$row['TEMPERATUR'];
$y_l=(float)$row['LUX'];
$y_a=(float)$row['PITCH'];*/
$ret = array($x, $y_h, /*$y_t,$y_l,$y_a,$mac*/ );
echo json_encode($ret);
}
$con = null;
}
The php code successfully returns data.
But I dont see a graph and debugging with the browser console does not give a clue either. Any suggestions what I'm doing wrong?
Beste Regards
You want to use c_temperature.series[0].setData(dataTemp, true); and c_temperature.series[1].setData(dataTemp, true);. By setting the data, you're not actually telling highcharts to redraw the chart, so nothing is happening when you update the data.
I think it has to do with the order in wich you do your operations: firstly you create the chart and then you make the ajax call to fetch the data, but you are not updating the chart.
Try to move the chart creation inside the ajax success callback: first populate the series array with the data received from PHP, then construct the chart passing the serie array as a option; like this:
success: function(data) {
var data_series = [];
/* here populate the data_series array from your PHP results */
new Highcharts.Chart({
/* here other options... */
series: data_series
});
So this is what I'm doing now:
function FetchData(){
$.ajax({
type: "POST",
url: 'php/reports/fetch_data.php',
data: "",
dataType: 'json',
success: function(data) {
var points = data;
c_temperature = new Highcharts.Chart({
chart: {
renderTo: 'dashboard',
defaultSeriesType: 'spline',
},
title: {
text: 'Temperatur'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: '°C',
margin: 10
}
},
legend:{
enabled: false
},
credits:{
enabled: false
},
series: points
});
/*dataTemp = [];
for(i=0;i<data.length;i++){
dataTemp.push(data[0][i]);
}
c_temperature.series[0].setData(dataTemp, true);
for(i=0;i<data.length;i++){
dataTemp.push(data[1][i]);
}
c_temperature.series[1].setData(dataTemp, true);*/
}
});
}
Result: it is showing the graph but still no plot.
The php return has been changed to this:
try {
$con = new PDO("mysql:host=$servername; dbname=$dbname" ,$username, $password);
$sql = "select ZEIT,FEUCHTE,TEMPERATUR,LUX,PITCH from ".$mac." where ID>'60080' order by ID";
$x = array();
$y_h = array();
foreach ($con->query($sql) as $row)
{
$x[]=$row['ZEIT'];
$y_h[]=(float)$row['FEUCHTE'];
$ret = array($x,$y_h);
}
echo json_encode($ret);
$con = null;
}
I have been able to produce results from mysql using:
$myArray=array();
$tempArray = array();
// Get all records
while ( $row = $results->fetch_assoc())
{
$tempArray = $row;
array_push($myArray, $tempArray);
}
echo json_encode($myArray);
$mysqli->close();
?>
And I then included this to produce a chart on my page index.php by using the following Javascript.
what concepts/code am I not understanding/missing to produce a chart based upon my ajax json?
EDITED - SOLUTION:
Final PHP code to produce the json:
while ( $row = $results->fetch_assoc())
{
$tempArray[0] = $row['unix_timestamp(auct.end_date)'];
$tempArray[0] *= 1000;
$tempArray[1] = $row['winning_bid'];
array_push($myArray, $tempArray);
}
echo json_encode ($myArray, JSON_NUMERIC_CHECK);
$mysqli->close();
?>
Final javascript code:
$('#btn_search').click(function(){
txt_search = $('#txt_search').val();
$.ajax({
url: './php/search.php',
type: 'GET',
data: {search: txt_search},
dataType: 'json',
success: function(rows)
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'chartdiv',
type: 'line',
marginRight: 100,
marginBottom: 50
},
title: {
text: 'Whisky Tracking',
x: -20 //center
},
xAxis: {
text: 'EndDate',
type: 'datetime'
},
yAxis: {
title: {
text: 'Price',
color: '#CC680E'
},
plotLines: [{
value: 0,
width: 20,
color: '#CC680E'
}]
},
series: [{
name: txt_search,
xAxis:0,
data: rows,
dataLabels: {
enabled: true,
formatter: function() {
return '£'+ Highcharts.numberFormat(this.y, 0);
}
}
}],
});
}
});
goToByScroll('tracker');
return false;
});
Sample Data from the JSON:
[1306732000000,160],[1306745000000,45],[1306788000000,65],[1306788000000,50],[1306712000000,130],[1306733000000,240],[1306744000000,60],[1306788000000,250],[1306710000000,145]
The problem is that values are strings, for example, your data:
["2011-05-30 00:00:00","130"]
Should be instead:
[1306706400000, 130]
To it's timestamp in ms and true value.
You can read about JSON_NUMERIC_CHECK option for json_encode(string, JSON_NUMERIC_CHECK) to change strings to numbers. But dates to timestamps you need to change on your own.
Edit:
Also the problem was with setting data in doubled array, changed from:
data: [rows]
to:
data: rows