Highcharts with data from mysql database - php

I'm using highcharts plugin to print stats in a codeigniter site.
Now I get the data from my database I manage it but when I print it inside highcharts nothing is printed.
This is my php code:
$arr_point = array();
$check_price = array();
for($i = 1; $i <= 12; $i++){
$sum = 0;
$this->load->model('backend/Notification_model');
$this->db->select('*,');
$this->db->from('booking');
$query = $this->db->get();
foreach ($query->result() as $row){
$sum+=(float)$row->total_with_markup;
}
$arr_point[] = str_replace(',', '.', $sum);
}
$result = array();
array_push($result,$arr_point);
return(json_encode($result));
and this is my highchart configuration:
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: $('#riepilogo option:selected').text()
},
subtitle: {
text: ''
},
xAxis: {
categories: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
]
},
yAxis: {
min: 0,
title: {
text: 'Euro'
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:.2f} euro</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [ {
name: $('#riepilogo options:selected').text(),
data: "<?php echo json_decode($data_chart); ?>"
}]
});
});
if I print json_decode($data_chart) I get this:
Array
if I print ($data_chart I get this:
[["0","297.23","74.41","65.57","2167.32","7649.77","2058.05","146.95","92.55","0","1754.72","0"]]
I have try to not use json_encode, to use json_decode, nothing. Can someone help me? Thanks

The problem is that you create an array in your script:
$arr_point = array();
Try returning just the array and delete:
$result = array();
array_push($result,$arr_point);
and return $array_point;
Or try:
$arr_point = "";
$check_price = array();
for ($i = 1; $i <= 12; $i++) {
$sum = 0;
$this->load->model('backend/Notification_model');
$this->db->select('*,');
$this->db->from('booking');
$query = $this->db->get();
foreach ($query->result() as $row) {
$sum+=(float) $row->total_with_markup;
}
if($arr_point == ""){
$arr_point .= "[";
}
if($arr_point != ""){
$arr_poin .= ",";
}
$arr_point .= str_replace(',', '.', $sum);
}
$arr_point .= "]";
return $arr_point;

Your code contains many injections, so I advice to print json inside your php file like:
echo json_encode($arr, JSON_NUMERIC_CHECK);
Then in javascript call $.getJSON() function and use it in highcahrts, skipping decoding / missing types of data.

Related

Drilldown with MySQL Data

How do i add drilldown function in my column highchart?
<script>
drilldown: {
series: [
<?php
for ($j=0; $j < count($service) ; $j++) {
name: '<?php echo $service[$j]; ?>',
id: '<?php echo $service[$j]; ?>',
data: [
<?php
$sql = $mysqli->query("SELECT DISTINCT(DATE_FORMAT(stamp, '%b %d')) as dateDays from entries where sid = '$arrSID[$j]'");
while ($row = $sql->fetch_assoc()) {
$days[] = $row['dateDays'];
}
for ($k=0; $k < count($days) ; $k++) {
$sql1 = $mysqli->query("SELECT COUNT(*) as totalDayVote FROM entries where DATE_FORMAT(stamp, '%b %d') = '$days[$k]' && sid = '$arrSID[$j]'");
while ($row1 = $sql1->fetch_assoc()) {
$dayVote = $row1['totalDayVote']; ?>
['<?php echo $days[$k]; ?>', <?php echo ($dayVote); ?>],
<?php
}
}
?>
]
}
?>
</script>
The result is i get the first chart that display title of my services and when i click on one of the services it will drilldown entries by day of that specific service.

Using database data to populate a graph

So I currently have graphs with have static data from JQ, I'm attempting to get the data from a DB using PHP. I've began the logic but struggling to move forward, Any ideas would be appreciated.. So far the graph outputs blank, only works when I use static data.
Used 0 in the output array as a test
PHP<?php
$userID = $_SESSION["userid"];
$days = array();
$query = "SELECT timeSpent
FROM gymTime
WHERE userid = '$userID'";
$result = mysqli_query($conn, $query);
$i=0;
while($row = $result->fetch_assoc()) {
$days[$i] = $row["timeSpent"];
$i++;
}
?
JQ <script>
// in php you simply need to create the two arrays and teh functionality will work
// monthly set to minutes
var myTimeMon = ;
var myMonths = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
// weekly data in mins
var myTimeWeek = [<?php echo $days[0]; ?>];
var myDays= ["Mon","Tue","Wed","Thur","Fri","Sat","Sun"];
// default values to be displayed when the page loads
var myLabels = myDays;
var mydata = myTimeWeek;
// store value of radiobutton
var currentValue = "m"
var displayData=[];
function contoMins(){
// change the values of the array
for(i=0; i<mydata.length; i++){
mydata[i]=mydata[i]*60;
}
destroyChart();
}
// destroy the chart so that it does not load on top of itself
function destroyChart(){
window.myBar.destroy();
buildChart();
}
function buildChart(){
displayData = mydata;
var barChartData = {
labels : myLabels,
//barValueSpacing : 25,
//barStrokeWidth : 40,
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: displayData
}
]
}
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, {
barValueSpacing : 10,
});
}
buildChart();
//sendData();
</script>
DB Structure
http://prntscr.com/avdg9r
Webpage
http://prntscr.com/avdgeq
This always sets $i equal to 0.
while($row = $result->fetch_assoc()) {
$i=0;
$days[$i] = $row["timeSpent"];
$i++;
}
Move $i = 0 outside the while loop.
$i=0;
while($row = $result->fetch_assoc()) {
$days[$i] = $row["timeSpent"];
$i++;
}
Also, loop through your $days array.
var myTimeWeek = [<?php echo $days[0]; ?>];
will only display the first element in $days. You need to loop through the array.
var myTimeWeek = [
<?php
$i = 0;
$total = 0;
foreach ($days as $day)
{
if ($i > 0) echo ', ';
echo '"' . $day . '"';
$total = $total + $day;
$i++;
}
?>
]
Move your $i outside the loop-block, otherwise the $i will be 0 for each iteration
$i=0;
while($row = $result->fetch_assoc()) {
$days[$i] = $row["timeSpent"];
$i++;
}

