How to change x-axis date format dynamically in c3js chart? - javascript

I have a line chart with dynamic data make by c3js chart library.
In that chart, I already show data depend on date with timeseries. Here is the sample of chart.
Now I add three button to show data in chart by day,month and year. When I click day button, I want to show data only day by day. And the year and month button are also too.
The main point is, I want to change x-axis date format dynamically when I click day, month and year button.
So I query data from database for each day, month and year. But the problem is, when I show data in chart, I need to change date format dynamically in x-axis. So, I try like this,
<?php
if(isset($_POST['btn_day'])) {
$sql = "......."
$query = ........;
//query data day by day just like DATE_FORMAT(date, '%d') as date
.
$format = '%d';
}elseif(isset($_POST['btn_month'])) {
$sql = "......."
$query = ........;
//query data for each month just like DATE_FORMAT(date, '%M') as date
.
$format = '%m';
}elseif(isset($_POST['btn_year'])) {
$sql = "......."
$query = ........;
//query data for each year just like DATE_FORMAT(date, '%Y') as date
.
$format = '%Y';
}else {
$sql = "......."
$query = ........;
.
.
$format = '%Y-%m-%d';
}
?>
<script>
var f = <?php echo "'".$format."'"?>; //'%Y-%m-%d'
console.log(f);
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'date',
json:<?php echo json_encode($data);?>,
mimeType: 'json',
keys: {
x: 'date',
value: <?php echo json_encode($names)?>
},
type: 'line',
},
axis: {
x: {
type: 'timeseries',
tick:{
format: function(f){
if(f == "%d"){
return d3.getDay();
}else if(f == "%m"){
return d3.getMonth();
}else if(f == "%Y"){
return d3.getFullYear();
}else{
return '%Y-%m-%d';
}
},
rotate: 75,
}
}
},
});
</script>
But I don't get correct result in chart. I know I was wrong in this part,
tick:{
format: function(f){
if(f == "%d"){
return d3.getDay();
}else if(f == "%m"){
return d3.getMonth();
}else if(f == "%Y"){
return d3.getFullYear();
}else{
return '%Y-%m-%d';
}
},
rotate: 75,
}
But I don't know how can I change x-axis date format dynamically. I already try a lot of way but I can't get correct result.
I very appreciate for any suggestion.

d3 doesn't have getDay() / getMonth() / getFullYear() functions, what you need (if f exists) is
d3.time.format(f)
See https://github.com/mbostock/d3/wiki/Time-Formatting
(Moreover, you're not really changing the formatting dynamically as far as the chart is concerned, you're generating a new c3 chart each time, though that's probably just semantics.)

Related

FullCalendar: Changing event colors with comparing dates

Recently, ive started tyring out arshaw's fullcalendar. Along the developing journey, i was searching through websites on solution to get the event color to change based on the dates of the event and the current date. This code is written with HTML and PHP with Javascript.
This is an answer to my own questions posts based on what i achieve as there is no similar questions with solutions to this.
So below is my answer and how the FullCalendar looks like.
To clarify, i am using odbc with microsoft Access as database.
My way of doing this is as below:
Events at fullcalendar script
events: [
<?php
include 'connect.php'; //connect to database
function getColor($date) {
$currentDate = date('Y-m-d');
$oneweekDate = date('Y-m-d',strtotime('-1 week')); // this part is to compare with the date 1 week ago
$eventColor = '';
if ($date == $currentDate) {
$eventColor = '#fb8c00';
} else if($date > $oneweekDate && $date < $currentDate){
$eventColor = '#ff0000';
} else if($date < $oneweekDate){
$eventColor = '#696969';
} else {
$eventColor = '#008000';
}
return $eventColor;
}
$sql="SELECT * FROM masterlist1";
$result=odbc_exec($conn,$sql);
while($row=odbc_fetch_array($result)){
$newEnd = date("Y-m-d", strtotime($row['Calibration_Due_Date']));
$color = getColor($newEnd); //store the date from database into a PHP variable and then call the PHP function getColor to get return result
?>
{
title: '--title--', <!--u may get info from fullcalendar.io on the documentations for these parts-->
start: '--start date--',
end: '--end date--',
description : '--description--',
color : '<?php echo $color?>' <!-- this part is where we get the return result from the getColor function and store it into $color variable and then echo it out here for the event color.-->
},
<?php } ?>
],

How to use The Date and Time in Google Charts

I am trying to use a MySQL TimeStamp for the X Axis on a Scatter graph using Google Charts. Currently, the only way I have managed to get the graph displaying it using the strtotime() Function. This confuses the graph or me as strtotime() Function shows a number of seconds from 1st Jan 1970.
new Date(2017-03-07 02:03:12)] YYYY-MM-DD HH:ii:SS this is the format of the date coming from my timestamp if I leave it like this then I get the error. only if I change the time to the strtotime() this works. But the Graph does not show the time properly. Is there another way to display the timestamp. As the Documentation on google does not make much sense.
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Distance');
data.addColumn('datetime', 'time');
data.addRows([
<?php
$query = "SELECT * FROM iot_sensors WHERE Sensor_ID ='Ultra_Dist'";
$execute = mysqli_query($conn, $query);
while ($row = mysqli_fetch_array($execute)){
$date = strtotime($row['Time_Stamp']);
echo "[".$row['Sensor_1'].", new Date(".$date.")],";
$Trimmed = trim($row['Time_Stamp']);
//echo $Trimmed;
}
?>
]);
var options = {
width: 800,
height: 500,
chart: {
title: 'Frequency of movement by time',
subtitle: 'Frequency of movement'
},
hAxis: {title: 'Distance'},
vAxis: {title: 'time'}
};
This is my code which retrieves the Time_Stamp and other value from my table and puts it in an array for the chart to use.
<?php
$query = "SELECT * FROM iot_sensors WHERE Sensor_ID ='Ultra_Dist'";
$execute = mysqli_query($conn, $query);
while ($row = mysqli_fetch_array($execute)){
$date = ($row['Time_Stamp']);
$date2 = new DateTime($date);
$date3 = date_format($date2, 'Y,m,d,H,i,s');
echo "[new Date(".$date3."),".$row['Sensor_1']."],";
}
?>
Put the date in a new Date() object then reformat it to the accepted format and then echo the date in the array.

