Amcharts V4 How to change data without reloading of whole chart?

Majestic picture Majestic · Apr 2, 2019 · Viewed 7.3k times · Source

I'd like to update my chart with new data without reloading the chart like it could be done in amcharts V3 here.

But I can't make it work in V4. I've found some links which deal about how to do it but never on V4. I've created a Pen with data based on examples of the amCharts V3, but it does not work.

JS code :

var globalVars = {unloaded:true};
var chart;
$(window).bind('beforeunload', function(){
    console.log("before unload");
    globalVars.unloaded = true;
});

$(document).ready(function() {
    getStatsByFlowByOperation();
});

function reloadData() {
    var newData = [
        {
            "OPERATION_NAME": "INIT",
            "NEW": 0,
            "READY": 2,
            "RUNNING": 0,
            "DONE": 0
        },
        {
            "OPERATION_NAME": "COPY",
            "NEW": 0,
            "READY": 2,
            "RUNNING": 2,
            "DONE": 2
        },
        {
            "OPERATION_NAME": "MERGE",
            "NEW": 0,
            "READY": 0,
            "RUNNING": 0,
            "DONE": 11
        }
    ];
    return newData;
}

function loadNewData() {
    var chartData = reloadData();
    chart.dataProvider = chartData;
    chart.validateData();
}

function getStatsByFlowByOperation(){

  am4core.useTheme(am4themes_material);
  chart = am4core.create("chartdiv", am4charts.XYChart);
  chart.hiddenState.properties.opacity = 0;

  var newData = [
    {
      "OPERATION_NAME": "INIT",
      "NEW": 2,
      "READY": 0,
      "RUNNING": 0,
      "DONE": 0
    },
    {
      "OPERATION_NAME": "COPY",
      "NEW": 2,
      "READY": 4,
      "RUNNING": 0,
      "DONE": 0
    },
    {
      "OPERATION_NAME": "MERGE",
      "NEW": 0,
      "READY": 0,
      "RUNNING": 5,
      "DONE": 6
    }
  ];

  chart.data = newData;

  chart.colors.step = 2;
  chart.padding(30, 30, 10, 30);
  chart.legend = new am4charts.Legend();

  var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
  categoryAxis.dataFields.category = "OPERATION_NAME";
  categoryAxis.renderer.grid.template.location = 0;

  var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
  valueAxis.renderer.inside = true;
  valueAxis.renderer.labels.template.disabled = true;
  valueAxis.min = 0;

  var listOfStatus = new Array();

  for(var obj in newData){
    if(newData.hasOwnProperty(obj)){
      for(var prop in newData[obj]){
        if(newData[obj].hasOwnProperty(prop)){
          if(prop == "NEW"
             || prop == "DISABLED"
             || prop == "SKIPPED"
             || prop == "READY"
             || prop == "DISPATCHED"
             || prop == "RUNNING"
             || prop == "ERROR_RESUMED"
             || prop == "ERROR"
             || prop == "FINISHED"
             || prop == "TIMEOUT"
             || prop == "RESUBMITTED"
             || prop == "CANCELLED"
             || prop == "DONE") {
            listOfStatus.push(prop);
          }
        }
      }
    }
  }

  var uniqueStatus = [];
  $.each(listOfStatus, function(i, el){
    if($.inArray(el, uniqueStatus) === -1) uniqueStatus.push(el);
  });

  var allStatus = [];
  allStatus.push("NEW");
  allStatus.push("DISABLED");
  allStatus.push("SKIPPED");
  allStatus.push("READY");
  allStatus.push("DISPATCHED");
  allStatus.push("RUNNING");
  allStatus.push("ERROR_RESUMED");
  allStatus.push("ERROR");
  allStatus.push("FINISHED");
  allStatus.push("TIMEOUT");
  allStatus.push("RESUBMITTED");
  allStatus.push("CANCELLED");
  allStatus.push("DONE");

  for(var i = 0; i < allStatus.length; i++) {
    if(uniqueStatus.includes(allStatus[i])) {
      createSeries(allStatus[i], allStatus[i]);
    }
  }
}

// Create series
function createSeries(field, name) {

  // Set up series
  var series = chart.series.push(new am4charts.ColumnSeries());
  series.name = name;
  series.dataFields.valueY = field;
  series.dataFields.categoryX = "OPERATION_NAME";
  series.sequencedInterpolation = true;

  // Make it stacked
  series.stacked = true;

  // Configure columns
  series.columns.template.width = am4core.percent(60);
  series.columns.template.tooltipText = "[bold]{name}[/]\n[font-size:14px]{categoryX}: {valueY}";

  // Add label
  var labelBullet = series.bullets.push(new am4charts.LabelBullet());
  labelBullet.label.text = "{valueY}";
  labelBullet.locationY = 0.5;

  return series;
}

HTML code :

<div id="chartdiv"></div>
<input type="button" value="Load new data" onclick="loadNewData();">

<!-- for graphes -->
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/material.js"></script>

Do you guys have some ideas ? Many thanks !

Answer

notacouch picture notacouch · Apr 3, 2019

To update the chart with a whole new data set, just re-assign the chart's data, e.g.

function loadNewData() {
    chart.data = reloadData();
}

Here's a fork of your pen:

https://codepen.io/team/amcharts/pen/a9050805dfa3cbfcf1da185348a11dcd