Highcharts data from MySQL / PHP

I am trying to build the data for my Highcharts chart but I'm having trouble when a certain day has no rows.
I.e. I want a chart to show enquiries per day for the current week. If no enquiries were received on Wednesday, then that day is missing from my chart or the data from Thursday falls into Wednesday which is wrong, depending on what I do.
SQL I have:
$W = date('W');
$Y = date('Y');
$SQL = "SELECT DATE_FORMAT(enquiries.dateCreated, '%a') AS name, COUNT(*) AS y
FROM enquiries
WHERE WEEK(enquiries.dateCreated, 1) = $W
AND YEAR(enquiries.dateCreated) = $Y
GROUP BY DAY(enquiries.dateCreated)";
$result = $this->db->prepare($SQL);
$result->execute();
return $result->fetchAll(PDO::FETCH_ASSOC);
And my current attempt to put it into an array which doesn't work:
$enquiries = $this->model->enquiriesTime();
$dayData = array();
for ($i = 0; $i != 5; $i++) {
if ($enquiries[$i]['name'] == 'Mon' || $enquiries[$i]['name'] == 'Tue' || $enquiries[$i]['name'] == 'Wed' || $enquiries[$i]['name'] == 'Thu' || $enquiries[$i]['name'] == 'Fri') {
$dayData[$i] = $enquiries[$i]['y'];
} else {
$dayData[$i] = '0';
}
}
When a day doesn't exist the 0 gets added to the end of the array and not index 2 (Wednesday) like it should, so Wednesday's results are actually Thursdays.
How can I get this to work properly?
Here is the JS:
function createActivityChart() {
$.ajax({
url: ROOT + 'Ajax',
data: {
call: 'lists->enquiriesTime'
},
dataType: 'json',
type: 'POST',
async: true,
success: function(returned) {
$('#enquiriesChart').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Weekly activity chart'
},
xAxis: {
categories: [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri'
]
},
yAxis: {
min: 0,
title: null,
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:.0f}</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black, 0 0 3px black'
}
}
}
},
series: returned
});
}
})
}
And the HTML container:
<div class="row-fluid">
<div class="span12">
<div class="gridData">
<div id="activityChart" style="min-width: 200px; height: 200px; margin: 0 auto"></div>
</div>
</div>
</div>
What I use to do to avoid your problem is create the highchart array with all 0 values, and then overwrite them. This way you make sure no data is left behind.
I appear to have done it using this horrendous logic ladder:
for ($i = 0; $i != 5; $i++) {
if ($i == 0) {
if ($enquiries[$i]['name'] == 'Mon') {
$dayData[$i] = $enquiries[$i]['y'];
} else {
$enquiriesI = array(array('name' => 'Mon', 'y' => 0));
array_splice($enquiries, 0, 0, $enquiriesI);
$dayData[$i] = 0;
}
}
if ($i == 1) {
if ($enquiries[$i]['name'] == 'Tue') {
$dayData[$i] = $enquiries[$i]['y'];
} else {
$enquiriesI = array(array('name' => 'Tue', 'y' => 0));
array_splice($enquiries, 1, 0, $enquiriesI);
$dayData[$i] = 0;
}
}
if ($i == 2) {
if ($enquiries[$i]['name'] == 'Wed') {
$dayData[$i] = $enquiries[$i]['y'];
} else {
$enquiriesI = array(array('name' => 'Wed', 'y' => 0));
array_splice($enquiries, 2, 0, $enquiriesI);
$dayData[$i] = 0;
}
}
if ($i == 3) {
if ($enquiries[$i]['name'] == 'Thu') {
$dayData[$i] = $enquiries[$i]['y'];
} else {
$enquiriesI = array(array('name' => 'Thu', 'y' => 0));
array_splice($enquiries, 3, 0, $enquiriesI);
$dayData[$i] = 0;
}
}
if ($i == 4) {
if ($enquiries[$i]['name'] == 'Fri') {
$dayData[$i] = $enquiries[$i]['y'];
} else {
$enquiriesI = array(array('name' => 'Fri', 'y' => 0));
array_splice($enquiries, 4, 0, $enquiriesI);
$dayData[$i] = 0;
}
}
}
There must be a better way?
I have found that the above method works well for week days and the following method for days of the month:
public function parseMonthlyGraph($SQLResults) { // For days
$dayData = array();
$startDate = date('Y-m').'-01';
$lastDay = date("t", strtotime($startDate));
for ($i = 0; $i != 31; $i++) {
if($i == $lastDay)
{
break;
}
$dayName = date('jS', strtotime($startDate . ' + '.$i.' days'));
if ($SQLResults[$i]['name'] == $dayName) {
$dayData[$i] = $SQLResults[$i]['y'];
if (empty($SQLResults[$i + 1])) {
$SQLResults[$i + 1]['name'] = date('jS', strtotime($startDate . ' + ' . $i+1 . +' days'));
$SQLResults[$i + 1]['y'] = 0;
}
} else {
$enquiriesI = array(array('name' => $dayName, 'y' => 0));
array_splice($SQLResults, $i, 0, $enquiriesI);
$dayData[$i] = 0;
}
}
return $dayData;
}

