Ajax and Highcharts - Display 'loading' until data is retrieved, then populate chart - ajax

I have some php scripts which esentially take a long time to retrieve data. As a result this impacts highcharts loading times as the current code I have only writes the chart once all the data is retrieved as the highcharts code is only echoed once all processing is complete.
This causes the page to basically show nothing until the data is retrieved. The goal is to have the highcharts load immedietly and then write to the series with the data returned by the php scripts.
So, what I'm looking to to is have all the graphs load immedietly and display 'loading' with no data and then use setData to pass in the data to the graph series once the php scripts have completed.
I'm just wondering if anyone had any examples of this being done? Another problem I'm having is only being able to set the data within the $(document).ready(function() function. e.g.
works:
http://preview.tinyurl.com/b724bxo
breaks:
http://preview.tinyurl.com/a7mqqkc
Many thanks and any help would be greatly appriciated.

Don't know if you're still looking for this, but to display a "loading" message, you can use the "setLoading()" method on the chart.
pipeline_by_sales_stage_highchart.setLoading("Loading...")
Check this fiddle: http://jsfiddle.net/QSfEJ/

You can't access variable out of scope, move that into that scope, or make variable global.
http://jsfiddle.net/M2jv7/33/ -inside scope
http://jsfiddle.net/M2jv7/34/ -global variable
var pipeline_by_sales_stage_highchart;
$(document).ready(function () {
pipeline_by_sales_stage_highchart = new Highcharts.Chart({
});
...
// somewhere:
pipeline_by_sales_stage_highchart.series[0].setData(data);

See my answer here: Highchart series update in javascript
Summary :
Initialise chart with empty series, then use addSeries in a loop to update chart, like this:
this.dataFromApi.forEach(function(serie) { // for each row of data, add a series
this.chart.addSeries(serie, false); // false is to prevent redrawing
}.bind(this));
this.chart.redraw(); // manually redraw
this.chart.hideLoading(); // stop loading if showLoading() was call before
jsFiddle here: https://jsfiddle.net/qyh81spb/

Related

Reloading JSON fails to render correctly in canvas with Fabric.js

I have a bit of an issue with Fabric.js. I'm loading a JSON string in to the canvas and then at some time in the future I want to load more JSON in again (possibly the same JSON). The first load seems to work fine but the second load has an issue: the foreground path object doesn't appear, even though its bounding box is clickable. I'm not sure if this is a problem relating to the backgroundImage, or the way I'm clearing the canvas before I load the JSON again, or the actual way I'm loading JSON (or all three).
I've put a simple fiddle here.
var j = { ... }; //json object (see fiddle)
var c = new fabric.Canvas( document.getElementById("c") );
c.loadFromJSON(j, function(objects, options) {
c.renderAll();
setTimeout(function(){
c.backgroundImage=0;
c.clear();
c.renderAll();
setTimeout(function(){
c.loadFromJSON(j, function(objects, options) {
c.renderAll();
c.setActiveObject(c.item(0));
});
},3000);
},3000);
});
I create the initial canvas view from the JSON object, then clear it out after 3 seconds, then load it in again after another 3 seconds (this is just to simulate clicking a button or whatever in a real app).
Would appreciate any help on this and apologies if this has been dealt with before.
Cheers
[EDIT] I've noticed that if I copy the JSON object in to a second variable so that i'm initialising two objects with the same content, and load that in the second loop, it will load again properly. Could the original JSON variable be getting modified or cached and that's causing the issue? (fiddle for this here
i checked the objects that you product and i see that when you load the svg for the second time, all the 'paths' object is missing.
you can see it too, by adding a console.log before the first load and another one just before the 2nd load.
like this:
console.log(JSON.stringify(j));
anyway, to the point,
you just need to stringify your object before you try to load it, in that way you keep all the object as one ,
i added a line that converts you svg object to json string and pass it on a temp variable
tmp = JSON.stringify( j );
take a look ,i update your code,on the fiddle: https://jsfiddle.net/5j7ejLmk/2/
if you find my answer correct please mark it as so.
good luck

d3 timeout like angular $.timeout

The situation is I need to load data for a long time, and I need to show a loading icon when loading, but it seems d3 stop my jquery code. My loading icon only display when the calculateAroundCenter function finished, I think it is because the jquery execute after the d3 scope end.
$("#loadingBox").show()
calculateAroundCenter();
so how to show the icon? Like $.timeout in angularjs, I wish you know this js.
Thanks a lot!
D3 doesn't provide anything for this, but you can easily make your own as follows:
showLoadingIcon();
d3.json(url, function(error, data) {
// do something with the data
removeLoadingIcon();
});
I've used this technique here.

The view area of ckEditor sometimes shows empty at the start

I am using the following directive to create a ckEditor view. There are other lines to the directive to save the data but these are not included as saving always works for me.
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = ck = CKEDITOR.replace(elm[0]);
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
setTimeout(function () {
ck.setData(ngModel.$modelValue);
}, 1000);
}; }
};
}])
The window appears but almost always the first time around it is empty. Then after clicking the [SOURCE] button to show the source and clicking it again the window is populated with data.
I'm very sure that the ck.setData works as I tried a ck.getData and then logged the output to the console. However it seems like ck.setData does not make the data visible at the start.
Is there some way to force the view window contents to appear?
You can call render on the model at any time and it will simply do whatever you've told it to do. In your case, calling ngModel.$render() will grab the $modelValue and pass it to ck.setData(). Angular will automatically call $render whenever it needs to during its digest cycle (i.e. whenever it notices that the model has been updated). However, I have noticed that there are times when Angular doesn't update properly, especially in instances where the $modelValue is set prior to the directive being compiled.
So, you can simply call ngModel.$render() when your modal object is set. The only problem with that is you have to have access to the ngModel object to do that, which you don't have in your controller. My suggestion would be to do the following:
In your controller:
$scope.editRow = function (row, entityType) {
$scope.modal.data = row;
$scope.modal.visible = true;
...
...
// trigger event after $scope.modal is set
$scope.$emit('modalObjectSet', $scope.modal); //passing $scope.modal is optional
}
In your directive:
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
scope.$on('modalObjectSet', function(e, modalData){
// force a call to render
ngModel.$render();
});
Its not a particularly clean solution, but it should allow you to call $render whenever you need to. I hope that helps.
UPDATE: (after your update)
I wasn't aware that your controllers were nested. This can get really icky in Angular, but I'll try to provide a few possible solutions (given that I'm not able to see all your code and project layout). Scope events (as noted here) are specific to the nesting of the scope and only emit events to child scopes. Because of that, I would suggest trying one of the three following solutions (listed in order of my personal preference):
1) Reorganize your code to have a cleaner layout (less nesting of controllers) so that your scopes are direct decendants (rather than sibling controllers).
2) I'm going to assume that 1) wasn't possible. Next I would try to use the $scope.$broadcast() function. The specs for that are listed here as well. The difference between $emit and $broadcast is that $emit only sends event to child $scopes, while $broadcast will send events to both parent and child scopes.
3) Forget using $scope events in angular and just use generic javascript events (using a framework such as jQuery or even just roll your own as in the example here)
There's a fairly simple answer to the question. I checked the DOM and found out the data was getting loaded in fact all of the time. However it was not displaying in the Chrome browser. So the problem is more of a display issue with ckEditor. Strange solution seems to be to do a resize of the ckEditor window which then makes the text visible.
This is a strange issue with ckeditor when your ckeditor is hidden by default. Trying to show the editor has a 30% chance of the editor being uneditable and the editor data is cleared. If you are trying to hide/show your editor, use a css trick like position:absolute;left-9999px; to hide the editor and just return it back by css. This way, the ckeditor is not being removed in the DOM but is just positioned elsewhere.
Use this java script code that is very simple and effective.Note editor1 is my textarea id
<script>
$(function () {
CKEDITOR.timestamp= new Date();
CKEDITOR.replace('editor1');
});
</script>
Second way In controller ,when your query is fetch data from database then use th
is code after .success(function().
$http.get(url).success(function(){
CKEDITOR.replace('editor1');
});
I know, that this thread is dead for a year, but I got the same problem and I found another (still ugly) solution to this problem:
instance.setData(html, function(){
instance.setData(html);
});

HighChart / HighStock chart.refresh seems to fail to reload the chart

Hia guys,
I'm currently learning to use HighCharts in order to graph some data.
After learning to set up on a local page, it was time to load the data dynamically / though ajax.
The chart loads fine, with series defined like:
var series1=[];
var series2=[];
var series3=[];
I then have a button, which fires an ajax request, and these arrays are filled with data, pulled from an sql database, formatted, and sent back to the webpage :D
(this has taken a while)
Now - with these arrays filled, I'm looking to get HighCharts to draw this data.
I've tried to use chart.refresh(); on the end of my ajax but this seems to give the error:
Uncaught TypeError: Object #<Object> has no method 'refresh'
I'm a little stumped and struggling to make progress - a nudge in the right direction would be very much appreciated!
Edit:
chart.series[0].setData(series1);
Is what needs firing after the arrays have been filled up.
Without seeing the rest of your code here is a wild guess:
You have set up your chart with these 3 series already "created" in the HighCharts options. You are loading the page, defining your HighCharts options (including the 3 series - as empty series), then firing the ajax call to populate the three series of data.
You are not actually pushing the new data in each series to the chart, however. You are just setting the vars to new values after they have been sent to HighCharts - refreshing (if even a valid HighCharts call) HighCharts does "nothing" because it is not re-reading the 3 var values.
Also, note that chart.refresh does not appear to be a valid HighCharts call. There is chart.redraw that you can try - but I do not think this will help in your case because of how you are defining your data series elements (again, no idea because the important part - telling HighCharts there is new data in code was not presented). Have a look at the API as well for pointers on dynamically assigning data.
How are you updating the series values? How are you telling the chart there is new data? It would be helpful to see the rest of the code because 3 lines of var x=[] is not really useful.
Here is a basic way to set the data of a series using setData:
$('#button').click(function() {
chart.series[0].setData([129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4] );
});

google.setOnLoadCallback(drawChart);

I have google chart on my page, but right now chart is drawn when Google Visualization library is loaded on the page load, and I have to give data dynamically through ajax, so is it possible to change the callback method, or is there any alternative?
I managed with it as i wanted, It can be helpful for someone, and if there is better solution for this please do suggest.
I removed this setOnLoadCallback function - google.setOnLoadCallback(drawChart);
This call back will call the drawChart() as soon as the visulization library is loaded,
(but I didn't wanted it, i wanted to call it on button click).
so I called drawChart(); function directily in the button click function code.
Then I faced problem with rendering the dynamic data to the datatable, when I was putting hard coded values, the chart drawn fine, but as I put variables instead of those values, it was unable to generate chart.
so i parsed the variable into integer by parseInt(doc_pre),
And it worked fine.
You can check this :
Jquery Charts

Resources