How to Capture ECharts Charts: html2canvas vs snapdom – A Practical Guide

This article walks through setting up an ECharts combo chart, then compares html2canvas and snapdom for one‑click screenshot and download, covering installation, core code, common pitfalls, performance benchmarks, and scenario‑based selection advice to help developers choose the right tool for reliable chart export.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
How to Capture ECharts Charts: html2canvas vs snapdom – A Practical Guide

Introduction

Recently a backend management system required a feature that lets users capture ECharts charts (line, bar, pie) with a single click for reporting or archiving. This guide uses the "ECharts chart screenshot" scenario to compare the mature html2canvas library with the newer, lightweight snapdom , detailing usage differences, source‑level logic, and selection recommendations.

1. Basic Setup: ECharts Chart Initialization

Before comparing the two libraries, create a standard ECharts chart DOM that will be used for all screenshots.

<!-- Chart container: includes title and ECharts canvas -->
<div id="chart-container" style="width: 600px; padding: 20px; background:#fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
  <h3 style="text-align: center; margin-bottom: 15px; color:#333;">2024 Monthly User Growth Trend</h3>
  <!-- ECharts canvas -->
  <div id="user-chart" style="width: 100%; height: 320px;"></div>
</div>
<button id="download-chart" style="margin-top: 20px; padding: 8px 16px; background:#409eff; color:#fff; border:none; border-radius:4px; cursor:pointer;">📥 Download Chart</button>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
<script>
  const initEcharts = () => {
    const chartDom = document.getElementById('user-chart');
    const myChart = echarts.init(chartDom);
    const option = {
      tooltip: { trigger: 'axis' },
      legend: { data: ['New Users', 'Active Users'], top: 0 },
      xAxis: { type: 'category', data: ['Jan','Feb','Mar','Apr','May','Jun'] },
      yAxis: { type: 'value' },
      series: [
        { name: 'New Users', type: 'bar', data: [1200,1900,2300,2100,2500,3100], itemStyle: { color: '#409eff' } },
        { name: 'Active Users', type: 'line', data: [800,1500,1800,1600,2000,2600], lineStyle: { width: 3, color: '#67c23a' }, symbol: 'circle', symbolSize: 8 }
      ]
    };
    myChart.setOption(option);
    window.addEventListener('resize', () => myChart.resize());
    return myChart;
  };
  window.onload = initEcharts;
</script>

The code above generates a combined bar‑and‑line chart. All subsequent screenshot steps target the #chart-container element, which includes the title and the chart.

2. Practical Implementation: Two Libraries for ECharts Screenshot

2.1 html2canvas – Legacy Solution (Compatibility First)

Installation & Import

# npm install
npm install html2canvas
# Or use CDN (no build step needed)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js"></script>

Core Screenshot Code

// Bind click event to download button
document.getElementById('download-chart').addEventListener('click', async () => {
  const chartContainer = document.getElementById('chart-container');
  const chartDom = document.getElementById('user-chart');
  const myChart = echarts.getInstanceByDom(chartDom);
  // Ensure chart is freshly rendered
  myChart.resize();
  // html2canvas options tuned for ECharts
  const html2canvasOptions = {
    scale: 2,               // High‑DPI screens
    useCORS: true,          // Load cross‑origin images
    logging: false,
    backgroundColor: '#fff',
    ignoreElements: el => el.classList.contains('echarts-tooltip') || el.classList.contains('echarts-loading'),
    windowWidth: document.documentElement.clientWidth,
    windowHeight: document.documentElement.clientHeight
  };
  try {
    const canvas = await html2canvas(chartContainer, html2canvasOptions);
    const downloadLink = document.createElement('a');
    const fileName = `UserGrowth_${new Date().toLocaleDateString().replace(/\//g,'-')}.png`;
    downloadLink.download = fileName;
    downloadLink.href = canvas.toDataURL('image/png', 0.92);
    downloadLink.click();
    URL.revokeObjectURL(downloadLink.href);
  } catch (error) {
    console.error('html2canvas screenshot failed:', error);
    alert('Screenshot failed, please retry!');
  }
});

Key Pitfalls

Tooltip residue : ECharts tooltips are temporary DOM nodes; filter them via ignoreElements to avoid random tooltip artifacts in the screenshot.

Blurry output on Retina screens : Canvas is rendered at 1× scale by default; set scale: 2 (or match devicePixelRatio) to obtain crisp images.