flot chart not plotting date in xaxis

I am trying to plot xaxis in Flot-chart with date. i have tried with configuring xaxis and also using javascript EPOCH but still no success, here is my piece of code.
<?php
foreach($data[0] as $i => $d){
foreach ($d as $key => $value) {
$data[0][$i][$key][0] = strtotime($value[0]);
}
}
$data1 = json_encode($data[0][0]);
$data2 = json_encode($data[0][1]);
echo $data1;
/* print $data1 will give this */
[[1367605800,"0.006"],[1367692200,"0.012"],[1367778600,"0.394"],[1367865000,"0.509"],[1367951400,"0.000"],[1368037800,"0.032"],[1368124200,"0.000"]]
/*for checking purpose */
$json = json_decode($data1);
foreach ($json as $key => $val) {
$readabledate = date("m-d-Y", $val[0]).'<br>';
echo $readabledate;
}
/* after decoding 1367605800,1367692200,... i get date in readable format again thsis is what i need in xaxis
05-05-2013
05-06-2013
05-07-2013
05-08-2013
05-09-2013
05-10-2013
*/
?>
<script>
$(function () {
/**
* Flot charts data and options
*/
var data1 = <?php echo $data1;?>;
var data2 = <?php echo $data2;?>;
/*checking static date values */
var date = new Date(1367605800*1000);
alert(date);
//Sat May 04 2013
/*alert showing 1367605799.2 value
ends here*/
var chartUsersOptions = {
grid: {
tickColor: "#f0f0f0",
borderWidth: 1,
borderColor: 'f0f0f0',
color: '#6a6c6f'
},
xaxis: {
mode: "time",
timeformat: "%Y/%m/%d",
minTickSize: [1, "day"]
},
colors: [ "#62cb31", "#efefef"],
};
$.plot($("#flot-line-chart"), [data1, data2], chartUsersOptions);
});
</script>
if i remove minTickSize: [1, "day"] from xaxis config its plotting 1970/01/16 in xaxis. where i am wrong or how it can be done. please suggest
i figured out the solution, basically javascript epoch is calculating time by multiplying it with 1000 which i have shown by taking a static value.
var data1 = <?php echo $data1;?>;
var data2 = <?php echo $data2;?>;
/*checking static date values */
var date = new Date(1367605800*1000);
alert(date);
//Sat May 04 2013
so to do this with the whole var data1 i just need to multiply $data[0][$i][$key][0] = strtotime($value[0])*1000; in my php code. that's it problem solved. Cheers..

Highcharts does not display when a line of PHP header('location...') is added

