ECharts tích hợp và xử lý sự cố thường gặp trong React

Vấn đề thường gặp khi sử dụng ECharts

Một lỗi phổ biến xảy ra khi gọi phương thức resize() trên biểu đồ ECharts khi phần tử chứa nó đang ở trạng thái ẩn (ví dụ: display: none). Trong trường hợp này, do không thể xác định kích thước thực tế của DOM, biểu đồ có thể bị render sai lệch hoặc mất định dạng. Để tránh điều này, cần đảm bảo rằng:

  • Chỉ gọi resize() khi phần tử đã được hiển thị trên giao diện.
  • Nếu sử dụng trong component React có điều kiện hiển thị (ví dụ với useState hoặc useEffect), nên kiểm tra sự tồn tại và kích thước của phần tử trước khi resize.

Khởi tạo biểu đồ cơ bản

Dưới đây là cách khởi tạo một biểu đồ tròn (pie chart) đơn giản bằng ECharts trong môi trường React. Lưu ý rằng phần tử DOM phải có kích thước rõ ràng (chiều rộng và chiều cao) thì biểu đồ mới được hiển thị đúng.

import React, { useEffect, useRef } from 'react';
import * as echarts from 'echarts/core';
import { PieChart } from 'echarts/charts';
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([
  PieChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  CanvasRenderer
]);

const ChartComponent = () => {
  const chartRef = useRef(null);
  constchartInstance = useRef<echarts.ECharts | null>(null);

  useEffect(() => {
    if (!chartRef.current) return;

    // Khởi tạo instance ECharts
    const instance = echarts.init(chartRef.current);
   chartInstance.current = instance;

    const option = {
      title: {
        text: 'Biểu đồ minh họa',
        left: 'center',
        textStyle: { fontSize: 14, color: '#555' }
      },
      tooltip: {
        trigger: 'item',
        formatter: '{b}: <b>{c}</b> ({d}%)'
      },
      legend: {
        bottom: '5%',
        left: 'center',
        type: 'scroll',
        itemWidth: 12
      },
      series: [
        {
          name: 'Dữ liệu mẫu',
          type: 'pie',
          radius: ['30%', '60%'],
          center: ['50%', '50%'],
          avoidLabelOverlap: true,
          label: { show: true, formatter: '{c}' },
          emphasis: {
            itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0,0,0,0.3)' }
          },
          data: [
            { value: 21, name: 'Nhóm A' },
            { value: 18, name: 'Nhóm B' },
            { value: 15, name: 'Nhóm C' },
            { value: 12, name: 'Nhóm D' },
            { value: 8, name: 'Nhóm E' }
          ],
          color: ['#4e89ff', '#5bcffc', '#a3d87f', '#ffd972', '#ff9999']
        }
      ]
    };

    instance.setOption(option);

    const handleResize = () => {
      instance.resize();
    };

    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
      if (chartInstance.current) {
        chartInstance.current.dispose();
      }
    };
  }, []);

  return <div ref={chartRef} style={{ height: '400px', width: '100%' }}></div>;
};

export default ChartComponent;

Tối ưu hóa hiệu năng với debounce (tùy chọn)

Khi người dùng thay đổi kích thước cửa sổ liên tục, việc gọi resize() quá nhiều lần có thể ảnh hưởng đến hiệu suất. Có thể áp dụng kỹ thuật debounce để giới hạn tần suất gọi hàm:

const debounce = (func, delay) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, args), delay);
  };
};

// Sử dụng:
const debouncedResize = debounce(() => {
  if (chartInstance.current) chartInstance.current.resize();
}, 200);

Tải module theo nhu cầu (Tree-shaking)

Để giảm kích thước bundle, nên chỉ import những thành phần thực sự cần thiết từ ECharts. Ví dụ:

  • Dùng echarts/core thay vì echarts toàn cục.
  • Chỉ đăng ký các biểu đồ và thành phần được sử dụng qua echarts.use().

Nếu biểu đồ không hiển thị đầy đủ, hãy kiểm tra xem đã đăng ký đủ module tương ứng chưa — ví dụ thiếu PieChart sẽ khiến biểu đồ tròn không hoạt động.

Thẻ: echarts react typescript frontend visualization

Đăng vào ngày 30 tháng 6 lúc 23:58