flot chart with json data is empty - php

I need to plot chart in flot with data returned by a php script as json encoded data
i get the data in through jquery like this
$("button").click(function(){
var dp1 = $('#dp1').val();
var dp2 = $('#dp2').val();
$.ajax({
type: "GET",
url: "chart.php",
datatype:"json",
success: onSuccess,
data: {d1:dp1, d2:dp1}
});
function onSuccess(series) {
var plotarea = $("#pieChart");
plotarea.css("height", "300px");
plotarea.css("width", "400px");
$.plot( plotarea , [
{
data: series,
bars: {
show: true
}
}
] );
}
});
the data return is json encoded i can see it in firebug like so
[["ebbok1",39.55],["ebbok2",92.23],["ebbok3",102.44]]
but my chart is empty
the php file returning the json data is
$dataset = array();
while($row = $result->fetch_array(MYSQLI_ASSOC)) {
//echo $row['amount'] . "\t" . $row['product_name']. "\n";
$dataset[] = array( $row['product_name'], $row['amount'] );
}
echo json_encode($dataset,JSON_NUMERIC_CHECK);
what am i doing wrong?
EDIT
i modified my php script, it now returns data like this
[{"label":"ebook1","data":39.55},{"label":"ebook2","data":92.23},{"label":"ebook3","data":102.44}]
but i still get empty chart

Your $.plot call doesn't look correct. You are mixing the options and data together.
var series = [
{"label":"ebbok1","data":12},
{"label":"ebook1","data":27.55},
{"label":"ebook2","data":92.33},
{"label":"ebook3","data":102.44}
];
$.plot( $("#somePlot") , series,
{
series: {
pie: {
show: true
}
}
}
);
See fiddle here.

You've misunderstood how a set of data is expected for flot.
You have:
series = [["label",1],["label2",2],... ];
Flot expects data formatted like this:
series = [[[x1,y1],[x2,y2],...]];// where xN and yN are all NUMBERS
See also the documentation on this topic.
So assuming that you really want to see the labels you've specified, one way to deal with that is to use the ticks property of the xaxis. So you'd return two sets of data:
data = [[[0,1],[1,1],...]];
tickLabels = [[0,"label1"],[1,"label2"],...];
Then in your flot options specify this:
$.plot( plotarea , data, {
series: {
bars: {
show:true;
}
},
xaxis: {
ticks:tickLabels
}
} );
Example: http://jsfiddle.net/ryleyb/8gGEz/1/
EDIT: If you want to keep returning your series data the same way, you can do the manipulation in the javascript:
var tickLabels = [];
for (var i =0;i<series.length;i++){
tickLabels.push([i,series[i][0]);
series[i][0] = i;
}
var data = [series];
//now you can call flot as I described above.

I meet the same problem with you. But now I figure it out.
The problem is cause by your data
[["ebbok1",39.55],["ebbok2",92.23],["ebbok3",102.44]]
It look like what you want to show at x-axis is "category" type.
So flot(v0.8.2) provide 'categories' mode to present the x-axis show what you want as categories.
As following:
Step1: add categories module to your HTML
<script type="text/javascript" src="flot/jquery.flot.categories.js"></script>
Step2: add the following to your js.
var options={
xaxis:{mode: "categories"}
};
try it and enjoy it :)

Related

Updating Chart.js Datasets - Array not re-initializing (Jquery / PHP)

