Amcharts5二次调用绘图函数绘制环形图报错且图表不显示问题咨询
问题原因
- 报错
You cannot have multiple Roots on the same DOM node是因为每次调用donutam函数时,都在同一个id为animating-donut的DOM节点上重复创建am5.Root实例,amCharts5不允许同一节点绑定多个Root实例。 - 第二个类型错误是Root实例冲突后,内部属性丢失导致的连锁报错。
- 额外隐患:代码中的
root变量未使用let/const/var声明,成为全局变量,会加剧上下文冲突。
解决方案
方案1:每次调用前销毁旧实例(适合模态框关闭后会销毁DOM的场景)
在函数外部声明变量存储Root实例,每次调用函数前先判断是否存在旧实例,存在就先调用dispose()方法销毁,再创建新实例。
改造后代码:
// 函数外部声明变量存储root实例 let donutRoot = null; function donutam(donutdatalabel,donutdataseries){ // 先销毁已存在的root实例 if (donutRoot) { donutRoot.dispose(); donutRoot = null; } // 创建新的root实例 donutRoot = am5.Root.new("animating-donut"); // 设置主题 donutRoot.setThemes([am5themes_Animated.new(donutRoot)]); // 创建图表 var chart = donutRoot.container.children.push(am5percent.PieChart.new(donutRoot, { layout: donutRoot.verticalLayout })); // 创建系列 var series = chart.series.push(am5percent.PieSeries.new(donutRoot, { valueField: "value", categoryField: "category" })); // 组装数据 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); // 创建图例 var legend = chart.children.push(am5.Legend.new(donutRoot, { centerX: am5.percent(50), x: am5.percent(50), marginTop: 15, marginBottom: 15, })); legend.data.setAll(series.dataItems); // 播放入场动画 series.appear(1000, 100); }
方案2:复用Root实例仅更新数据(性能更优,适合模态框仅隐藏不销毁DOM的场景)
仅首次调用时创建Root、图表、系列实例,后续调用只更新数据,不需要重复创建组件:
// 外部存储实例 let donutRoot = null; let donutSeries = null; function donutam(donutdatalabel,donutdataseries){ // 首次调用初始化所有组件 if (!donutRoot) { donutRoot = am5.Root.new("animating-donut"); donutRoot.setThemes([am5themes_Animated.new(donutRoot)]); var chart = donutRoot.container.children.push(am5percent.PieChart.new(donutRoot, { layout: donutRoot.verticalLayout })); donutSeries = chart.series.push(am5percent.PieSeries.new(donutRoot, { valueField: "value", categoryField: "category" })); var legend = chart.children.push(am5.Legend.new(donutRoot, { centerX: am5.percent(50), x: am5.percent(50), marginTop: 15, marginBottom: 15, })); legend.data.setAll(donutSeries.dataItems); } // 每次调用仅更新数据 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]}; } donutSeries.data.setAll(seriesarr); donutSeries.appear(1000, 100); }
内容的提问来源于stack exchange,提问作者Isaac Nehmad
相关产品推荐
相关产品推荐

