Update Flot plot with 2 series in realtime - php

I'm working on displaying 2 time series of values using jquery and flot. I'm using them for a small period of time and for now I'm sticking to the examples. Basically I adapted several examples to extract from MySQL database the series using a PHP script that I include in the JQuery script. All works fine this far. I wish to be able to refresh this series every several seconds. This refresh doesn't seem to work and I'm not sure why. Bellow is the jquery code used to generate the graph. I put now part one of the script.
$(function(){
//add data source to flot. 2 datasets with same structure: data in UNIX_TIMESTAMP format, value in DECIMAL format
<?php include 'datasource.php'; ?>;
//declare datasets
var datasets = {
"temperature": {
label: "Temperature (C)",
data: <?php echo json_encode($dataset1); ?>
},
"humidity": {
label: "Humidity (%)",
data: <?php echo json_encode($dataset2); ?>
}
};
//set fixed colors for each series
var i = 0;
$.each(datasets, function(key, val) {
val.color = i;
++i;
});
// insert checkboxes
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
choiceContainer.append(' <input type="checkbox" name="' + key +
'" checked="checked" id="id' + key + '">' +
'<label for="id' + key + '">'
+ val.label + '</label>');
});
choiceContainer.find("input").click(plotAccordingToChoices);
//define plot options
var options = {series: { shadowSize: 0 },
yaxis: { min: <?php echo json_encode($mintemp) ?>, max: <?php echo json_encode($maxtemp) ?> },
xaxis: { show: true, mode: "time", timeformat: "%h:%M %d.%m.%y", labelWidth: "10"}};
//draw plot
function plotAccordingToChoices() {
var data = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key])
data.push(datasets[key]);
});
if (data.length > 0)
$.plot($("#placeholder"), data, options);
}
plotAccordingToChoices();
//define plot refresh timeout
setInterval(plotAccordingToChoices(), 3000);})

The first argument to setInterval should to be a string:
setInterval('plotAccordingToChoices()', 3000);
Or only the function name (not calling it):
setInterval(plotAccordingToChoices, 3000);
See: https://developer.mozilla.org/en/window.setInterval
To get updated data from the server-side (PHP), you also need to do remote calls (AJAX). You may use jQuery getScript function.
Something like this:
function updatePlot() {
$.getScript('update_plot.php');
}
setInterval(updatePlot, 3000);
Then, in your update_plot.php file, you can return JavaScript code mixed with PHP (just like you already did):
<?php // here some PHP code to get your data ?>
// and here some javascript code to use the data
plotAccordingToChoices(); // and finally update the plot

Related

Run jQuery Counter with value from MySQL