Alter highchart output to display start - end date

I currently have the following highchart which display a start date and outputs the values for the next 31 days of data. Does anyone know how I may improve on this to include and end date so that I can filter the data by smaller specific amounts? On the x-axis I am also trying to only display labels that have data attached to them and hide any others. Any help is appreciated.
My code is as follows:
<script type="text/javascript">
var chart;
$(document).ready(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: '<?php echo $type ?>',
x: -20 //center
},
xAxis: {
categories: [ <? php
$start = $_POST["dateStart"];
$dates = array();
for ($i = 0, $days = date('t', strtotime($start)); $i < $days; ++$i) {
$dates[] = date('Y-m-d', strtotime($start.' + '.$i.' day'));
}
echo "'".implode("', '", $dates)."'"; ?> ]
},
yAxis: {
title: {
text: 'Total Amount'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [ <? php
foreach($array as $legend = > $data) {
echo '{';
echo "name: '".$legend."',";
$values = array();
for ($i = 0; $i < $days; ++$i) {
$date = date('Y-m-d', strtotime($start.' + '.$i.' day'));
$values[] = isset($data[$date]) ? $data[$date] : 0;
}
echo 'data: ['.implode(', ', $values).'],';
echo '},';
} ?> ]
});
});
Thanks
Please note that the following IS NOT secure. You should ALWAYS run a sanity check on data submitted by the user.
xAxis: {
categories: [ <? php
$start = $_POST["dateStart"];
$end = $_POST["dateEnd"];
$dates = array();
$current=$start;
while($current<=$end){
$dates[]=$current;
$current=date('Y-m-d', strtotime($current.' + 1 day'));
}
echo "'".implode("', '", $dates)."'"; ?> ]
},

Displaying dates in Flot from timestamps

I am trying to get my graph to display dates on the x axis instead of the timestamps. I've searched and read other posts and still can't get it to budge. Here's my code:
for($i = 0; $i < 3; $i++)
{
$j = $i + 1;
$query = "SELECT UNIX_TIMESTAMP(date_added)*1000, COUNT(id)
FROM likes
WHERE date_added BETWEEN
DATE_SUB(CURDATE(), INTERVAL $j MONTH)
AND DATE_SUB(CURDATE(), INTERVAL $i MONTH)";
$result = mysql_query($query);
echo mysql_error();
$date = mysql_result($result, 0, 0);
$count = mysql_result($result, 0, 1);
$pair = array( (string)$date, (int)$count );
array_push($data_series1, $pair);
}
$.ajax({
url: 'graph_likes.php?get_data=month',
dataType: 'json',
success: function(returned) {
$.plot($('#container'),
[{
data: returned,
points:
{
show: true
},
lines:
{
show: true
},
color: '#00d6e2',
xaxis:
{
mode: 'time'
}
}]);
}
});
If you want flot to display your timestamps nicely formatted, you can try using the timestamp format option (called timeformat):
...
xaxis:
{
mode: 'time',
timeformat: "%y/%m/%d"
}
...
You find the option explained in this document: http://people.iola.dk/olau/flot/API.txt , look for the section called Time series data.

Categories