Async data timing : If chart data loads asynchronously, trigger the screenshot after myChart.setOption completes, or listen to the finished event.

2.2 snapdom – Modern Lightweight Solution (Performance First)

Installation & Import

# npm install (recommended for project management)
npm install snapdom
# Or include the UMD build directly
<script src="./snapdom.min.js"></script>

Core Screenshot Code

// Bind click event to download button
document.getElementById('download-chart').addEventListener('click', async () => {
  const chartContainer = document.getElementById('chart-container');
  const chartDom = document.getElementById('user-chart');
  const myChart = echarts.getInstanceByDom(chartDom);
  myChart.resize();
  const snapdomOptions = {
    scale: 2,
    allowCORS: true,
    transparent: false,
    processNode: node => {
      // Convert ECharts canvas to <img> for SVG compatibility
      if (node.tagName === 'CANVAS' && node.parentNode.id === 'user-chart') {
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = node.width;
        tempCanvas.height = node.height;
        tempCanvas.getContext('2d').drawImage(node, 0, 0);
        const chartImg = document.createElement('img');
        chartImg.src = tempCanvas.toDataURL('image/png');
        chartImg.style.width = '100%';
        chartImg.style.height = '100%';
        chartImg.style.objectFit = 'contain';
        return chartImg;
      }
      // Filter ECharts tooltip nodes
      if (node.classList.contains('echarts-tooltip')) {
        return document.createComment('ignore echarts tooltip');
      }
      return node;
    }
  };
  try {
    const imageUrl = await snapdom(chartContainer, snapdomOptions);
    const downloadLink = document.createElement('a');
    const fileName = `UserGrowth_${new Date().toLocaleDateString().replace(/\//g,'-')}.png`;
    downloadLink.download = fileName;
    downloadLink.href = imageUrl;
    downloadLink.click();
    URL.revokeObjectURL(imageUrl);
  } catch (error) {
    console.error('snapdom screenshot failed:', error);
    alert('Screenshot failed, please retry!');
  }
});

Key Pitfalls

Canvas‑to‑img conversion : SVG’s foreignObject cannot render canvas directly, so the processNode step must replace each ECharts canvas with an img element.

Browser compatibility : snapdom relies on foreignObject, which is unsupported in IE; it works in modern Chrome, Firefox, Safari, and Electron.

Style inheritance : Inline styles may need to be added manually (e.g., chart titles) because the cloned DOM inside SVG does not inherit external CSS automatically.

3. Deep Comparison (Usage & Source‑Level Differences)

Usage level : html2canvas natively handles canvas and offers >20 fine‑grained options, making it suitable for complex scenarios. snapdom provides a minimal API (≈5 core options + processNode) and returns a ready‑to‑download image URL.

Source implementation : html2canvas traverses the DOM, parses styles, and draws each node onto a canvas, with special handling for cross‑origin canvas pollution. snapdom clones the DOM, embeds it in an SVG foreignObject, converts ECharts canvas to img, then rasterizes the SVG to a PNG.

Performance & memory : In benchmark tests (single combo chart + three DOM elements), snapdom averages 120 ms for the first screenshot and 95 MB peak memory, while html2canvas takes 280 ms and 180 MB. The gap widens with larger data sets.

4. Scenario‑Based Selection Guidance

Prefer html2canvas when

IE11 or other legacy browsers must be supported.

Charts contain complex interactive elements (dynamic tooltips, dataZoom, cross‑origin background images, loading states).

Maximum stability is required for official reports or audits.

Fine‑grained control over capture region or rendering parameters is needed.

Prefer snapdom when

Only modern browsers are targeted (Chrome, Firefox, Safari, Electron).

Frequent or real‑time screenshots are required (e.g., monitoring dashboards).

Package size matters (snapdom ~20 KB vs html2canvas ~100 KB).

Chart styles are simple (basic line, bar, pie) without heavy interactivity.

Conclusion

html2canvas and snapdom are complementary rather than interchangeable. Choose html2canvas for broad compatibility and robust handling of complex ECharts features; choose snapdom for superior performance, smaller bundle size, and a streamlined workflow in modern browser environments.

AI编程资讯AI Coding专区指南: https://aicoding.juejin.cn/aicoding
frontendCompatibilityhtml2canvasEChartsscreenshotsnapdom
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.