I have jQuery counter which move numbers from one fixed number to other fixed number. But I want to create the Counter which end at number which come from MySQL database.
Counter Function Code:
Now It starts value from 99950 and end value is 100000 but I want to change end value. It should be the value which I fetch from mysql.
<script type="text/javascript">
(function($) {
$.fn.countTo = function(options) {
// merge the default plugin settings with the custom options
options = $.extend({}, $.fn.countTo.defaults, options || {});
// how many times to update the value, and how much to increment the value on each update
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;
return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);
function updateTimer() {
value += increment;
loopCount++;
$(_this).html(value.toFixed(options.decimals));
if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}
if (loopCount >= loops) {
clearInterval(interval);
value = options.to;
if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}
});
};
$.fn.countTo.defaults = {
from: 0, // the number the element should start at
to: 100, // the number the element should end at
speed: 1000, // how long it should take to count between the target numbers
refreshInterval: 100, // how often the element should be updated
decimals: 0, // the number of decimal places to show
onUpdate: null, // callback method for every time the element is updated,
onComplete: null, // callback method for when the element finishes updating
};
})(jQuery);
jQuery(function($) {
$('.timer').countTo({
from: 99950,
to: 100000,
speed: 2000,
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
});
</script>
HTML Code:
<h2><span class="timer" style="color:#F44336;font-weight:700; font-size:20px;"></span></h2>
You will need a server side language for getting data extracted from mysql. Say for instance, if you are using PHP as your server side language, in that case you can simply put :
<?php
mysql_connect('host','username','password') or die();
mysql_select_db('your_database_name') or die();
$query='SELECT `min_count`, `max_count` FROM 'your_table_name`;
$row=mysql_query($query);
while($rs=mysql_fetch_array($row)){
$from=$rs[0];
$to=$rs[1];
}
?>
<script type="text/javascript">
(function($) {
$.fn.countTo = function(options) {
// merge the default plugin settings with the custom options
options = $.extend({}, $.fn.countTo.defaults, options || {});
// how many times to update the value, and how much to increment the value on each update
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;
return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);
function updateTimer() {
value += increment;
loopCount++;
$(_this).html(value.toFixed(options.decimals));
if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}
if (loopCount >= loops) {
clearInterval(interval);
value = options.to;
if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}
});
};
$.fn.countTo.defaults = {
from: 0, // the number the element should start at
to: 100, // the number the element should end at
speed: 1000, // how long it should take to count between the target numbers
refreshInterval: 100, // how often the element should be updated
decimals: 0, // the number of decimal places to show
onUpdate: null, // callback method for every time the element is updated,
onComplete: null, // callback method for when the element finishes updating
};
})(jQuery);
jQuery(function($) {
$('.timer').countTo({
from: <?php echo "$from"; ?>,
to: <?php echo "$to"; ?>,
speed: 2000,
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
});
Do you mean, you want to get an sql query to the counter?
You could use AJAX for that, make a php file with an sql query and call it from the script using Ajax.
jQuery code:
$.ajax({
type: "POST",
dataType: "json",
url: 'endpoint to php script',
success: function(data) {
$('.timer').countTo({
from: data.startFrom,
to: data.endOn,
speed: 2000,
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
},
error: function(error) {
console.log(error);
}
});
PHP code:
<?php
//I assume you know how connect to your database and get data
header("Content-Type: application/json", true);
$result = array(
'startFrom' => 1000,
'endOn' => 9000
);
echo json_encode($result);
I thnik it's clear and explain this code is not needed

Ajax result from PHP to be clickable and run a Jquery function

So, I've been learning PHP over the past year or so and recently been playing with Ajax and Jquery. The reason for this is that it seems inefficient to constantly fire PHP scripts off and reload my html each time I want to display or do something.
So what I'm doing: I have a html document with input fields which I need to populate with data. The data is retrieved via a Ajax post call to a PHP script and returns a Json_encoded string. Jquery uses the JSON object to iterate through.
Where I am: I have managed to have Ajax pull back the correct results and populate the input elements I require. The results should be displayed as dynamically named Div IDs as list elements for each. This kind of works but I'm probably over complicating the process.
What I have with this code: So the results come back, and as I start typing in the search box, multiple results will return in the fashion I like. The on(click...) event works to a degree - i.e. it does populate the fields BUT only the last returned result from the Ajax call (last item).
I think the code is almost there (although could be made less complex but it's out of my reach at my current level). It's probably my flow which is wrong (i.e. using .each and then using a click event within it ...) ... I've attempted multiple ways of re-arranging the code but cannot fathom it. Any advice would be amazing. Full code relating to this is attached.
HTML:`
<input type="text" id="search_js" autocomplete="off">
<!-- Show Results -->
<h4 id="results-text"> <b id="search-string"></b> </h4>
<div id="resultsdiv">
<ul id="results">
<!--Results should show up here with custom Div IDs to keep unique -->
</ul>
<!-- END resultsdiv -->
</div>
<!-- End search-container div -->
</div>
...`
PHP:
<?PHP
$search_string = preg_replace("/[^A-Za-z0-9]/", " ", $_POST['query']);
$search_string = "$search_string%";
if (strlen($search_string) >= 1 && $search_string !== ' ') {
// Build Query
$searchstmt = "select * from vw_person_full where name like :s;";
$database->query($searchstmt);
$database->bind(':s', $search_string);
//Custom PDO function - returns associative array
$result_array = $database->resultset();
$output = $result_array;
//convert result array into json format
$json_result = json_encode($output);
echo $json_result;
Jquery:
$(document).ready(function() {
$("input#search_js").on("keyup", function(e) {
// Set Timeout
clearTimeout($.data(this, 'timer'));
// Set Search String
var search_string = $(this).val();
// Do Search
if(search_string == '') {
$("ul#results").fadeOut();
$('h4#results-text').fadeOut();
} else {
$("ul#results").fadeIn();
$('h4#results-text').fadeIn();
$(this).data('timer', setTimeout(search, 100));
};
});
var newsearchres;
function search() {
var query_value = $('input#search_js').val();
var output = '';
//if search box is not empty :
if(query_value !== '') {
$.ajax({
type: "POST",
url: "search.php",
data: {
query: query_value
},
dataType: 'JSON',
cache: false,
success: function(searchres) {
$.each(searchres, function(i, val) {
var countval = i;
//searchres = JSON.parse(searchres);
newsearchres = searchres[i];
console.log(val+" " + countval);
//individual divs for results with ID=divres_##
//output += '<div data-val-index="countval"id="divres' + countval + '" class="cl_divres">';
output += '<div data-val-index="'+countval+'" id="divres' + countval + '" class="cl_divres">';
output += '<li>' + val.fighter_name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>';
//Display output in the result div:
$('#resultsdiv').html(output);
console.log(searchres);
});
}
});
};
}
function showDetail(ref) {
var val_id = $(ref).attr('data-val-index');
var val = $.each(newsearchres, function(i, val2) {
if(i == val_id) return val2;
});
$("#pid").prop({
"value": val.pid
});
$("#firstname").prop({
"value": val.first_name
});
$("#lastname").prop({
"value": val.last_name
});
$("#fightername").prop({
"value": val.fighter_name
});
$("#addressl1").prop({
"value": val.address_line1
});
$("#addressl2").prop({
"value": val.address_line2
});
$("#town").prop({
"value": val.town
});
$("#city").prop({
"value": val.city
});
$("#county").prop({
"value": val.county
});
$("#postcode").prop({
"value": val.postcode
});
$("#dob").prop({
"value": val.dob
});
$("#nat").prop({
"value": val.nationality
});
$("#email").prop({
"value": val.email
});
$("#homephone").prop({
"value": val.home_phone
});
$("#mobilephone").prop({
"value": val.mobile_phone
});
};
// $(document).find("div[id^='divres_']").on('click', function() {
$(document).on('click', 'div[id^="divres"]', function() {
console.log(this);
console.log("clicked");
showDetail(this);
});
});
Really sorry for crappy image - but hopefully it makes sense.
First thing that comes to mind right now is that you are ending the search result div at each item. I am only inclined to this because I see you open a new div in the $.each but you close 2.
See below:
$.each(searchres, function (i, val) {
var countval = i;
//individual divs for results with ID=divres_##
output += '<div id="divres_' + countval + '" class="cl_divres">';
output += '<li>' + val.name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>'; // <--- add this after the $.each?
The possible reason is that "You are accessing the val for each li events that is accesing outside the each iteration so getting the last values only ."
So try to get the values from index .something as below -
$.each(searchres, function (i, val) {
var countval = i;
//individual divs for results with ID=divres_##
output += '<div data-val-index="countval"
id="divres_' + countval + '" class="cl_divres">';
output += '<li>' + val.name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>';
//Display output in the result div:
$('#resultsdiv').html(output);
$(document).find("div[id^='divres_']").on('click',function(){showDetail(this); });
});
Now your callback for event may be as -
function showDetail(ref)
{
var val_id=$(ref).attr('data-val-index');
var val=$.each(searchres, function (i, val2) { if(i==val_id) return val2 ;});
$("#pid").prop({"value": val.pid});
$("#firstname").prop({"value": val.first_name});
$("#lastname").prop({"value": val.last_name});
$("#fightername").prop({"value": val.name});
$("#addressl1").prop({"value": val.address_line1});
$("#addressl2").prop({"value": val.address_line2});
$("#town").prop({"value": val.town});
$("#city").prop({"value": val.city});
$("#county").prop({"value": val.county});
$("#postcode").prop({"value": val.postcode});
$("#dob").prop({"value": val.dob});
$("#nat").prop({"value": val.nationality});
$("#email").prop({"value": val.email});
$("#homephone").prop({"value": val.home_phone});
$("#mobilephone").prop({"value": val.mobile_phone});
}

Installation progress bar php

I have a simple installer that's divided in segments, not by syntax, but just by logic. Here's how it works:
if ($_POST['install'] == "Install")
{
// fetches user values
// creates tables
// creates some files
// creates some emails
// inserts relevant stuff into the database
// finishes
}
The code is too long and unnecessary for this question. Each of those steps counts as 20% complete for the installation, how would I make a progress bar displaying the info to the user? I'd like this for two reasons, one is for them to keep track, other is for them to know they shouldn't close the browser tab before it's done.
Now my idea is to assign a variable to each part of the code, for instance $done = 20% in the first, $done = 40% in the second etc, and simply show progress bar based on that variable. The the only thing I don't know is how to show the progress bar?
Thanks
My recommended solution:
Create separate ajax requests for each step in your process like so...
// do first step
$.ajax({
url: myUrl + '?step=1',
success: function() {
// update progress bar 20%
}
});
// do second step
$.ajax({
url: myUrl + '?step=2',
success: function() {
// update progress bar 40%
}
});
// etc.
If you want to be DRY, try this:
var steps = 5;
for (var i = 1; i <= steps; i++) {
$.ajax({
url: myUrl + '?step=' + i;
success: function() {
// update success incrementally
}
});
}
With jQuery UI progressbar:
$(function() {
$("#progressbar").progressbar({
value: 0
});
var steps = 5;
for (var i = 1; i <= steps; i++) {
$.ajax({
url: myUrl + '?step=' + i;
success: function() {
// update success incrementally
$("#progressbar").progressbar('value', i * 20);
}
});
}
});
Ref. http://jqueryui.com/progressbar/#default
The best practice is to store the progress value in a db or a key-value storage system such as APC, Memcache or Redis. And then retrieve the progress with an ajax query.
A good jquery plugin is progressbar bar from jQuery-ui, and you can use json to encode the progress value:
// GET /ajax/get-status.json
{
"progress":10,
"error":"",
"warning":""
}
The page:
<div id="error" style="color: red"></div>
<div id="warning" style="color: yellow"></div>
<div id="message"></div>
<div id="progressbar"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
$("#progressbar").progressbar({ value: 0 });
$.ajaxSetup({ cache: false });
function updateProgress() {
jQuery.getJSON("/ajax/get-status.json", function(response) {
if (response.error) {
$("#error").html( response.error );
return;
} else {
$("#progressbar").progressbar( 'value', parseInt( response.progress ) ); // Add the new value to the progress bar
$("#message").html( response.message );
$("#warning").html( response.warning );
if(parseInt( response.progress ) < 100){
setTimeout(updateProgress, 1);
}
}
});
}
updateProgress();
});
</script>
You can use an HTML5 progress bar.
Send ajax request and return the percent complete.
Change the progress tag's value.
<progress id='p' max="100" value="50"></progress>

Unable to navigate Dynamically created pages in DOM

After so many trials, I have finally managed to create pages dynamically using PHP, JSON and AJAX and load them into DOM. But the problem now is I'm unable to call/navigate those pages dynamically, but manually i.e gallery.html#page1 ...etc.
I seek guidance rather than burdening you, as I'm here to learn.
**PHP - photos.php **
$photos = array();
$i=0;
while ($row = mysqli_fetch_array($query)){
$img = $row["fn"];
$photos[] = $img;
$i++;
}
$count = count($photos);
echo json_encode(array('status' => 'success', 'count' => $count, 'items' => $photos));
JSON array
{
"status":"success",
"count":3,
"items":
[
"img1.jpg",
"img2.jpg",
"img3.jpg"
]
}
I use the below method to fetch and store ID of the desired gallery,
<input type="hidden" value="<?php echo $id; ?>" id="displayid" />
and then I call it back to use it in AJAX.
var ID = $('#displayid').val();
AJAX and JQM
$.ajax({
Type: "GET",
url: 'photos.php',
data: { display: ID }, // = $('#displayid').val();
dataType: "json",
contentType: "application/json",
success: function(data) {
var count = data.count;
var number = 0;
$.each(data.items, function(i,item) {
var newPage = $("<div data-role=page data-url=page" + number + "><div data-role=header><h1>Photo " + number + "</h1></div><div data-role=content><img src=" + item + " /></div></div");
newPage.appendTo( $.mobile.pageContainer );
number++;
if (number == count) { $.mobile.changePage( newPage ); }; // it goes to last page
I got this code from here thanks Gajotres to dynamically navigate between pages. It's within the same code.
$(document).on('pagebeforeshow', '[data-role="page"]', function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.activePage.find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'b'}).addClass('ui-btn-right').html('Next').button());
}
}); // next button
}); // each loop
} // success
}); //ajax
I found your problem.
This part of code can't be used here like this:
$(document).on('pagebeforeshow', '[data-role="page"]', function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.activePage.find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'b'}).addClass('ui-btn-right').html('Next').button());
}
});
This is the problem. First remove pagebeforeshow event binding, it can't be used here like that. Rest of the code is not going to do anything because currently there are any next page (next page is going to be generated during then next loop iteration), so remove this whole block.
Now, after the each block ends and all pages are generated (that is the main thing, all pages should exist at this point), add this code:
$('[data-role="page"]').each(function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$(this).find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'a'}).addClass('ui-btn-right').html('Next').button());
}
});
This is what will happen. Each loop will loop through every available page (we have them all by now) and in case it is not the last one it will add next button.
Here's a live example: http://jsfiddle.net/Gajotres/Xjkvq/
Ok in this example pages are already there, but point is the same. They need to exist (no matter if you add them dynamically or if they are preexisting) before you can add next buttons.
I hope this helps.

Retrieving data from server using jquery $.get function

I am creating a real-time graph with flot library and using jquery $.get function.
I want the graph to be updated every 5 seconds retrieving the recorded data.
The X axis is in time mode. I have been trying to retrieve the necessary data but i can't get it yet. The .php file is fine because it connects to the postgresql database and writes the data into the requested variable.
I think that my problem is in the $.get function.
Can you please help me to find if my Javascript code is fine?
Thanks in advance
<script type="text/javascript">
$(function () {
var data=[];
var data_inicial = [];
var data_actual = [];
var x;
var y;
function data_init()
{
$.get("param_pozos_linea1.php", function(data1) { x= data1; });
data_inicial.push([x]);
return data_inicial;
}
function actualiza_data()
{
$.get("param_pozos_linea2.php", function(data2) { y= data2; });
data_actual.push(y);
return data_actual;
}
// control de velocidad
var updateInterval = 500;
$("#updateInterval").val(updateInterval).change(function () {
var v = $(this).val();
if (v && !isNaN(+v)) {
updateInterval = +v;
if (updateInterval < 1)
updateInterval = 1;
$(this).val("" + updateInterval);
}
});
// setup plot
var options = {
series: { shadowSize: 0 }, // drawing is faster without shadows
yaxis: { min: 0, max: 100 },
xaxis: { mode: "time",tickLength: 5, timeformat: "%d/%m - %h:%M %p"}
};
var plot = $.plot($("#placeholder"), data_init() , options);
function update() {
plot.setData([ actualiza_data() ]);
plot.draw();
setTimeout(update, updateInterval);
}
update();
});
</script>
The retrieved data from "param_pozos_linea1.php" file loooks like this:
[1355767803000,0],[1355767502000,0],[1355767202000,0],[1355766902000,0],[1355766602000,0],[1355766302000,0],[1355766002000,0],[1355765702000,0],[1355765402000,0],[1355765103000,2570.17],[1355764803000,2569.63]
And the retrieved data from "param_pozos_linea2.php" looks like this:
[1355767803000,0]
The get request is asynchronous, it is impossible for it to work in a synchronous manner like you think it does.
function data_init()
{
$.get("param_pozos_linea1.php", function(data1) { x= data1; }); <-- calls the server asynchronously
data_inicial.push([x]); <-- is called before code is set on server, so it is setting it with what ever the last value was
return data_inicial; <-- returns something you do not want
}
what you want to do is call the function that set the data
function data_init()
{
$.get("param_pozos_linea1.php",
function(data1) {
data_inicial.push([data1]);
callYourPlotFunction(data_inicial);
}
);
}

Categories