Displaying dates in Flot from timestamps - php

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.

Related

DB requery with php for envoriment monitoring

I am new here and this is my first post
I need help for a college project.
We are programming a raspberry pie so that is measures temperature and air humidity and visualize the data on an html page.
But we have a problem to make the visualize right.
We take the data from myadminphp and show it graphically, but the time stamp is not steady it change the time to time at the moment minus 3 hours but we want to have it fixed every 3 hours.
Php code:
$lastDatetime = $db->query("select date_time
from measurements
where id=(
select max(id)
from measurements
)")
->fetch(PDO::FETCH_ASSOC)["date_time"];
$thisDay = $lastDatetime;
$dataLastSevenDays = array();
for ($i = 0; $i < 56; $i++) {
$maxTemperatureThisDay = $db->query("select value
from measurements
where date_time like '" . substr($thisDay, 0, 13) . "%'
and channel = 1
limit 1"
)
->fetch(PDO::FETCH_ASSOC)["value"];
//channel 1 Temp
$maxBrightnessThisDayThisDay =
$db->query("select value
from measurements
where date_time like '" . substr($thisDay, 0, 13) . "%'
and channel = 2
limit 1")
->fetch(PDO::FETCH_ASSOC)["value"]; //channel 2 Licht
$maxHumidityThisDay =
$db->query("select value
from measurements
where date_time like '" . substr($thisDay, 0, 13) . "%'
and channel = 4
limit 1")
->fetch(PDO::FETCH_ASSOC)["value"]; //channel 4 Luftfeuchtigkeit
$thisDay = date_sub(new DateTime($thisDay), new DateInterval('PT10800S'))->format('Y-m-d H:i:s');
$dataLastSevenDays[$i] = array($thisDay, $maxTemperatureThisDay, $maxBrightnessThisDayThisDay, $maxHumidityThisDay);
}
the html code:
<script>
var ctx = document.getElementById('temperature').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: [
<?php
for ($i = 56; $i > 0; $i--) {
echo '"' . $dataLastSevenDays[$i][0] . '",';
}
?>
],
datasets: [{
label: "gemessene Temperatur",
borderColor: 'rgb(16, 119, 237)',
data: [
<?php
for ($i = 56; $i > 0; $i--) {
echo '"' . $dataLastSevenDays[$i][1] . '",';
}
?>
]}]
},
options: {}
});
</script>

Plotting multiple series from JSON php import to Highcharts

