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()
Related
I am trying to update a webpage on the fly after inserting some data in the db and returning a json object to no avail.
Let's say I have
<div id="try1"> try(<span id="votes1">0</span>)</div>
When loeaded the page displays the current number of votes, (0) at the moment.
then I have a button
<button onclick="vote(1);">+</button>
that calls this function:
function vote(votes_id)
{
var div = 'try' +votes_id;
var url = 'vote.php?id=' +votes_id;
var destination = '#votes' +votes_id;
$.getJSON( url, function(data) {
$(destination).html (data.votes);
});
}
my vote.php returns this json or after correctly updating the db or, at least that is what I think
{"votes":"1"}
However my webpage doesn't get updated from 0 to 1,
I use $data = json_encode($data);
the result of which as var_dump is:
string '{"votes":"1"}'
and
{"votes":"1"}
as echo $data.
What am I possibly missing?
That's because you are putting he success callback in the wrong place.
Use:
function vote(votes_id)
{
var div = 'try' +votes_id;
var url = 'vote.php?id=' +votes_id;
var destination = '#votes' +votes_id;
$.getJSON( url, {}, function(data) {
$(destination).html (data.votes);
});
}
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 :)
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();
}
}
As you can see i am noob at jquery / javascript, i need to pass variable to GET or POST written in form and the result from php need to be passed to jquery, i started to write smthing as below, but it doesnt work.
anyone help me out please
// id and settings for msg box
$("#registerin").click(function() {
$.msgbox("<p>In order to process your request you must provide the following:</p>", {
type : "prompt",
inputs : [
{type: "text",label: "Insert your Name:", value: "George", required: true},
],
buttons : [
{type: "submit", value: "OK"},
{type: "cancel", value: "Exit"}
]
}, // id and settings for msg box - end
function(name) {
// checking if name field has been set
if(name) {
// pass from field to php $_GET['name_php'] variable
$.get("form.php", {name_php: name },
**// rewriten**
function(data) {
if (data){
// inline the data creation/insertion
$.msgbox($('#textbox').html(data), {type: "info"});
} // if data end
}); // function data end
**// rewriten**
} // if name end
}); // function name end
}); // registerin click
$.get is an asynchronous function call, so that means that code below it is not garunteed to be run AFTER it has been proccessed. your callback function inside the $.get call should look like this:
function(data) {
if (data){
// inline the data creation/insertion
$.msgbox($('#textbox').html(data), {type: "info"});
}
}
The JS
SWFlocation = "open-flash-chart.swf";
getMyData = function()
{
$.post(
myJsURL,
{
passedval: 1234
},
function (returned_json) {
return returned_json;
},
"json"
);
}
swfobject.embedSWF(SWFlocation, "myChartDiv", "650", "200", "9.0.0", "", {"get-data":"getMyData"} );
Using firebug, if I hardcode the returned JSON, the chart works fine. But when I request the data as above - i.e. after the page has loaded, I get a 2032 error.
The getMyData method actually requests data from a PHP script that in turn requests data from and extrnal API (a big one like flickr) so there can be a few seconds delay if the results are not currently cached by us. Maybe I'm going about this the wrong way?
You have to put the swfobject.embedSWF() into the ajax callback.
like this:
SWFlocation = "open-flash-chart.swf";
init_chart = function()
{
$.post(
myJsURL,
{
passedval: 1234
},
function (returned_json) {
swfobject.embedSWF(SWFlocation, "myChartDiv", "650", "200", "9.0.0", "", {"get-data":returned_json} );
},
"json"
);
}
init_chart();
just use $.ajaxSetup({async : false}); before you call $.post();
example
function ajaxchart() {
$.ajaxSetup({async : false});
var chart = '';
var url = "data.php";
var data = '';
var callback = function(resp) {
chart = resp;
};
$.post(url, data, callback, 'text');
return chart;
}
$(function() {
$("#test").click(function() {
swfobject.embedSWF("open-flash-chart.swf", "my_chart", "350", "200", "9.0.0", "expressInstall.swf", {"get-data":"ajaxchart"});
});
});
Just a guess as I don't use Open Flash Chart but since you're making an async ajax call your getMyData function is not actually returning the json value (the callback function you defined is).
Try preloading (maybe make a synchronous ajax call before the swf embed?) the data and storing it in a var, then have your getMyData function simply return that var.
In Javascript, declair a variable flashvars and a var data like this:
var flashvars = {};
var data;
Also, make sure that you have this function, which is automatically called by swfobject.embedSWF:
function open_flash_chart_data(){
return JSON.stringify(data);
}
Now go to your AJAX-function and change your AJAX-Success-call like this:
success: function(returned_json){
// we need to set both
// data and flashvars.ofc
data=returned_json;
flashvars.ofc = returned_json;
swfobject.embedSWF(SWFlocation, "myChartDiv", "650", "200", "9.0.0", "",flashvars);
I had a similar problem, and it was quite hard to debug that you need both vars data and flashvars in the success callback. If these variables (or function open_flash_chart_data() ) are missing, you'll get Error 2032.