Managing ECharts Resize Events in Loops with Closures

When dynamically generating multiple ECharts instances within a loop, ensuring they adapt smoothly to viewport changes requires careful event handling. A common issue arises where charts do not resize proportionally, which can be exacerbated by incorrect percentage calculations (e.g., distributing width evenly among five elements requires 20% rather than 25%). However, the core JavaScript challenge involves correctly capturing the loop index during the resize event using closures.

Chart Initialization

initializeChart(identifier) {
  const container = document.getElementById(`chart-wrapper-${identifier}`);
  const chartInstance = echarts.init(container);
  const configuration = {
    legend: {
      orient: 'vertical',
      left: 'left',
      bottom: 0,
      selectedMode: false,
      formatter: function (label) {
        if (label === 'Done') {
          return `${label} 15%`;
        } else if (label === 'Pending') {
          return `${label} 25%`;
        }
      },
      data: [{ name: 'Done' }, { name: 'Pending' }]
    },
    series: [{
      name: 'Metrics',
      type: 'pie',
      radius: '70%',
      data: [
        { value: 15, name: 'Overdue', itemStyle: { color: '#d9534f' } },
        { value: 25, name: 'Pending', itemStyle: { color: '#5bc0de' } },
        { value: 40, name: 'Done', itemStyle: { color: '#5cb85c' } }
      ],
      label: {
        position: 'inner',
        fontSize: 10,
        formatter: '{b}: {c}\n{d}%'
      }
    }]
  };
  chartInstance.setOption(configuration);
  return chartInstance;
}

Problematic Approach: Overwriting onresize

Assigning a function to window.onresize directly replaces any previously assigned resize handlers. Furthermore, without a closure or slight delay, synchronous resizing of multiple heavy chart instances can lead to performance bottlenecks and uneven scaling.

this.$nextTick(async () => {
  const instances = [];
  for (let idx = 1; idx <= 5; idx++) {
    const chart = await this.initializeChart(idx);
    instances.push(chart);
  }
  window.onresize = function() {
    for (let j = 0; j < instances.length; j++) {
      instances[j].resize();
    }
  };
});

Robust Approach: addEventListener with Closures

Using window.addEventListener ensures multiple listeners can coexist. By introducing an IIFE (Immediately Invoked Function Expression) closure combined with setTimeout, each chart instance processes its resize operation asynchronously, preventing layout thrashing and ensuring the correct index is targeted.

this.$nextTick(async () => {
  const chartList = [];
  for (let idx = 1; idx <= 5; idx++) {
    const chart = await this.initializeChart(idx);
    chartList.push(chart);
  }
  window.addEventListener('resize', () => {
    for (let k = 0; k < chartList.length; k++) {
      ((currentIdx) => {
        setTimeout(() => {
          chartList[currentIdx].resize();
        }, 100);
      })(k);
    }
  });
});

Tags: javascript closures echarts Event Listeners Responsive Design

Posted on Mon, 27 Jul 2026 16:15:06 +0000 by Copernicus