because I'm pretty new to JS, I can't understand how to implement multiple data series into my code
Here is my php page that I use as data grabber:
getTrendData-TIMEREQUESTED-hms.php
<?php
//Define possible Argument request
$format = $_GET['format'];
if($format=='json') {
header("Content-type: text/json");
}
//Define database credential
$servername = "localhost";
$username = "test";
$password = "test";
$dbname = "test";
try {
//Open connection to mysql_db from defined Database credentials
$connection = mysqli_connect($servername, $username, $password, $dbname) or die ("Error " . mysqli_error($connection));
$sql = "select TIMEREQUESTED,TS FROM TIMEREQUESTED ORDER BY TS;";
$result = mysqli_query($connection, $sql) or die ("Error in Selecting " . mysqli_error($connection));
//create an array
$data = array();
while($row = mysqli_fetch_assoc($result)) {
$TIMEREQUESTED = strtotime($row['TIMEREQUESTED'])*1000;
$TS = strtotime($row['TS'])*1000;
$data[] = array($TS, $TIMEREQUESTED);
}
echo json_encode($data);
//close the db connection
mysqli_close($connection);
}
catch(PDOException $e) {
echo $e->getMessage();
}
?>
Than I include in HighCharts with an Ajax call, that call himselfs each 2500 miliseconds,
getTrendData-TIMEREQUESTED-hms.php
[[1461241983000,5.67,0],[1461242015000,16.67,0],[1461242164000,16.67,0],[1461242303000,26.25,0],[1461242835000,-2.5,0],[1461242869000,-2.5,0],[1461242991000,1.5,0],[1461243034000,3.14,0],[1461243374000,-14.22,0],[1461243456000,-11.92,0],[1461244995000,0,0],[1461245036000,-3.6,140],[1461245208000,-3,140],[1461245260000,3.56,140],[1461245312000,2.1,140],[1461245346000,2.1,140],[1461245411000,3.5,140],[1461245442000,3.5,140],[1461245479000,-1,140],[1461245757000,-0.8,140],[1461245809000,-0.69,140]]
TIMEREQUESTED-hms.html
function buildTIMEREQUESTED() {
var chart;
var dataSource = 'getTrendData-TIMEREQUESTED-hms.php?format=json';
var ChartHeight = window.innerHeight;
function requestData() {
$.ajax({
url: dataSource,
success: function(points) {
chart.series[0].setData(points, true);
setTimeout(requestData, 2500);
},
cache: false
});
}
$(document).ready(function() {
//add our div for the chart
$("#container").append("<div id=chart-laptime style='width:100%''></div>");
chart = new Highcharts.Chart({
chart: {
height: ChartHeight,
renderTo: 'chart-laptime',
defaultSeriesType: 'line',
events: {
load: function() {
requestData();
}
},
},
tooltip: {
enabled: true,
formatter: function() {
s = (this.y / 1000);
m = Math.floor(s / 60);
h = Math.floor(m / 60);
s = s % 60;
m = m % 60;
h = h % 24;
if (h < 9) h = "0" + h;
if (m < 9) m = "0" + m;
if (s < 9) s = "0" + s;
return '<span style="color:black">Time Zero - </span>' + [m, s].join(':');
}
},
title: {
text: 'TIMEREQUESTED'
},
subtitle: {
text: 'BEST 5 CAR AVEREGE LAPTIME IN LAST 10 MINUTES'
},
xAxis: {
type: 'datetime',
title: {
text: 'RACE TIME'
}
},
yAxis: {
type: 'datetime',
dateTimeLabelFormats: {
millisecond: '%H:%M:%S',
},
//dateFormat: {"%H:%M:%S.%L"}
title: {
text: 'TIMEREQUESTED'
}
},
series: [{
name: 'TIMEREQUESTED',
showInLegend: false,
//tooltip: {type: 'datetime',},
data: [],
}]
}); //end chart
}); //end document.ready
}
In that way I can get the single series proper displayed, but with the MySQL query I'm able to get more columns from the database, and parsing in each rows of the json file,(As is showed in the JSON file from php request, there is a third values for each array) but I'm not able to understand how to display multiple data series, with on the xAxis always the first column of the JSON file, and on the yAxis each time a different columns.
Could you please give me some suggestions on how to display multi series on the same graph? It would be so much appreciated,
Best regards.
var dataForTwoSeries = [[1461241983000,5.67,0],[1461242015000,16.67,0],[1461242164000,16.67,0]]; //your data, just took 3 elements. Should work for any number of elements.
var seriesOne = [];
var seriesTwo = [];
$.each(dataForTwoSeries, function(index, dataPoints){
var seriesOneDataPoint = [dataPoints[0], dataPoints[1]];
var seriesTwoDataPoint = [dataPoints[0], dataPoints[2]];
seriesOne.push(seriesOneDataPoint);
seriesTwo.push(seriesTwoDataPoint);
});
And then you'll have to create 2 series in your chart object like
series: [{
name: 'seriesName1',
showInLegend: false,
data: [],
},{
name: 'seriesName2',
showInLegend: false,
data: [],
}]
And in your requestData method, set the data for both like
chart.series[0].setData(seriesOne, false); //redraw after setting data for second series
chart.series[1].setData(seriesTwo); //boolean redraw is true by default, don't need to pass it
EDIT : After your updated code, these are the changes you further need to make.
$.ajax({url: dataSource, success: function(dataForTwoSeries) //dataForTwoSeries is the data you get from the request
{
//var dataForTwoSeries = []; you don't need this.
var seriesOne = []; //these two don't have to be global.
var seriesTwo = [];
$.each(dataForTwoSeries, function(index, dataPoints){
var seriesOneDataPoint = [dataPoints[1], dataPoints[0]];
var seriesTwoDataPoint = [dataPoints[2], dataPoints[0]];
seriesOne.push(seriesOneDataPoint);
seriesTwo.push(seriesTwoDataPoint);
}); // draw chart after iteration and not during each interation
chart.series[0].setData(seriesOne, false); //redraw after setting data for second series
chart.series[1].setData(seriesTwo); //boolean redraw is true by default, don't need to pass it
setTimeout(requestData, 2500);
},
cache: false
});
I've update the code and now is free from syntax error, but I have no data displayed. I'm going to put some windows.allert() tu understand where the data flow is broken.
Here's the updated code:
<!DOCTYPE html>
<html>
<head>
<title>Strategy - Time Zero</title>
<script src="js/jquery/jquery-1.12.3.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="js/Highcharts/Highcharts-4.2.3/highcharts.js"></script>
<script src="js/Highcharts/Highcharts-4.2.3/modules/exporting.js"></script>
<script>
var chart;
var dataSource = 'getTrendData-TimeZero.php?format=json';
var ChartHeight = window.innerHeight;
var dataForTwoSeries = [];
var seriesOne = [];
var seriesTwo = [];
function requestData() {
$.ajax({url: dataSource, success: function(dataPoints)
{
$.each(dataForTwoSeries, function(index, dataPoints){
var seriesOneDataPoint = [dataPoints[1], dataPoints[0]];
var seriesTwoDataPoint = [dataPoints[2], dataPoints[0]];
window.alert(seriesOneDataPoint)
seriesOne.push(seriesOneDataPoint);
seriesTwo.push(seriesTwoDataPoint);
chart.series[0].setData(seriesOne, false); //redraw after setting data for second series
chart.series[1].setData(seriesTwo); //boolean redraw is true by default, don't need to pass it
setTimeout(requestData, 2500);
});
},
cache: false
});
}
$(document).ready(function() {
//add our div for the chart
$("#container").append("<div id=chart-TimeZero style='width:100%''></div>");
//StockChart
//Chart
chart = new Highcharts.Chart({
chart: {
height: ChartHeight,
renderTo: 'chart-TimeZero',
defaultSeriesType: 'line',
events: {
load: function() {
requestData();
}
},
},
tooltip: {
enabled: true,
formatter: function() {
if (this.y < 0)
{
h = Math.ceil(this.y / 3600);
m = Math.ceil(this.y / 60);
s = Math.ceil(this.y % 60);
h = Math.abs(h);
m = Math.abs(m);
s = Math.abs(s);
s = s % 60;
m = m % 60;
h = h % 24;
if (h < 9) h = "-0" + h;
if (m < 9) m = "0" + m;
if (s < 9) s = "0" + s;
}
else
{
h = Math.floor(this.y / 3600);
m = Math.floor(this.y / 60);
s = Math.floor(this.y % 60);
h = Math.abs(h);
m = Math.abs(m);
s = Math.abs(s);
s = s % 60;
m = m % 60;
h = h % 24;
if (h < 9) h = "0" + h;
if (m < 9) m = "0" + m;
if (s < 9) s = "0" + s;
}
return '<span style="color:black">Time Zero</span> ' + [h, m, s].join(':');
}
},
title: {
text: 'TIME ZERO'
},
subtitle: {
text: 'BEST 5 CAR AVEREGE LAPTIME IN LAST 10 MINUTES'
},
xAxis: {
type: 'datetime',
title: {text: 'DAY TIME'}
},
yAxis: {
title: {text: 'TIME ZERO'},
labels: {
formatter: function() {
if (this.value < 0)
{
h = Math.ceil(this.value / 3600);
m = Math.ceil(this.value / 60);
s = Math.ceil(this.value % 60);
h = Math.abs(h);
m = Math.abs(m);
s = Math.abs(s);
s = s % 60;
m = m % 60;
h = h % 24;
if (h < 9) h = "-0" + h;
if (m < 9) m = "0" + m;
if (s < 9) s = "0" + s;
}
else
{
h = Math.floor(this.value / 3600);
m = Math.floor(this.value / 60);
s = Math.floor(this.value % 60);
h = Math.abs(h);
m = Math.abs(m);
s = Math.abs(s);
s = s % 60;
m = m % 60;
h = h % 24;
if (h < 9) h = "0" + h;
if (m < 9) m = "0" + m;
if (s < 9) s = "0" + s;
}
return [h, m, s].join(':');
}
}
},
series: [{
name: 'seriesName1',
showInLegend: true,
data: [],
},{
name: 'seriesName2',
showInLegend: true,
data: [],
}]
}); //end chart
}); //end document.ready
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>

