4

I am calling this function to draw the pie to a div with the id "animating-donut" which is inside a modal window.

The first time it works but when clicking the second time I got these errors and the chart is not displayed

  1. Uncaught Error: You cannot have multiple Roots on the same DOM node
  2. Uncaught TypeError: Cannot read properties of undefined (reading '_display')

Anyway, I don't think those errors cause the chart not to be displayed the second time as the first time it was displayed even with these errors -

Thank You

Here is my function

function donutam(donutdatalabel,donutdataseries){
//Pie View;
root = am5.Root.new("animating-donut");

// Set themes
root.setThemes([
  am5themes_Animated.new(root)
]);


// Create chart
var chart = root.container.children.push(am5percent.PieChart.new(root, {
  layout: root.verticalLayout
}));


// Create series
var series = chart.series.push(am5percent.PieSeries.new(root, {
  valueField: "value",
  categoryField: "category"
}));


// Set data
var serie = donutdataseries.split(',');
var labels = donutdatalabel.split(',');
var seriesarr = [];
for (i = 0; i < serie.length; i++) {
    seriesarr[i] = {value: serie[i], category: labels[i]};
}
    
series.data.setAll(seriesarr);


// Create legend
var legend = chart.children.push(am5.Legend.new(root, {
  centerX: am5.percent(50),
  x: am5.percent(50),
  marginTop: 15,
  marginBottom: 15,
}));

legend.data.setAll(series.dataItems);


// Play initial series animation
series.appear(1000, 100);

}

Isaac Nehmad
  • 41
  • 1
  • 5

3 Answers3

6

You are trying to create a new root element in a container before disposing the old one that is currently residing there, will result in an error. If we do not have reference to a previously created root element, we can find it among am5.registry.rootElements, which is an array that holds all root elements.

function maybeDisposeRoot(divId) {
  am5.array.each(am5.registry.rootElements, function (root) {
    if (root.dom.id == divId) {
      root.dispose();
    }
  });
};

function donutam(donutdatalabel,donutdataseries){
//Pie View;
maybeDisposeRoot("animating-donut");
root = am5.Root.new("animating-donut");

// Set themes
root.setThemes([
  am5themes_Animated.new(root)
]);


// Create chart
var chart = root.container.children.push(am5percent.PieChart.new(root, {
  layout: root.verticalLayout
}));


// Create series
var series = chart.series.push(am5percent.PieSeries.new(root, {
  valueField: "value",
  categoryField: "category"
}));


// Set data
var serie = donutdataseries.split(',');
var labels = donutdatalabel.split(',');
var seriesarr = [];
for (i = 0; i < serie.length; i++) {
    seriesarr[i] = {value: serie[i], category: labels[i]};
}
    
series.data.setAll(seriesarr);


// Create legend
var legend = chart.children.push(am5.Legend.new(root, {
  centerX: am5.percent(50),
  x: am5.percent(50),
  marginTop: 15,
  marginBottom: 15,
}));

legend.data.setAll(series.dataItems);


// Play initial series animation
rogue0n3
  • 3
  • 2
1

You can dispose the root if not null:

if (root !== null) root.dispose();
Ruli
  • 2,592
  • 12
  • 30
  • 40
1

Before creating new root, you should dispose previously created root element and its children as shown in below code according to the official document.

am5.array.each(am5.registry.rootElements, function(root) {
  if (root.dom.id == divId) {
    root.dispose();
  }
});
burak isik
  • 395
  • 5
  • 6