Search code examples
javascriptamcharts

How to make Amcharts animateData working?


I need to create real-time values per minute chart, its last bar value is incremented for a minute after its addition and after a minute the new bar with value 1 is added and first bar (the oldest one) is removed.

I need all these changes to be animated like in the example below.

var chart = AmCharts.makeChart("chartdiv", {
	"type": "serial",
	"theme": "light",
	"dataProvider": generateChartData(),
	"graphs": [{
		"valueField": "value",
		"type": "column",
    "fillAlphas": 1,
		"alphaField": "alpha1"
	}, {
		"valueField": "value2",
    "fillAlphas": 1,
		"type": "column",
		"alphaField": "alpha2"
	}],
	"valueAxes": [{
		"minimum": 0,
		"maximum": 400
	}],
	"chartCursor": {},
	"categoryAxis": {
		"parseDates": true,
		"minPeriod": "mm"
	},
	"zoomOutOnDataUpdate": false,
	"categoryField": "date"
});


function generateChartData() {
	var chartData = [];
	var firstDate = new Date( 2012, 0, 1 );
	firstDate.setDate( firstDate.getDate() - 1000 );
	firstDate.setHours( 0, Math.floor(Math.random() * 10), 0, 0 );

	for ( var i = 0; i < 10; i++ ) {
		var newDate = new Date( firstDate );
		newDate.setHours( 0, i, 0, 0 );

		var a = Math.round( Math.random() * ( 200 + i ) ) + 100 + i;
		var b = Math.round( Math.random() * ( 200 + i ) ) + 100 + i;

    chartData.push( {
      date: newDate,
      value: a,
      value2: b,
      alpha1: (Math.random() < 0.5 ? 0 : 1),
      alpha2: (Math.random() < 0.5 ? 0 : 1)
    } );
	}

	return chartData;
}


function loop() {
	var data = generateChartData();

	chart.animateData(data, {
		duration: 1000,
		complete: function () {
			setTimeout(loop, 2000);
		}
	});
}

chart.addListener("init", function () {
	setTimeout(loop, 1000);
});
html, body {
  width: 100%;
  height: 100%;
  margin: 0px;
}

#chartdiv {
	width: 100%;
	height: 100%;
}
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<script src="https://www.amcharts.com/lib/3/plugins/animate/animate.min.js"></script>

<div id="chartdiv"></div>

I set up the codepen with bar chart and its data update here. I use animateData() method like in the example, but no animation is applied to the chart. What am I doing wrong?


Solution

  • The data needs to be a completely new array for the animation to work, as indicated in the example you linked. You'll need to clone your modified array and pass that into the animateData method. Here's an example using lodash's cloneDeep method

      chart.animateData(_.cloneDeep(data), {
        duration: 1000,
        complete: () => setTimeout(updateChartData, 500),
      });
    

    Updated codepen