I want to use a chartjs linechart to visualize my data points. Chartjs seems to animate the graph by default, but it does not animate the values on the x-axis. The x-axis only move in discrete steps.
Is there any way to enable animation on the axis also?
Thanks!
3 Answers
Answers 1
As far as I am aware, ChartJS does not support x-axis animation out-of-the-box. So you'll have to hack it. There are several ways to possibly do this, but the following method seems to work.
When a chart is updated, the following steps occur: 1) The axes are drawn, and then 2) a draw()
function is called to draw the data. There are different draw()
functions for different chart types, and the function for line charts is Chart.controllers.line.prototype.draw
. The draw()
functions take one argument, which I will call animationFraction
, that indicates how complete the animation is as a fraction. For instance, if an animation is 5% complete, animationFraction
will be 0.05, and if an animation is 100% complete (i.e. if the chart is in its final form), animationFraction=1
. The draw()
function is called at each step of the animation to update the data display.
One hack to animate the x-axis then is to monkey-patch the line chart draw()
function to translate the canvas in the horizontal dimension at every draw step:
var hShift = (1-animationFraction)*ctx.canvas.width;
hShift
is the horizontal shift in pixels of the chart. As defined above, the data will sweep in from the right; if you want it to sweep in from the left, you can make the above negative. You then save the canvas context state, transform the canvas using hShift
, draw the chart data, and then restore the canvas to its original state so that on the next animation frame the axes will be drawn in the correct spot:
ctx.save(); ctx.setTransform(1, 0, 0, 1, hShift, 0); ctx.oldDraw.call(this, animationFraction); ctx.restore();
In the above, this
refers to the chart object, and oldDraw
refers to the original line chart drawing function that was saved previously:
var oldDraw = Chart.controllers.line.prototype.draw;
You can additionally setup your new draw()
function to read new animation options that allow you to set whether the x-axis and y-axis are animated:
var oldDraw = Chart.controllers.line.prototype.draw; Chart.controllers.line.prototype.draw = function(animationFraction) { var animationConfig = this.chart.options.animation; if (animationConfig.xAxis === true) { var ctx = this.chart.chart.ctx; var hShift = (1-animationFraction)*ctx.canvas.width; ctx.save(); ctx.setTransform(1, 0, 0, 1, hShift,0); if (animationConfig.yAxis === true) { oldDraw.call(this, animationFraction); } else { oldDraw.call(this, 1); } ctx.restore(); } else if (animationConfig.yAxis === true) { oldDraw.call(this, animationFraction); } else { oldDraw.call(this, 1); } }
You can then create a line chart with both axes animated with:
var lineChart = new Chart(ctx, { type: 'line', data: data, options: { animation: { duration: 5000, xAxis: true, yAxis: true, } } });
See https://jsfiddle.net/16L8sk2p/ for a demo.
Answers 2
I am no expert in javascript but I found an example for Chartjs that, when inserted a new data point, updates the x-axis via animation as it seems, maybe it helps you: example.
Example source: sitepoint.com
Answers 3
You can loop through the points / bars onAnimationComplete and display the values
Preview
HTML
<canvas id="myChart1" height="300" width="500"></canvas> <canvas id="myChart2" height="300" width="500"></canvas>
Script
var chartData = { labels: ["January", "February", "March", "April", "May", "June"], datasets: [ { fillColor: "#79D1CF", strokeColor: "#79D1CF", data: [60, 80, 81, 56, 55, 40] } ] }; var ctx = document.getElementById("myChart1").getContext("2d"); var myLine = new Chart(ctx).Line(chartData, { showTooltips: false, onAnimationComplete: function () { var ctx = this.chart.ctx; ctx.font = this.scale.font; ctx.fillStyle = this.scale.textColor ctx.textAlign = "center"; ctx.textBaseline = "bottom"; this.datasets.forEach(function (dataset) { dataset.points.forEach(function (points) { ctx.fillText(points.value, points.x, points.y - 10); }); }) } }); var ctx = document.getElementById("myChart2").getContext("2d"); var myBar = new Chart(ctx).Bar(chartData, { showTooltips: false, onAnimationComplete: function () { var ctx = this.chart.ctx; ctx.font = this.scale.font; ctx.fillStyle = this.scale.textColor ctx.textAlign = "center"; ctx.textBaseline = "bottom"; this.datasets.forEach(function (dataset) { dataset.bars.forEach(function (bar) { ctx.fillText(bar.value, bar.x, bar.y - 5); }); }) } });
Fiddle - http://jsfiddle.net/uh9vw0ao/
0 comments:
Post a Comment