I am using Highcharts to display a chart containing dates/time and temperature of a room.
The javascript used to generate the chart is in the temperature.php file which user will be able to view, and the javascript will get data from a dataSorter.php file which contains SQL query to retrieve the results from MySQL for the chart to display.
Javascript to generate the chart in temperature.php:
<script type="text/javascript">
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 50
},
title: {
text: 'Temperature vs. Time',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Degrees Celcius'
},
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: []
}
$.getJSON("dataSorter.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
});
</script>
At this point, I have generated 4 drop down lists in temperature.php containing From Date, To Date, From Time and To Time. This will allow users to select a range which they wish to see the chart generate. (E.g 2014-01-20 00:00:00 to 2014-01-21 22:00:00). A button onclick will activate the function:
if(isset($_POST['sort'])){
$from=$_POST['SDate'];
$to=$_POST['EDate'];
$sTime=$_POST['STime'];
$eTime=$_POST['ETime'];
$start=$from." ".$sTime;
$end=$to." ".$eTime;
header('Location: dataSorter.php?start='.$start.'&end='.$end.'');
}
?>
$from = start date
$to = end date
$sTime = start time
$eTime = end time
$start = combine $from and $sTime to get a start date/time
$end = combine $to and $eTime to get a end date/time
dataSorter.php has the following codes:
<?php
$con = mysql_connect("localhost","root","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("scsense", $con);
if(isset($_GET['start'])){
$start = $_GET['start'];
$end = $_GET['end'];
$sth = mysql_query("SELECT * FROM scsenseinfo WHERE roomID='501' AND (dateTime BETWEEN '$start' AND '$end') ORDER BY recordID");
$rows = array();
$rows['name'] = 'DateTime';
while($rr = mysql_fetch_assoc($sth)) {
$rows['data'][] = $rr['dateTime'];
}
$sth = mysql_query("SELECT * FROM scsenseinfo WHERE roomID='501' AND (dateTime BETWEEN '$start' AND '$end') ORDER BY recordID");
$rows1 = array();
$rows1['name'] = 'RoomTemperature';
while($r = mysql_fetch_array($sth)) {
$rows1['data'][] = $r['roomTemp'];
}
$result = array();
array_push($result,$rows);
array_push($result,$rows1);
$help = print json_encode($result, JSON_NUMERIC_CHECK);
mysql_close($con);
}
else{
$sth = mysql_query("SELECT * FROM (SELECT * FROM scsenseinfo WHERE roomID='501' ORDER BY recordID DESC LIMIT 5) AS tbl ORDER BY tbl.recordID ASC");
$rows = array();
$rows['name'] = 'DateTime';
while($rr = mysql_fetch_assoc($sth)) {
$rows['data'][] = $rr['dateTime'];
}
$sth = mysql_query("SELECT * FROM (SELECT * FROM scsenseinfo WHERE roomID='501' ORDER BY recordID DESC LIMIT 5) AS tbl ORDER BY tbl.recordID ASC");
$rows1 = array();
$rows1['name'] = 'RoomTemperature';
while($r = mysql_fetch_array($sth)) {
$rows1['data'][] = $r['roomTemp'];
}
$result = array();
array_push($result,$rows);
array_push($result,$rows1);
$help = print json_encode($result, JSON_NUMERIC_CHECK);
mysql_close($con);
}
//header('Location: L501TempSorter.php');
?>
If I have header('Location: L501TempSorter.php'); un-commented, the chart does not display a thing, even when onload of the page, without clicking the button to sort the dates. If it is commented, the chart is displayed onload, but clicking the button to sort the dates lead to dataSorter.php and stays on the page, which just displays the arrays containing the sorted dates. I really need help with this, thank you in advance!
You cannot use header when you have already printed something, like you sdo with //header('Location: L501TempSorter.php');.
If you are trying to save the output from print to the variable $help than you need to use sprint instead. Print will always output to the output buffer and always returns 1. This is true for any print function not starting with a s or vs the s before the print in the function name always indicates that it will return the resulting string instead of outputting it.
To solve your problem with the data not being displayed please post the onlcick code of the button. It should be an ajax call like
<script>
$.getJSON('dataSorter.php', {
sort: 'sortValue',
STime: /* get start value */,
ETime: /* get end value */,
SDate: /* get start value */,
EDate: /* get end value */
}, function(data) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
/* or anything that updates your chart */
});
</script>
In the php script run when the onClick function is executed. You should probably url encode your Location: in part
<?php
header('Location: dataSorter.php?start='.urlencode($start).'&end='.urlencode($end));
Though I don't understand why you are using header('Location: ...'); here anyways? You are already on the Server why tell the client browser to load a different location just include your script that is supposed to run now.
What is your purpose of using location, in case when you use this script only for return json? When you load json in javascirpt, you run your entire php script, so instead od returning json you are redirect to other location, as a result json is not loaded in javascript.

How can I pass multiple data from PHP to jQuery/AJAX?

