I have a setup where I am using amcharts that is feed data via appendData from an AJAX call. The call goes to a URL which simply renders the Time.now as the X and 8 lines using the function 2cos(x/2)+2ln (ln is the line number). AJAX request is made every 1 second.
The backend is always correct and always returns a single point, unless it is a duplicate X in which it throws an error. The error causes not to complete and therefore not call appendData.
Anybody have any idea what is going wrong with amcharts? It seems to be an issue only with appendData (which I need to simulate a sliding window).
The Javascript code is below. It assumes that the page creates a line chart with 8 points graphs and passes it to setup_chart_loader. Netcordia.rapid_poller.updateChart is used to update the chart using the Ajax request
Ext.ns("Netcordia.rapid_poller");
Netcordia.rapid_poller.refresh_rate = 1; //seconds
Netcordia.rapid_poller.pause = false; //causes the AJAX to suspend
Netcordia.rapid_poller.chart = null;
Netcordia.rapid_poller.stop = false;
/* This function does everything that is required to get the chart data correct */
Netcordia.rapid_poller.setup_chart_loader = function(chart){
assert(Netcordia.rapid_poller.displaySizeInMinutes,"No display size");
assert(Netcordia.rapid_poller.delta_url, "Data URL is empty");
assert(Netcordia.rapid_poller.delta_params, "No Data params");
if(typeof(chart) !== 'object'){
chart = document.getElementById(chart);
}
Netcordia.rapid_poller.chart = chart;
// 5 seconds raw polling
var maxPoints = Netcordia.rapid_poller.displaySizeInMinutes * 60 / 5;
var count = 0;
var lastUpdate = '';
debug("max number of points: "+maxPoints);
debug('creating updateChart function');
Netcordia.rapid_poller.updateChart = function(){
debug("Sending Data request");
var params = {last: lastUpdate, max: 1}; //maxPoints};
//I have to do this otherwise amcharts get a lot of data and only renders
// one item, then the counts is off
if(lastUpdate === ''){params['max'] = maxPoints;}
if (Netcordia.rapid_poller.pause){
alert("pausing");
params['historical'] = 1;
params['max'] = maxPoints;
}
Ext.apply(params, Netcordia.rapid_poller.delta_params);
//this might need to be moved to within the Ajax request
// incase things start piling up
if(!Netcordia.rapid_poller.stop){
setTimeout(Netcordia.rapid_poller.updateChart,1000*Netcordia.rapid_poller.refresh_rate);
} else {
debug("skipping next poll");
return;
}
Ext.Ajax.request({
url: Netcordia.rapid_poller.delta_url,
baseParams: Netcordia.rapid_poller.delta_params,
params: params,
success: function(response){
//if(Netcordia.rapid_poller.pause){
// debug("Data stopped");
// return;
//}
var json = Ext.util.JSON.decode(response.responseText);
lastUpdate = json.lastUpdate;
if( json.count === 0 ){
debug("no data to append");
return;
}
debug("appending "+json.count);
var remove = (count + json.count) - maxPoints;
if(remove <= 0){ remove = 0; }
count += json.count;
if(count > maxPoints){ count = maxPoints; }
debug("removing "+remove);
debug("count: "+count);
if(Netcordia.rapid_poller.pause){
alert("Pausing for historical");
//append a zero point and delete the existing data
// amcharts can leak extra points onto the screen so deleting
// twice the number is
chart.appendData("00:00:00;0;0;0;0;0;0;0;0",(count*2).toString());
count = json.count;
remove = 1;
Netcordia.rapid_poller.stop = true;
}
chart.appendData(json.lines.toString(),remove.toString());
}
});
};
};
The rails code that returns the data is as follows:
def get_delta
max = 1
begin
current = Time.parse(params[:last])
rescue
current = Time.now
end
if params[:historical]
max = params[:max].to_i || 10
current = Time.at(current.to_i - (max/2))
end
logger.info(current.to_i)
logger.info(max)
n = current.to_i
m = n+max-1
data = (n..m).collect do |x|
logger.info "For Point: #{x}"
point = Math.cos(x/2)
data = [Time.at(x).strftime("%H:%M:%S")]
for i in (1..8)
data.push(2*point+(2*i));
end
data.join(";")
end
render :json => {count: data.size, lastUpdate: Time.now.strftime('%Y-%m-%d %H:%M:%S'), lines: data.join("\n")}
end

Seems to be a bug in Amcharts itself.
Forum Post has the developer’s answer.