Hi @etimberg & @simonbrunel ,
related to live charts immediately had a new gulp build and some test after #3399 and found out a little problem: datasets.datas nicely render sliding right to left, but not graph ticks generated over a callback (data was already rendering nicely without latest PR too, just adding a linear easing on animation), getting rendered delayed to relative data value (no smooth sliding too).
on data update from Django we get cpu stats & timistamp, labels array populated only with :15, :30: :45 min:00
callback: function(value) {
return value.toString().length > 0 ? value : null;
Any suggestion?
Mirko
Hi @MFlyer,
If your question is _"how to animate labels horizontally"_, I don't think that Chart.js currently supports animation of scale elements. It would be a very great feature, but I suppose, not quite easy to implement :\
Hi @simonbrunel you're right, that was the one line question eheh :smile:
Here is a plunker example with newly built Chart.js showing scale ticks rendering before animation ending: http://plnkr.co/edit/M92CwRGoJw5YJM6M9VpA?p=preview
Please check same example both on Chrome-Chromium and Firefox (no smoothing over Firefox)
Mirko
I don't have any good suggestion for the labels issue, @etimberg can confirm what is currently feasible. For smooth data animations, you need a duration a bit longer than the refresh rate (e.g. 1250ms for the chart animation.duration and 1000ms for setInterval()).
Thanks for suggestion about animation.duration
One question: why not having callback return null (so we have no ticks) and instead draw ticks inside animation onProgress?
At the moment scales are not affected by the easing (which is a number on the range [0, 1]) indicating how far along the animation is and so always draw on the first frame of the animation in their final position. I suppose it is possible to make it work, but it could get complicated.
Hi @etimberg ,
this seems to be an interesting issue, maybe I'll give it a shot :)
M.
@MFlyer sounds good
Hi @etimberg and @simonbrunel , reading code from core.scale.js finally found why ticks & labels have wrong positions on a dynamic data chart:
On draw function every tick and label defines its x/y positions by getPixelForTick func, but x/y pos don't have any relationship with points[index_of_tick/label] x/y (data points array, don't know real var name), so it's all fine over a static chart (every chart point has a well defined pos equal to ticks/labels position) not on dynamic chart - points moving right to left from tick_xpos(n) to tick_pos(n-1) over z number frames each rendering a different position between n and n-1, while ticks/labels having only 2 states/pos/array indexes
Where to check for chart points array data / functions? Just to avoid reading again all chart.js modules :laughing: thx
Mods required over var pixel
getPixelForTick: function(index, includeOffset) {
var me = this;
if (me.isHorizontal()) {
var innerWidth = me.width - (me.paddingLeft + me.paddingRight); // <- OK
var tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1); // <- OK
var pixel = (tickWidth * index) + me.paddingLeft; // <- Every tick position grounds on tick index and tickWidth, not current related chart point
if (includeOffset) {
pixel += tickWidth / 2;
}
var finalVal = me.left + Math.round(pixel);
finalVal += me.isFullWidth() ? me.margins.left : 0;
return finalVal;
}
var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
return me.top + (index * (innerHeight / (me.ticks.length - 1)));
},
Hi @etimberg & @simonbrunel got it, enjoy this demo :wink:
http://plnkr.co/edit/KToiNLlBrQzBsO1cPDNU?p=preview
Going to PR asap
Mirko
@MFlyer that looks really nice. I'm excited to look at the PR
Hi @etimberg just one suggestion because had it working on the fly without reading all chart.js code:
How to correctly get _view / chart metadata from core.scale draw function?
Currently having
var meta = me.data.datasets[0]._meta[0]; //grab metadata
....
var xLineValue = meta.data[index]._view.x; //replaced getPixelForTick
labelX = meta.data[index]._view.x + optionTicks.labelOffset; //replaced getPixelForTick
Last 2 rows use _viex.x instead of getPixelForTick(), so we have real position during animations too, but probably there's a better way to query chart metadata and _view.
Pls note: Plunker example working with this code, while same built and used on a backbone context not working :/
Edit: from inside draw using me.chart.getDatasetMeta(0) and working, had to test only on backbone under Rockstor project
Yup, getDatasetMeta is the correct method to use.
One thing I should note is that you can't guarantee that meta.data[index]._view.x; is a grid line. In a scatter chart, it definitely will not be.
What might be better would be to have the axes create an _model property like the elements and then transition it to _view and then draw from the views. That way the positions would only be determined once on update and then each frame of the animation would simply transition a little further towards the final value.
Update:
Over Rockstor backbone widgets solved (missing initial dataset data) plus if statement over Chart.js, checking for meta.data[index] (if ok use it, otherwise use old getPixelForTick - example horizontalbar chart)
Closing this as chartjs-plugin-streaming provides a solution for the real-time use cases like this.