如何在amCharts 4地图的多饼图间实现共享可点击图例?
解决amCharts多饼图共享图例点击控制问题
核心思路
要实现共享图例控制所有饼图的切片显示,关键在于获取所有饼图实例的引用,并在图例点击事件中遍历这些实例,针对对应类别的切片进行显示/隐藏操作。
步骤1:存储所有饼图实例的引用
在创建地图上的饼图bullet时,把每个饼图实例存入一个全局数组,这样后续可以方便地遍历所有饼图:
// 全局数组存储所有饼图实例 let allPieCharts = []; // 假设你是这样创建饼图bullet的(根据你的实际代码调整) let pieBullet = mapSeries.bullets.push(new am4charts.PieBullet()); pieBullet.series.name = "PieBullet"; pieBullet.series.dataFields.value = "value"; pieBullet.series.dataFields.category = "category"; // 将饼图实例加入全局数组 allPieCharts.push(pieBullet.series);
步骤2:完善图例点击事件逻辑
现在可以在图例的hit事件中,遍历allPieCharts数组,对每个饼图的切片进行控制。同时同步图例项的激活状态:
// 修改你的图例点击事件 legend.itemContainers.template.events.on("hit", function(ev) { let targetItem = ev.target; let categoryIndex = targetItem.dataItem.index; // 切换当前图例项的激活状态 targetItem.isActive = !targetItem.isActive; // 检查是否有激活的图例项 let activeItems = legend.dataItems.filter(item => item.isActive); // 遍历所有饼图 allPieCharts.forEach(pieChart => { // 遍历饼图的所有切片 pieChart.slices.each(slice => { if (activeItems.length === 0) { // 没有激活项时,显示所有切片 slice.show(); } else { // 只显示与激活图例项对应的切片 let shouldShow = activeItems.some(item => item.index === slice.dataItem.index); shouldShow ? slice.show() : slice.hide(); } }); }); });
步骤3:初始化图例激活状态
确保图例初始状态下所有项都是激活的,这样默认显示所有切片:
// 在设置legend.data之后添加 legend.dataItems.each(item => { item.isActive = true; });
补充说明
- 如果你的需求是多选图例项(即点击多个图例项,显示对应多个类别的切片),上面的代码已经支持,因为它会检查所有激活的项并显示对应切片。
- 如果需要单选(每次只能激活一个图例项),可以在点击事件开头先把所有图例项设为非激活,再设置当前项为激活:
legend.itemContainers.template.events.on("hit", function(ev) { let targetItem = ev.target; let categoryIndex = targetItem.dataItem.index; // 单选逻辑:先取消所有图例项的激活状态 legend.dataItems.each(item => { item.isActive = false; }); // 激活当前点击的项 targetItem.isActive = true; // 遍历所有饼图控制切片 allPieCharts.forEach(pieChart => { pieChart.slices.each(slice => { slice.dataItem.index === categoryIndex ? slice.show() : slice.hide(); }); }); });
这样就能实现你要的点击共享图例,控制所有饼图仅显示对应激活类别的切片啦!
内容的提问来源于stack exchange,提问作者giraffe111
相关产品推荐
相关产品推荐