I have a main select list of courses which drives various things on a page. When a course is selected another select list will be repopulated with the start date of that course up to 6 months in advance. Also, I have a table on the page with the students name and phone number, when a course is selected, the table will be repopulated with all the students enrolled onto that course. My problem is I will be getting various different things from PHP via JSON i.e. the students and the starting date. How can I therefore pass more than one thing to jQuery? What if the course select list affected not just 2 things but 3, 5 or even 10? How would we handle that with PHP and jQuery?
foreach($m as $meta)
{
$metaCourse = $this->getCourseInfo($meta['parent_course']);
//populate the select list with the name of each course
$metaSelectList .= '<option id="select'.$count.'" value="'.$metaCourse['id'].'">'.$metaCourse['fullname'].'</option>';
$count++;
//get only the first course's dates
if($count3 == 1)
{
$startDate = intval( $course->getStartDate(50) );
$endDate = strtotime('+6 month', $startDate);
//populates the select list with the starting date of the course up to the next six months
for($date = $startDate; $date <= $endDate ; $date = strtotime('+1 day', $date))
{
$dateSelectList .= '<option id="select'.$count2.'" value="'.$date.'">'.date('D d F Y', $date).'</option>';
$count2++;
}
$count3++;
$students = $s->getStudents($metaCourse['id']);
$content = $this->createStudentTable($students);
}
}
This is my handler for the AJAX...FOR NOW (I haven't implemented the students table yet as I'm still trying to figure out how to pass multiple pieces of data to jQuery). Basically each time a course is selected, PHP creates a new select list with the appropriate dates and then passes it to jQuery. I'm not sure if I should do this in JavaScript or in PHP.
if (isset($_GET['pid']) && (isset($_GET['ajax']) && $_GET['ajax'] == "true"))//this is for lesson select list
{
$pid = intval( $_GET['pid'] );
$c = new CourseCreator();
$startDate = intval( $c->getStartDate($pid) );
$endDate = strtotime('+6 month', $startDate);
$dateSelectList = '<select name="dateSelect" id="dateSelect">';
//populates the select list with the starting date of the course up to the next six months
for($date = $startDate; $date <= $endDate ; $date = strtotime('+1 day', $date))
{
$dateSelectList .= '<option id="select'.$count2.'" value="'.$date.'">'.date('D d F Y', $date).'</option>';
$count2++;
}
$dateSelectList .= '</select>';
echo json_encode($dateSelectList);
exit;
}
My jQuery handler:
$('#metaSelect').live('change', function()
{
$.getJSON('?ajax=true&pid='+$('#metaSelect').val(), function(data)
{
alert(data);
$('#dateSelectDiv').html(data);
});
});
You can easily pass ALOT of data from PHP to your HTML via JSON (which you seem to of put in basic already)
However to expand on what you have - heres a quick example
<?php
$arrayOfStuff = array("theKey" => "theEntry", 123 => "Bob Dow", 56 => "Charlie Bronw", 20 => 'Monkey!', "theMyID" => $_POST['myID']);
echo json_encode($arrayOfStuff);
?>
On your HTML side.
<script>
$.post("/theurl/", {type: "fetchArrayOfStuff", myID: 24}, function(success) {
//your success object will look like this
/*
{
theKey: 'theEntry',
123: 'Bob Dow',
56: 'Charlie Bronw',
20: 'Monkey!',
theMyID: 24
}
so you can easily access any of the data.
alert(success.theKey);
alert(success[123]);
alert(success[56]);
alert(success[20]);
alert(success.theMyID);
*/
//we can iterate through the success JSON!
for(var x in success) {
alert(x + "::" + success[x]);
};
}, "json");
</script>
In the long run - your MUCH better of letting the backend do the backend stuff, and the front end doing the front-end stuff.
What this means is, try keep the HTML generation as far away as possible from the back-end, so instead of constantly passing
for($date = $startDate; $date <= $endDate ; $date = strtotime('+1 day', $date))
{
$dateSelectList .= '<option id="select'.$count2.'" value="'.$date.'">'.date('D d F Y', $date).'</option>';
$count2++;
}
You could perhaps
$date = $startDate;
$myJson = array()
while($date <= $endDate) {
$myJson[] = array("date" => $date, "formattedDate" => date('D d F Y', $date));
$date += 86400; //86400 is the value of 1 day.
}
echo json_encode($myJson);
And you can just do a simple iteration on your HTML code.
<script>
$.get("/", {ajax: true, pid: $('#metaSelect').val()}, function(success) {
//we can iterate through the success JSON!
var _dom = $('#dateSelectDiv').html(''); //just to clear it out.
for(var x in success) {
_dom.append("<option value='"+success[x].date+"'>"+success[x].formattedDate+"</option>");
};
}, "json");
</script>
So as you can see - you can pass alot of data using JSON
Maybe look at some of the documentation to - http://api.jquery.com/jQuery.get/ , http://api.jquery.com/jQuery.post/ - might give you more ideas.
Best of luck to you

Categories

Resources