You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AmCharts 4的多个饼图中实现自定义图例?

Fixing Custom Legend Display for Multiple AmCharts Pie Charts

Alright, let's sort out why your custom legends aren't showing up when rendering multiple pie charts. The core issue is that your current code relies on non-unique selectors and global references, which clash when multiple charts attempt to populate their legends simultaneously. Here's a step-by-step solution:

1. First, Adjust Your HTML Structure

Make sure each pie chart has its own dedicated legend element with a unique ID (tied to the chart's ID):

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

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

2. Updated JavaScript Code

We'll refactor the code to bind each chart to its own legend, use unique identifiers, and avoid global conflicts:

am4core.ready(function() {
  // Reusable function to create a pie chart with custom legend
  function buildPieChart(chartId, chartData) {
    // Initialize chart instance
    chartReg[chartId] = am4core.create(chartId, am4charts.PieChart);
    
    // Assign chart-specific data
    chartReg[chartId].data = chartData;
    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;
    
    // Get the matching legend element for this chart
    const legendEl = document.getElementById(`legend-${chartId}`);
    if (!legendEl) {
      console.warn(`No legend element found for chart: ${chartId}`);
      return;
    }
    
    // Clear existing legend content before populating
    legendEl.innerHTML = "";
    
    // Populate custom legend when chart is ready
    chartReg[chartId].events.on("ready", () => {
      chartReg[chartId].customLegend = legendEl;
      
      pieSeries.dataItems.each((row, index) => {
        const color = pieSeries.colors.getIndex(index);
        const percent = Math.round(row.values.value.percent * 100) / 100;
        const value = row.value;
        const title = row.category;
        
        // Create unique legend item
        const legendItem = document.createElement("div");
        legendItem.className = "legend-item";
        legendItem.id = `legend-item-${chartId}-${index}`;
        legendItem.onclick = () => toggleSlice(chartId, index);
        legendItem.onmouseover = () => hoverSlice(chartId, index);
        legendItem.onmouseout = () => blurSlice(chartId, index);
        
        // Populate legend item content
        legendItem.innerHTML = `
          <div class="legend-marker" style="background: ${color}"></div>
          <div class="legend-title">${title}</div>
          <div class="legend-value">${value} | ${percent}%</div>
        `;
        
        // Add item to the chart's legend
        legendEl.appendChild(legendItem);
      });
    });
  }

  // Example: Initialize two separate charts with unique data
  buildPieChart("chart-sales", [
    { key: "Direct", value: 30 },
    { key: "Referral", value: 20 },
    { key: "Social", value: 50 }
  ]);
  
  buildPieChart("chart-users", [
    { key: "New", value: 45 },
    { key: "Returning", value: 55 }
  ]);
});

// Updated interaction functions to target specific charts
function toggleSlice(chartId, sliceIndex) {
  const chart = chartReg[chartId];
  if (!chart) return;
  const dataItem = chart.series.getIndex(0).dataItems.getIndex(sliceIndex);
  dataItem.toggle();
}

function hoverSlice(chartId, sliceIndex) {
  const chart = chartReg[chartId];
  if (!chart) return;
  const dataItem = chart.series.getIndex(0).dataItems.getIndex(sliceIndex);
  dataItem.isHover = true;
}

function blurSlice(chartId, sliceIndex) {
  const chart = chartReg[chartId];
  if (!chart) return;
  const dataItem = chart.series.getIndex(0).dataItems.getIndex(sliceIndex);
  dataItem.isHover = false;
}

Key Fixes Explained

  • Unique Legend Binding: Each chart targets its own legend element using a chart-specific ID (e.g., legend-chart-sales for chart-sales), eliminating selector conflicts.
  • Clear Legend Content: We empty the legend before populating it to prevent content stacking from multiple chart renders.
  • Unique Interaction Handlers: Legend items and interaction functions now include the chart ID, ensuring clicks/hovers target the correct chart's slices.
  • Reusable Chart Function: The buildPieChart function makes it easy to create multiple charts without repeating code, and ensures each chart has isolated data and legend references.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:00:30