Ajax request from overridden component of joomla template

I'm new guy in joomla and i was searching for the answer a lot of time, but didn't get the result. I have my template in joomla 3.4.5 and i have overridden component com_content and category inside it. I made my file blog.php where i output my calendar. The problem is to send ajax changing month by clickng proper button. There is an error, when i'm trying to send ajax. Seems like joomla bans direct request. I read many articles, like how to use ajax in modules and components, but there is no advice how to use it in overriden component. Please give me detailed answer for my problem.
JHtml::_('jquery.framework');
$document = JFactory::getDocument();
$document->addScript('/space/media/media/js/mainscript.js');
i used that code to include my scriptfile in blog.php
function getAjaxData()
{
echo 'login: ' .$_REQUEST['month'] . '; password: ' . $_REQUEST['year'];
exit;
}
created method to handle my ajax request in blog.php
var j = jQuery.noConflict()
j(document).ready(function(){
j('#next').click(function(){
var month = j(this).data('month');
var year = j(this).data('year');
if(month == 12){
year +=1;
month = 1;
}
else{
month++;
}
j.post("/space/templates/forte/")
j.ajax({
url: "index.php?option=com_content&view=category&task=getAjaxData&format=raw",
type: "POST",
data: {
month: month,
year: year
},
success: function(data){
j('#calendar_wrap').html(data);
}
});
console.log('month: '+month+' year: '+year);
})
j('#prev').click(function(){
var month = j(this).data('month');
var year = j(this).data('year');
if(month == 1){
year -=1;
month = 12;
}
else{
month--;
}
j.ajax({
url: "index.php?option=com_content&view=category&task=getAjaxData&format=raw",
type: "POST",
data: {
month: month,
year: year
},
success: function(data){
j('#calendar_wrap').html(data);
}
});
console.log('month: '+month+' year: '+year);
})
});
mainscript.js, included in blog.php
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/
here is the error outputted to browser console
I solve problem with that error by putting that method:
public function getAjaxData()
{
}
In file: /site/components/com_content/controller.php
but, i have one more problem now.
In that method my calendar outputs again, but now we have new values, send by ajax. The code below:
public function getAjaxData()
{
JHtml::_('jquery.framework');
$document = JFactory::getDocument();
$document->addScript('/space/media/media/js/mainscript.js');
function days_in_month($month, $year)
{
// calculate number of days in a month
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
}
// get number of days in needed month
$currentYear = date('Y');
$currentMonth = date('n');
if(isset($_REQUEST['year']))
$currentYear = $_REQUEST['year'];
if(isset($_REQUEST['month']))
$currentMonth = $_REQUEST['month'];
$rusmonth = array('Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь');
$dayofmonth = days_in_month($currentMonth, $currentYear);
// count for days in month
$day_count = 1;
// 1. first week
$num = 0;
for($i = 0; $i < 7; $i++)
{
// get day of week
$dayofweek = date('w',
mktime(0, 0, 0, $currentMonth, $day_count, $currentYear));
// format our values to 1-monday, 6-saturday
$dayofweek = $dayofweek - 1;
if($dayofweek == -1) $dayofweek = 6;
if($dayofweek == $i)
{
// if numbers of week are equal,
// put values into array $week
$week[$num][$i] = $day_count;
$day_count++;
}
else
{
$week[$num][$i] = "";
}
}
// 2. other weeks of month
while(true)
{
$num++;
for($i = 0; $i < 7; $i++)
{
$week[$num][$i] = $day_count;
$day_count++;
// if we got the end of the month exit from loop
if($day_count > $dayofmonth) break;
}
if($day_count > $dayofmonth) break;
}
// 3. output array $week
echo '<div> <span id="prev" data-month="'.$currentMonth.'" data-year="'.$currentYear.'"><</span> '.$rusmonth[$currentMonth-1].' <span id="next" data-month="'.$currentMonth.'" data-year="'.$currentYear.'">></span> </div>';
echo '<div id="calendar_wrap">';
echo '<table border=1>';
echo '<tr>
<th>ПН</th>
<th>ВТ</th>
<th>СР</th>
<th>ЧТ</th>
<th>ПТ</th>
<th>СБ</th>
<th>ВС</th>
</tr>';
for($i = 0; $i < count($week); $i++)
{
echo "<tr>";
for($j = 0; $j < 7; $j++)
{
if(!empty($week[$i][$j]))
{
if($j == 5 || $j == 6)
echo "<td><font color=red>".$week[$i][$j]."</font></td>";
else echo "<td>".$week[$i][$j]."</td>";
}
else echo "<td> </td>";
}
echo "</tr>";
}
echo "</table>";
echo '</div>';
exit;
}
in that method i can't add my script again to get new month.
So there are two ways for me as I see:
1. make my method that way, so he become something like a bridge between blog.php and ajax. There will be no outputs.
Find a way, how could i add script to controller and make double code.
The problem is, that i have no idea, how realize both of it in Joomla...
Of course i prefer 1st variant.

Highcharts with data from mysql database

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.

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

Categories