I am using Chart.js (v 3.3.2) to display a bar graph (myChart) with a dropdown filter. I have an event listener for my dropdown to update the PHP/SQL query to fetch the correct data - this works perfectly.
But my graph still displays the old data after the update (With disabling cache). The ajax function is POST'ing correctly. Following the chart.js docs on updating the datasets :: Updating Charts
I declare chart, label, data in my ajax: success function's params.
In my success function:
success: function (chart, label, data) {
myChart.data.labels.push(label); //Push the labels for chart
myChart.data.datasets.forEach((dataset) => { //Push data for each dataset
dataset.data.push(data); });
console.log(myChart.data.labels); // Log new labels
console.log(myChart.data.datasets);// Log new array
myChart.update(); // Update my chart
}
I look at the response from my PHP fetch file, and the correct data can be seen in the the inspector. But when looking at the data in my console log, I am still seeing the old data.
So I approached this all wrong. The select.on.change() should have been called outside the function, and when executing, call the showSuccessRate() function.
Here is the working code:
$(document).ready(function(){
$('#selectTop')
.on('change', // When the user changed the select option, run this
function () {
$('#clisuccessrate-chart').remove(); //Remove the chart canvas (because it would have loaded when document ready)
$('div#clisuccessrate-container').append('<canvas id="clisuccessrate-chart" height="200"></canvas>'); // Add the canvas back into the html
showSuccessRate(); // Call the function to draw the chart
})// end onchange event
showSuccessRate(); // Make the Bar Chart when document is ready
function showSuccessRate(){ // Build Bar Graph
{var selectedOption = $('#selectTop').children('option:selected').val(); // Get the value of the option, use this value to set limit in PHP SQL Query
$.ajax("database/cliSuccessFail-filter.php", {data: {topSelect: selectedOption} ,method:'POST', success: function (data) {
console.log('The selected option value is: ' + selectedOption); // Log the value to check response
var mx_cli = [];
var mx_success = [];
var mx_failure = [];
var mx_attempts = [];
// ^ Declare empty array
for (var i in data) {
mx_cli.push(data[i].mx_cli);
mx_success.push(data[i].mx_success);
mx_failure.push(data[i].mx_failure);
mx_attempts.push(data[i].mx_attempts);
};
// ^ Populate the arrays
var csf_datasets = {
labels: mx_cli, // Assign label
datasets: [{
backgroundColor: '#007bff',
borderColor: '#007bff',
data: mx_success,
label: 'Successful'
},
{
backgroundColor: '#ced4da',
borderColor: '#ced4da',
data: mx_failure,
label: 'Unsuccessful'
}
]
};
var csf_options = {
maintainAspectRatio: false,
};
var csf_config = {
type: 'bar',
data: csf_datasets, // Bind dataset
options: csf_options, // Bind options
}
var $cliSuccessRateChart = $('#clisuccessrate-chart'); // Get the canvas ID
var myChart = new Chart($cliSuccessRateChart, csf_config); // Draw the chart
} }) // END POST
}
}// END FUNCTION showSuccessRate
}); //End document.ready()

onchange F(x) to php to Highchart on same page

