You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AmCharts 4多饼图自定义图例不显示问题及解决方法

Fixing Custom Legend Issues for Multiple AmCharts Pie Charts

Got it, let's break down exactly why your custom legend stops working when you render multiple pie charts, and walk through a solid fix step by step:

What's Causing the Problem?

Your current code has three key issues that trip up multiple chart instances:

  • Duplicate/Unscoped Legend Selector: Using $('#legend') targets a single global element, so when the second chart initializes, it overwrites or ignores the first chart's legend (plus, IDs should always be unique in the DOM!).
  • Uncontrolled InnerHTML Updates: Directly appending to legend.innerHTML without clearing the container first leads to messy, overlapping content when multiple charts load.
  • Instance-Agnostic Interaction Functions: toggleSlice, hoverSlice, and blurSlice don't know which chart to target—they'll always affect the last initialized chart, or a random one, when multiple exist.

Step-by-Step Fix

1. Create Unique Legend Containers for Every Chart

First, make sure each chart has its own dedicated legend element. If your chart containers use IDs like chart-1, chart-2, pair them with matching legends like legend-1, legend-2:

<!-- Chart 1 -->
<div id="chart-1" class="pie-chart"></div>
<div id="legend-1" class="custom-legend"></div>

<!-- Chart 2 -->
<div id="chart-2" class="pie-chart"></div>
<div id="legend-2" class="custom-legend"></div>

2. Update Chart Initialization to Target Unique Legends

Modify your code to pass (or derive) the legend ID alongside the chart ID, so each chart knows exactly which legend to populate. I'll use a config array example here (adjust to match how you're feeding data to your charts):

am4core.ready(function() { 
  // Example: Array of chart configs, each with unique chart ID, legend ID, and data
  const chartConfigs = [
    { chartId: "chart-1", legendId: "legend-1", data: yourFirstDataset },
    { chartId: "chart-2", legendId: "legend-2", data: yourSecondDataset }
  ];

  chartConfigs.forEach(config => {
    const { chartId, legendId, data } = config;
    
    // Initialize chart instance
    chartReg[chartId] = am4core.create(chartId, am4charts.PieChart); 
    chartReg[chartId].data = data; 
    chartReg[chartId].innerRadius = 60; 

    // Configure pie series
    const pieSeries = chartReg[chartId].series.push(new am4charts.PieSeries()); 
    pieSeries.dataFields.value = "value"; 
    pieSeries.dataFields.category = "key"; 
    pieSeries.ticks.template.disabled = true; 
    pieSeries.alignLabels = false; 

    // Populate custom legend for THIS chart
    chartReg[chartId].events.on("ready", function(event) { 
      const currentChart = event.target;
      const legendContainer = document.getElementById(legendId);
      
      // Clear the legend first to avoid duplicate entries
      legendContainer.innerHTML = '';

      pieSeries.dataItems.each((row, i) => { 
        const color = pieSeries.colors.getIndex(i); 
        const percent = Math.round(row.values.value.percent * 100) / 100; 
        const value = row.value; 
        const title = row.category;

        // Build the legend item, and bind interactions to THIS chart's ID
        const legendItem = document.createElement('div');
        legendItem.className = 'legend-item';
        legendItem.id = `legend-item-${chartId}-${i}`;
        legendItem.onclick = () => toggleSlice(chartId, i);
        legendItem.onmouseover = () => hoverSlice(chartId, i);
        legendItem.onmouseout = () => blurSlice(chartId, i);

        legendItem.innerHTML = `
          <div class="legend-marker" style="background: ${color}"></div>
          <div class="legend-title">${title}</div>
          <div class="legend-value">${value} | ${percent}%</div>
        `;

        legendContainer.appendChild(legendItem);
      }); 
    }); 
  });
});

3. Update Interaction Functions to Target Specific Charts

Modify your toggle/hover/blur functions to accept the chart ID as a parameter, so they always operate on the correct chart instance:

function toggleSlice(chartId, sliceIndex) {
  const targetChart = chartReg[chartId];
  const targetSlice = targetChart.series.getIndex(0).dataItems.getIndex(sliceIndex);
  
  targetSlice.hidden ? targetSlice.show() : targetSlice.hide();
}

function hoverSlice(chartId, sliceIndex) {
  const targetChart = chartReg[chartId];
  const targetSlice = targetChart.series.getIndex(0).dataItems.getIndex(sliceIndex);
  
  targetSlice.isHover = true;
}

function blurSlice(chartId, sliceIndex) {
  const targetChart = chartReg[chartId];
  const targetSlice = targetChart.series.getIndex(0).dataItems.getIndex(sliceIndex);
  
  targetSlice.isHover = false;
}

4. Optional: Clean Up Old Chart Instances

If you're dynamically adding/removing charts, add a cleanup function to avoid memory leaks:

function disposeChart(chartId) {
  if (chartReg[chartId]) {
    chartReg[chartId].dispose();
    delete chartReg[chartId];
    
    // Clear the corresponding legend
    const legendId = `legend-${chartId.replace('chart-', '')}`;
    document.getElementById(legendId).innerHTML = '';
  }
}

Quick Recap

  • Unique IDs: Never reuse IDs for charts or legends—each needs its own identifier.
  • Scope Everything: Tie all DOM updates and interactions to the specific chart instance.
  • Pass Context: Use the chart ID in interaction functions to ensure you're targeting the right chart.

内容的提问来源于stack exchange,提问作者hamed dehghan

火山引擎 最新活动