If I have a string in the following format from a form input:
02/08/2016, 02/09/2016, 02/10/2016, 02/17/2016
How can I show the dates as events in a calendar like http://fullcalendar.io/?
Should I convert them to an array, and then how can I convert them to an array? and how can I add more dates to that array/update it?
As I saw source file of this page, you need JSON array to create your events. At the end you have to create a string like this:
events: [
{
title: 'All Day Event',
start: '2016-01-01'
},
{
title: 'All Day Event',
start: '2016-01-07',
},
{
title: 'All Day Event',
start: '2016-01-09'
},
{
title: 'All Day Event',
start: '2016-01-16'
},
{
title: 'All Day Event',
start: '2016-01-11',
}
]
So use this code:
<?php
$s = '02/08/2016, 02/09/2016, 02/10/2016, 02/17/2016';
$s = explode(', ', $s);
$dates = [];
foreach($s as $event) {
//Fix format
$temp = explode('/', $event);
$dates[] = array('title' => 'All Day Event', 'start' => $temp[2] . '-' . $temp[1] . '-' . $temp[0] );
}
$dates = json_encode($dates);
So finally, Your whole HTML would be something like this:
<?php
$s = '02/08/2016, 02/09/2016, 02/10/2016, 02/17/2016';
$s = explode(', ', $s);
$dates = [];
foreach($s as $event) {
//Fix format
$temp = explode('/', $event);
$dates[] = array('title' => 'All Day Event', 'start' => $temp[2] . '-' . $temp[1] . '-' . $temp[0] );
}
$dates = json_encode($dates);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link rel='stylesheet' href='../lib/cupertino/jquery-ui.min.css' />
<link href='../fullcalendar.css' rel='stylesheet' />
<link href='../fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='../lib/moment.min.js'></script>
<script src='../lib/jquery.min.js'></script>
<script src='../fullcalendar.min.js'></script>
<script src='../lang-all.js'></script>
<script>
$(document).ready(function() {
var currentLangCode = 'en';
// build the language selector's options
$.each($.fullCalendar.langs, function(langCode) {
$('#lang-selector').append(
$('<option/>')
.attr('value', langCode)
.prop('selected', langCode == currentLangCode)
.text(langCode)
);
});
// rerender the calendar when the selected option changes
$('#lang-selector').on('change', function() {
if (this.value) {
currentLangCode = this.value;
$('#calendar').fullCalendar('destroy');
renderCalendar();
}
});
function renderCalendar() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2016-01-12',
lang: currentLangCode,
buttonIcons: false, // show the prev/next text
weekNumbers: true,
editable: true,
eventLimit: true, // allow "more" link when too many events
events: <?php $dates ?>
});
}
renderCalendar();
});
</script>
<style>
body {
margin: 0;
padding: 0;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
font-size: 14px;
}
#top {
background: #eee;
border-bottom: 1px solid #ddd;
padding: 0 10px;
line-height: 40px;
font-size: 12px;
}
#calendar {
max-width: 900px;
margin: 40px auto;
padding: 0 10px;
}
</style>
</head>
<body>
<div id='top'>
Language:
<select id='lang-selector'></select>
</div>
<div id='calendar'></div>
</body>
</html>
In fullcalendar plugin you need date in this format "Y-m-d".
So you need to use explode() for string to array conversion and than you can use strtotime() for date format conversion.
<?php
$string = "02/08/2016, 02/09/2016, 02/10/2016, 02/17/2016";
$explodedDates = explode(",",$string); // explode with comma
$convertedDate = array();
foreach ($explodedDates as $key => $value) {
$convertedDate[] = date("Y-m-d", strtotime($value)); // conversion in correct format.
}
echo "<pre>";
print_r($convertedDate);
?>
From your question: and how can I add more dates to that array/update
it?
You can just push the value in your existing array as:
array_push($convertedDate,'2015-10-10');
print_r($convertedDate);
A calendar like http://fullcalendar.io/ is complex. The question is too broad, if you want to know how they do it.
Converting a string into an array is a good question. You can use the explode function in PHP as follows:
$inputs = explode(", ", "02/08/2016, 02/09/2016, 02/10/2016, 02/17/2016");
See http://php.net/manual/de/function.explode.php for more details.
Adding an element to an array can be done like this:
$inputs[] = "03/05/2016";
To update an array element, you have to find it first. You can search for an element of a simple array like the one above by an index such as $inputs[4]. But that might not be the best solution to uniquely identify a date, because in a calendar, you might have more than one event at the same day. Additionally, if you are dealing with thousands of events, it would be very slow to find the one that you want to update. I would recommend to look into other indexing strategies.
E.g. $inputs[year][month][day][id].
But that is only one of many possibilities.
Solution with php is as below
PHP code
<?php
$str = explode(',', str_replace(" ","","02/08/2016, 02/09/2016, 02/10/2016, 02/17/2016"));
print_r($str);
$events = array();
foreach($str as $k => $date) {
$events[$k]['title'] = 'Title';
$events[$k]['start'] = date('D M d Y H:i:s', strtotime($date));
}
?>
<script type="text/javascript">
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
events: <?php echo json_encode($events);?> // load events
});
});
</script>
Related
I am new to web programming, I have personal project to track expenditure.
Straight to the point, I have database data contains this month and last month total expenditure. I am able to show it manually (by echo). But i can't pass the value to highcharts series. Due to many small separate data, i want to populate it manually using php/mysql rather than json.
Graph2.php
<?php
$mysql_hostname = "localhost";
$mysql_user = "root";
$mysql_password = "mypassword";
$mysql_database = "mytraining";
$bd = mysqli_connect($mysql_hostname, $mysql_user, $mysql_password, $mysql_database);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query2 = "select year(date) as y, month(date) as m, sum(amount) as p from expenditure_bak group by year(date), month(date) order by m ASC";
$sth = mysqli_query($bd, $query2);
$rows = array();
$rows['name'] = 'Revenue';
while($r = mysqli_fetch_array($sth)) {
$rows['data'][]= round($r['p'],2);
}
//echo join($rows['data'], ','); //able to display correct value 660.2,60
?>
PopupGraph.html
<?php
include('graph2.php');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Monthly Expenditure</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<style type="text/css">
${demo.css}
</style>
<script type="text/javascript">
$(function () {
$('#container').highcharts({
title: {
text: 'Monthly Expenditure'
},
xAxis: {
categories: ['Jun', 'Jul']
},
yAxis: [{
min: 0,
title: {
text: ''
}
}, {
min: 0,
opposite: false, //optional, you can have it on the same side.
title: {
text: 'Average'
}
}
],
labels: {
items: [{
html: 'Monthly Expenditure',
style: {
left: '50px',
top: '18px',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y
/*+ '<br/>' + 'Total: ' + this.point.stackTotal*/;
}
},
series: [{
type: 'spline',
name: 'Average',
yAxis: 1, //to make y axis
//data: [660.2,60], //able to show correct graph with static input
data: [<?php echo join($rows[data], ',') ?>],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}]
});
});
</script>
</head>
<body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>
So, what is the correct code to be put inside data: [] in the highcharts series.
Output should be like JSFiddle but using dynamic data from database obviously.
Finally, I want to display something like
Expenditure Tracking
You will likely need to encode your data. I recommend that you take a look at the answer from here Pass a PHP array to a JavaScript function. Based on this, you should be able to do something like this:
JSON.parse(<?php echo json_encode(join($rows[data], ',')) ?>);
then you should be able to get the result that you want. You might not need the JSON.parse.
I have already implemented full calenedar in php. It works fine . I have called the data from database and shown it in the fullcalendar.
Now I have implemented a dropdown. I have used ajax to call controller that calls my another view.
The controller fetches the data based on the dropdown selection. By default it fetches all the data.
But i am not getting the calendar after ajax call. I have called the script to load full calendar in ajax view.
When I echo in the ajax view page, i get the required data. But I am not able to display the full calendar after the ajax call.
As suggested i have give the code.
My first view:
<link rel="stylesheet" href="http://localhost/drive_training/addons/shared_addons/modules/schedule/css/fullcalendar.print.css" rel="stylesheet" media="print" />
<link rel="stylesheet" href="http://localhost/drive_training/addons/shared_addons/modules/schedule/css/fullcalendar.css" rel="stylesheet" />
<div class="content">
<div id='input'>
<?php echo form_dropdown("package_id", $packagelist, "",'id="packageid"'); ?>
</div>
<div id='calendar'></div>
</div>
<style>
#calendar {
max-width: 900px;
margin: 0 auto;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
$('#packageid').change(function() { //any select change on the dropdown with id country trigger this code
var packageid = $('#packageid').val();
alert(packageid);
$.ajax({
type: "POST",
url: "<?php echo base_url('admin/schedule/scheduledetails/hel') ?>", //here we are calling our user controller and get_cities method with the country_id
data: {'packageid': packageid,},
success: function(data)
{
},
error: function() {
alert('failed');
}
});
});
});
</script>
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
displayEventEnd: {
month: true,
basicWeek: true,
"default": true
},
defaultDate: '2014-11-12',
//editable: true,
eventLimit: true, // allow "more" link when too many events
events:
"<?php echo base_url('admin/schedule/scheduledetails/json');?>",
});
});
</script>
My controller hel function
public function hel()
{
$packageid = 9;//$_POST['packageid'];
// echo "hello";
$coursedetails = $this->course_m->where('course_id',$packageid)->get_all();
// echo "<pre>";print_r($coursedetails); echo "</pre>";
$scheduledetails = array();
foreach ($coursedetails as $details) {
$packagedays = $this->course_m->packagedays($details->id);
$presentdays = $this->attendance_m->count_attendance($details->id);
$startdate = $details->start_date;
$starttime = $details->start_time;
$endtime = $details->end_time;
$postponedays = 0;
//$enddate = date('Y-m-d', strtotime($details->start_date . ' + ' . $packagedays . ' days'));
$postponedays = $this->postpone_m->count_postponedays($details->id);
if ($postponedays == 0) {
$enddate = date('Y-m-d', strtotime($details->start_date . ' + ' . $packagedays . ' days'));
} else {
$add = $postponedays + $packagedays;
$enddate = date('Y-m-d', strtotime($details->start_date . ' + ' . $add . ' days'));
$postponefrom = $this->postpone_m->postponedate($details->id)->postponefrom;
$postponeto = $this->postpone_m->postponedate($details->id)->postponeto;
//echo $postponeto;die;
}
$temp = array
(
array
(
'course_id' => $details->id, //it means acutal course id
'title' => $this->training_package_m->get($details->course_id)->training_code, //course_id means packageid
'start' => $startdate . 'T' . $starttime,
'end' => $enddate . 'T' . $endtime,
'description' => 'Hello gyys how are you all',
'starttime' => $starttime,
'endtime' => $endtime,
// 'postponefrom' => $postponefrom,
//'postponeto' => $postponeto,
'postponeddays' => $postponedays,
'packagedays' => $packagedays,
),
);
$scheduledetails = array_merge($scheduledetails, $temp);
}
// echo json_encode($scheduledetails);
$data['jsondata'] = json_encode($scheduledetails);
//print_r($data['jsondata']);die;
$this->template
->title($this->module_details['name'])
->set_layout(false)
->build('admin/fullcalendarfiltered',$data);
}
My view to load through controller. i.e fullcalendarfiltered view file
<style>
#calendar {
max-width: 900px;
margin: 0 auto;
}
</style>
<div>Test Ajax</div>
<div id='calendar'></div>
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
displayEventEnd: {
month: true,
basicWeek: true,
"default": true
},
defaultDate: '2014-11-22',
//editable: true,
eventLimit: true, // allow "more" link when too many events
events: "<?= $jsondata?>",
});
});
</script>
The view file displays test ajax only. when i echo the json data in view file it is echoed. But the problem is that it wont load in calendar. Infact the calendar is not displayed in fullcalendarfiltered view file
I'm currently trying to create a JSON feed for FullCalendar. I currently have a working example, However the output doesn't get my database into the calendar. Anyone have any ideas? I've been stuck on this now..
In my codes:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href='css/fullcalendar.css' rel='stylesheet' />
<script src='js/jquery-1.9.1.min.js'></script>
<script src='js/jquery-ui-1.10.2.custom.min.js'></script>
<script src='js/fullcalendar.min.js'></script>
<script>
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
editable: true,
events : "test1.php",
eventClick: function(event) {
// opens events in a popup window
window.open(event.url, '', 'width=700,height=600');
return false;
},
loading: function(bool) {
if (bool) {
$('#loading').show();
}else{
$('#loading').hide();
}
}
});
});
</script>
<style>
body {
margin-top: 40px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
}
#calendar {
width: 900px;
margin: 0 auto;
}
</style>
</head>
<body>
<div id='calendar'></div>
</body>
</html>
Code for test1.php
$link = mysql_connect('localhost','root','abc123');
if (!$link) { die('Could not connect: ' . mysql_error()); }
mysql_select_db('trainingcourse');
$result = mysql_query("SELECT * FROM tbl_course ");
Initializes a container array for all of the calendar events
$jsonArray = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$eventtest = $row['courseid'];
$startdate = $row['startdate'];
$starttime = $row['starttime'];
$enddate = $row['enddate'];
$endtime = $row['endtime'];
// Stores each database record to an array
$buildjson = array('courseid' => "$eventtest", 'startdate' => "$startdate", 'enddate' => "$enddate", 'allday' => false);
// Adds each array into the container array
array_push($jsonArray, $buildjson);
}
// Output the json formatted data so that the jQuery call can read it
echo json_encode($jsonArray);
?>
It is unable to display on Calendar.
I am really appreciated for your help.
Could you try this?
<?php
$link = mysql_connect('localhost','root','abc123');
if (!$link) { die('Could not connect: ' . mysql_error()); }
mysql_select_db('trainingcourse',$link);
$result = mysql_query("SELECT * FROM tbl_course ");
while($row = mysql_fetch_assoc($result, MYSQL_ASSOC))
{
$eventtest = $row['courseid'];
$startdate = $row['startdate'];
$starttime = $row['starttime'];
$enddate = $row['enddate'];
$endtime = $row['endtime'];
// Stores each database record to an array
$buildjson[] = array(
'courseid' => $eventtest,
'startdate' => $startdate,
'enddate' => $enddate,
'allday' => false
);
}
// Output the json formatted data so that the jQuery call can read it
echo json_encode($buildjson);
?><br>
Hope it works. Please also try to print the results print_r($buildjson);
try this, it works for me
on your PHP code:
header('Content-Type: application/json');
echo json_encode($jsonArray);
on you html code:
add this option to you calendar:
eventSources: [
// your event source
{
url: 'url/of/your/jsonphp',
type: 'POST',
data: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
error: function() {
alert('there was an error while fetching events!');
},
color: '#dadada',
textColor: '#000000'
}
I am passing Highstock/Highcharts three separate series of data via PHP and for some reason only one series is displayed when the chart is loaded. Here is an example of what my HTML output looks like now: http://bit.ly/15D3Dhi and here is what my full PHP code looks like:
date_default_timezone_set('America/Los_Angeles');
$stocks = array('MSFT' => 'http://ichart.finance.yahoo.com/table.csv?s=MSFT', 'AAPL' => 'http://ichart.finance.yahoo.com/table.csv?s=AAPL', 'FB' => 'http://ichart.finance.yahoo.com/table.csv?s=FB', 'ZNGA' => 'http://ichart.finance.yahoo.com/table.csv?s=ZNGA');
$stocks_data = array();
foreach ($stocks as $key=>$stock) {
$fh = fopen($stock, 'r');
$header = fgetcsv($fh);
$varname = $key . '_data';
$$varname = array();
while ($line = fgetcsv($fh)) {
${$varname}[count($$varname)] = array_combine($header, $line);
}
fclose($fh);
}
foreach($MSFT_data as $val){
$MSFT[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$MSFT = json_encode($MSFT);
foreach($AAPL_data as $val){
$AAPL[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$AAPL = json_encode($AAPL);
foreach($FB_data as $val){
$FB[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$FB = json_encode($FB);
?>
<html>
<head>
<title>
Highcharts + PHP + Stock Data
</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function() {
return (this.value > 0 ? '+' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
plotOptions: {
series: {
compare: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: [{
name: 'MSFT',
data: <?php echo $MSFT; ?>
}, {
name: 'AAPL',
data: <?php echo $AAPL; ?>
}, {
name: 'FB',
data: <?php echo $FB; ?>
}]
});
});
</script>
</head>
<body>
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 500px; min-width: 600px"></div>
</body>
</html>
Can anyone look at my code and see why only one series is showing up? If you look at the source of my HTML output, all data appears to have been passed in the same way, so it's not clear to me why only one series is displayed.
Thanks and let me know if you have any questions or need more information.
Looked at it, and the first thing I noticed is the code is quite clean, but there is a JS error:
Highcharts error #15: www.highcharts.com/errors/15
Title: Highcharts expects data to be sorted
Then I noticed FB is the only one that shows up, but expanding the date range lets you see FB and another series, so the Y axis is to blame.
Out of whim I decided to fix the JS error first, and somehow the Y-axis solved itself. So looks like the JS error is the culprit.
EDITED: Using the much faster array_reverse instead of array_unshift per 585connor's suggestion:
foreach($MSFT_data as $val){
$MSFT[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$MSFT = json_encode(array_reverse($MSFT));
foreach($AAPL_data as $val){
$AAPL[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$AAPL = json_encode(array_reverse($AAPL));
foreach($FB_data as $val){
$FB[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$FB = json_encode(array_reverse($FB));
foreach($ZNGA_data as $val){
$ZNGA[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$ZNGA = json_encode(array_reverse($ZNGA));
I need to read data from text file that have many lines to load into highchart but if I put it as many lines, it will show the messy text please see this link. I don't want like this, I want that if have more than 20 lines in text file, it should be display 2 or 3 graphic of highchart to make the text is easy to see.I have the PHP code and script code as below:
<?php
$PMTA_DATE = date("Y-m-d");
$PMTA_FILE = file_get_contents("../stats_domain_emetteur.switchcall.com.".$PMTA_DATE.".txt");
$lineFromText = explode("\n", $PMTA_FILE);
//$number_bar_charts = 12;
$row = 0;
$cate = "";
$total ="";
$fail = "";
$mailSuc = "";
$title = "";
foreach($lineFromText as $line){
// if($row < $number_bar_charts){
$words = explode(";",$line);
$dateTime .= ','.$words[0];
if($title == ""){
$title = $words[0];
}
$cate .= ','."'$words[5]'";
$total .= ','.$words[6];
$fail .= ','.$words[7];
$mailSuc .= ','.((int)$words[6] - (int)$words[7]);
$row++;
// }
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Colunm Stack Percent Chat</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'PMTA4',
type: 'column'
},
title: {
text: 'PMTA4 - Unitead.info -<?php echo $title;?>'
},
xAxis: {
categories: [<?php echo substr($cate,1);?>]
},
yAxis: {
min: 0,
title: {
text: '% envoi'
}
},
tooltip: {
formatter: function() {
return ''+
this.series.name +': '+ this.y +' ('+ Math.round(this.percentage) +'%)';
}
},
plotOptions: {
column: {
stacking: 'percent'
}
},
series: [{
name: 'Total mail succesful',
data: [<?php echo substr($mailSuc,1);?>]
}, {
name: 'Total mail fail',
data: [<?php echo substr($fail,1);?>]
}]
});
});
});
</script>
</head>
<body>
<script src="js/highcharts.js"></script>
<script src="js/modules/exporting.js"></script>
<div id="PMTA4" style="min-width: 400px; height: 200px; margin-top:10px;"></div>
</body>
</html>
I do not know how to fix this, anyone help me please,Thanks.
If you take a look the reference you'll see that you can style labels.
Using staggerLines to display the label in more than one line, but it's not a good way and you can see why on my demo.
xAxys: {
labels: {
staggerLines: 10
}
}
demo
Or you can try to rotate them.
xAxys: {
labels: {
rotate: 90, // you can use 45 or 60 for a better readability
align: 'left'
}
}
demo
Reference:
http://api.highcharts.com/highstock#xAxis.labels.staggerLines