I am continuing a previous question that was asked onclick -> mysql query -> javascript; same page
This is my onchange function for a drop down of names. it is called when each drop down is changed. The idea is to send each runners name into the php page to run a mysql query then return 3 arrays to be entered into javascript.
function sendCharts() {
var awayTeam = document.getElementById('awayRunner').value;
var homeTeam = document.getElementById('homeRunner').value;
if(window.XMLHttpRequest) {
xmlhttp14 = new XMLHttpRequest();
}
else {
xmlhttp14 = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp14.onreadystatechange = function() {
if(xmlhttp14.readyState == 4 && xmlhttp14.status == 200) {
var parts = xmlhttp14.responseText.split(','); //THIS IS WHAT IS RETURNED FROM THE MYSQL QUERY. WHEN I ALERT IT, IT OUTPUTS IN THE FORM 14,15,18,16,17,12,13
... code that generates the chart
series: [ {
name: document.getElementById('awayRunner').value,
data: [parts,','], //THIS IS WHERE AN ARRAY MUST BE ENTERED. THIS OUPUTS ONLY ONE NUMBER
type: 'column',
pointStart: 0
//pointInterval
},
{
name: document.getElementById('homeRunner').value,
data: parts, // TRIED THIS
type: 'column',
pointStart: 0
//pointInterval
},
{
name: 'League Avg',
data: [], //THIS IS WHERE 3rd ARRAY MUST BE ENTERED
type:'spline',
pointStart: 0
//pointInterval
},
]
});
}
}
xmlhttp14.open("GET", "getCharts.php?awayRunner="+awayRunner+"&homeRunner="+homeRunner, true);
xmlhttp14.send();
}
my php code looks like this. As you'll see, there are 3 arrays that must be returned to be entered into different spots in the javascript to generate the code.
$away=$_GET['awayRunner'];
$home=$_GET['homeRunner'];
$db=mydb;
$homeRunner=array();
$awayRunner = array();
$totalOverall= array();
$getHome="select column from $db where tmName = '$home'";
$result2 = mysql_query($getHome);
while($row = mysql_fetch_array($result2)){
$homeRunner[]= $row['column'];
}
$getAway="select column from $db where tmName ='$away'";
$result22 = mysql_query($getAway);
while($row2 = mysql_fetch_array($result22)){
$awayRunner[]= $row2['column'];
}
$week = 0;
while($week<20){
$week++;
$teamCount = "select count(column) from $db where week = $week";
$resultTeam = mysql_query($teamCount);
$rowTeam = mysql_fetch_array($resultTeam);
$t = $rowTeam['count(column)'];
$getLeague = "select sum(column) from $db where week = $week";
$resultLeague = mysql_query($getLeague);
while($row3 = mysql_fetch_array($resultLeague)){
$totalOverall[]=$row3['sum(column)']/$t;
}
}
echo join(',',$awayRunner);
currently, by doing it this way, the chart only outputs the second value in the array. for instance, if var parts is equal to 23,25,26,24,23...only 25 is shown.
A previous question resulted with the following answer -
Load the page.
User chooses an option.
An onChange listener fires off an AJAX request
The server receives and processes the request
The server sends back a JSON array of options for the dependent select
The client side AJAX sender gets the response back
The client updates the select to have the values from the JSON array.
I'm lost on #'s 5 - 7. Can someone provide examples of code that gets this done? Normally, I would just ask for direction, but I have been stuck on this problem for days. I'm about ready to scrap the idea of having charts on my site. Thanks in advance
EDIT
this is the first change that I have made to send and receive just one request
<script>
$(function(){
$("#awayRunner").change(function(){
$.ajax({
type: "POST",
data: "data=" + $("#awayRunner").val(),
dataType: "json",
url: "/my.php",
success: function(response){
alert(response);
}
});
});
});
The data displayed in the alertbox is in the form 12,15,16,15. Now, when I enter in
data: response,
only the second number from each is being displayed in the chart. Any ideas?
EDIT
OK, so i figured out that the info in response is a string. It must be converted to an INT using parseInt to be usable in the chart. currently, I have
$("#awayTeam").change(function(){
$.ajax({
type: "POST",
data: "away=" + $("#awayTeam").val(),
dataType: "json",
url: "/getCharts.php",
success: function(response){
var asdf = [];
asdf[0] = parseInt(response[0]);
asdf[1] = parseInt(response[1]);
asdf[2] = parseInt(response[2]);
asdf[3] = parseInt(response[3]);
alert(asdf);
will have to write a function to make this cleaner.
I can't believe it, but I finally got it. here is how I used an onchange method to stimulate a MYSQL query and have the Highchart display the result. The major problem was that the returned JSON array was a string that needed to be converted into an INT. The resultArray variable is then used in the data: portion of the highChart.
$(function(){
$("#awayTeam").change(function(){
$.ajax({
type: "POST",
data: "away=" + $("#awayRunner").val(),
dataType: "json",
url: "/getCharts.php",
success: function(response){
var arrayLength = response.length;
var resultArray = [];
var i = 0;
while(i<arrayLength){
resultArray[i] = parseInt(response[i]);
i++;
}
In the PHP code, the array must be returned as JSON like this
echo json_encode($awayRunner);

Display returned JSON objects with jQuery

I'm having trouble figuring out how to display some return JSON objects.
My script works like this:
I'm making an ajax call, sending some params to a CodeIgniter Controller where I'm processing it with a model, making some queries towards an database and then returning the json_encoded rows to the ajax callback function. This works great btw.
Here is what I want to do now and here its where I'm stuck. I want the new JSON objects (contains database rows) to "replace" the old rows in a html table. So I want it to update the table depending on the params I'm passing but only in the tbody mind.
I'm new at jquery so I've tried i few things. I've tried iterate trough the json data and use the $.html(string) function but i guess this replace everything and it will eventually just display the last object(Am i right?).
So I wonder how in a general sense I would do this?
$.ajax({
type: 'GET',
url: 'someSite.com/someEndpoint'
data: xyz.
success: function( response ) {
//lets say you have an object like this: object = { data: { ... } }
var html = '';
for(var i = 0; i<response.data.length; i++) {
html += '<tr><td>'+response.data[i].title+'</td></tr>';
}
$('#someTable tbody').html(html);
}
});
You don't have to return JSON objects in an AJAX request. Try setting the data_type config setting for the $.ajax call to "html" (or leave it blank--jQuery is really good about figuring it out from the response data).
I usually factor out the <tbody>...</tbody> portion of a view to its own view partial. Then, the "original" page load can use it, and so can an updating AJAX call.
The only asterisk to this is if you need some sort of object-oriented response along with the HTML. I would usually do something like this:
{
"stat": "ok",
"payload": "<tr><td>row1</td></tr><tr><td>row2</td></tr>"
}
And then in the ajax success function:
$.post('/controller/action', { some: 'data' }, function(response) {
$('#my_table tbody').append(response.payload);
}, 'json');
What are the params your passing in?
for example you might use a select or input field to trigger an ajax call and pass its value as the param.
var tableObj = {
var init : function(){
//check that your selectors id exists, then call it
this.foo();
},
foo : function(){
var requestAjax = function(param){
var data = {param : param}
$.ajax({
data : data,
success : function(callback){
console.log(callback);//debug it
$("tbody").empty();//remove existing data
for(var i =0; i < callback.data.length; i++){}//run a loop on the data an build tbody contents
$("tbody").append(someElements);//append new data
}
});
}
//trigger event for bar
$("#bar").keyup(function(){
requestAjax($(this).val());
});
}
}
$(function(){
tableObj.init();
})
Your php method
public function my_method(){
if($this->input->is_ajax_request())
{
//change the output, no view
$json = array(
'status' => 'ok',
'data' => $object
);
$this->output
->set_content_type('application/json')
->set_output(json_encode($json));
}
else
{
show_404();
}
}

Autocomplete in jQgrid with JSON data returned by a Php page

I was trying to implement autocomplete for a textbox which is generated by jQgrid. A Php page would return JSON data. Here's what I was able to do so far: (Please help)
function autocomplete_element(value, options) {
var $ac = $('<input type="text"/>');
$ac.val(value);
$ac.autocomplete({
source: function(request, response) {
$.getJSON("autocomplete.php", { q: request.term }, response);
}
});
return $ac;
}
function autocomplete_value(elem, op, value) {
if (op == "set") {
$(elem).val(value);
}
return $(elem).val();
}
$(function(){
$("#list").jqGrid({
url:'process1.php',
datatype: 'xml',
mtype: 'GET',
colNames:['Column Name'],
colModel :[
{name:'columnid', index:'columnid', width:50, edittype:'custom',
editoptions: {
custom_element : autocomplete_element,
custom_value : autocomplete_value
}
}
]
........
........
////////////////////////////////////////////////
/// THE PHP PAGE ////
////////////////////////////////////////////////
/*
autocomplete.php
*/
<?php
require_once("../dbconfig.php");
$term = trim(strip_tags($_REQUEST['q']));//retrieve the search term that autocomplete sends
$qstring = "SELECT description as value, id FROM test WHERE name LIKE '%".$term."%'";
$result = mysql_query($qstring);//query the database for entries containing the term
while ($row = mysql_fetch_array($result,MYSQL_ASSOC))//loop through the retrieved values
{
$row['id']=(int)$row['id'];
$row['value']=htmlentities(stripslashes($row['value']));
$row_set[] = $row;//build an array
}
echo json_encode($row_set);//format the array into json data
?>
When I use data such as ["blah","hello","howdy"] in source of $ac.autocomplete, the thing seems to work nicely. But I have around 2000 rows of data to search from. The jQgrid form is working correctly and I am being able to add & edit data. Also, I have tested the php page which displays proper JSON data when I point a browser at it. I am only struck with autocomplete with data returned from the php page since I am not much comfortable with jQuery. Please help.
Try adding exit() after the last echo in php code. I hope this will fix.

JSON returned as individual string and not objects

I am using Codeigniter and trying to use the jQuery autocomplete with it. I am also using #Phil Sturgeon client rest library for Codeigniter because I am getting the autocomplete data from netflix. I am return correct JSON and I can access the first element with
response(data.autocomplete.autocomplete_item[0].title.short);
but when I loop through the results
for (var i in data.autocomplete.autocomplete_item) {
response(data.autocomplete.autocomplete_item[i].title.short)
}
it acts like a string. Lets say the result is "Swingers", it will return:
Object.value = s
Object.value = w
Object.value = i
and so on.
the js:
$("#movies").autocomplete({
source: function(request, response) {
$.ajax({
url: "<?php echo site_url();?>/welcome/search",
dataType: "JSON",
type:"POST",
data: {
q: request.term
},
success: function(data) {
for (var i in data.autocomplete.autocomplete_item) {
response(data.autocomplete.autocomplete_item[i].title.short);
}
}
});
}
}).data("autocomplete")._renderItem = function(ul, item) {
//console.log(item);
$(ul).attr('id', 'search-autocomplete');
return $("<li class=\""+item.type+"\"></li>").data( "item.autocomplete", item ).append(""+item.title+"").appendTo(ul);
};
the controller:
public function search(){
$search = $this->input->post('q');
// Run some setup
$this->rest->initialize(array('server' => 'http://api.netflix.com/'));
// set var equal to results
$netflix_query = $this->rest->get('catalog/titles/autocomplete', array('oauth_consumer_key'=>$this->consumer_key,'term'=> $search,'output'=>'json'));
//$this->rest->debug();
//$json_data = $this->load->view('nice',$data,true);
//return $json_data;
echo json_encode($netflix_query);
}
the json return
{"autocomplete":
{"autocomplete_item":[
{"title":{"short":"The Strawberry Shortcake Movie: Sky's the Limit"}},
{"title":{"short":"Futurama the Movie: Bender's Big Score"}},
{"title":{"short":"Daffy Duck's Movie: Fantastic Island"}}
...
any ideas?
thanks.
there are some console logs with the return
the url
in, as you've noticed, doesn't do what you'd like with arrays. Use $.each
As far as I know, for (property in object) means that you want to access each of its properties rather than accessing them via the index. If you want to access them via the index, you probably want to use the standard for loop.
for (i = 0; i <= 10; i++) {
response(data.autocomplete.autocomplete_item[i].title.short);
}
or if you still want to use your code, try this:
for (i in data.autocomplete.autocomplete_item) {
response(i.title.short);
}
I haven't test them yet but I think you have the idea.
ok I figured out the correct format that I need to send to the autocomplete response method:
the view
$("#movies").autocomplete({
minLength: 2,
source: function(request, response) {
$.post("<?php echo base_url();?>welcome/search", {q: request.term},
function(data){
//console.log(data);
response(data);
}, 'json');
}
});
the controller:
$search = $this->input->post('q');
// Run some setup
$this->rest->initialize(array('server' => 'http://api.netflix.com/'));
// Pull in an array
$netflix_query = $this->rest->get('catalog/titles/autocomplete', array('oauth_consumer_key'=>$this->consumer_key,'term'=> $search,'output'=>'json'),'json');
$json = array();
foreach($netflix_query->autocomplete->autocomplete_item as $item){
$temp = array("label" => $item->title->short);
array_push($json,$temp);
}
echo json_encode($json);
what was needed was to send back to the view an array of objects. Thank you guys for all your answers and help!!

Categories