Building a China COVID-19 Map with ECharts and Live Data

This article demonstrates how to create an interactive COVID-19 map of China using Apache ECharts. Two approaches are covered: fetching live data from the Tencent API and consuming server-side data (e.g., from a Java backend). The visual map uses piecewise coloring to reflect confirmed case ranges across provinces.

Approach 1: Fetching Live Data from Tencent API

The following HTML page loads ECharts and the China map plugin, then retrieves province-level confirmed case data via JSONP from the Tencent public endpoint.


<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>COVID-19 China Map</title>
  <style>
    #mapContainer { width: 800px; height: 500px; margin: 20px auto; border: 1px solid #ddd; }
  </style>
  <!-- ECharts CDN -->
  <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
  <!-- China map registration -->
  <script src="https://cdn.jsdelivr.net/npm/echarts@5/map/json/china.json"></script>
</head>
<body>
<div id="mapContainer"></div>
<script>
  const chart = echarts.init(document.getElementById('mapContainer'));
  const option = {
    title: { text: 'Confirmed Cases in China', left: 'center' },
    tooltip: { trigger: 'item' },
    visualMap: {
      type: 'piecewise',
      pieces: [
        { min: 10000, label: '≥10k', color: '#4e160f' },
        { min: 1000, max: 9999, label: '1k-9,999', color: '#974236' },
        { min: 100, max: 999, label: '100-999', color: '#ee7263' },
        { min: 1, max: 99, label: '1-99', color: '#f5bba7' }
      ],
      color: ['#E0022B', '#E09107', '#A3E00B']
    },
    toolbox: {
      show: true, orient: 'vertical', left: 'right', top: 'center',
      feature: { mark: true, dataView: { readOnly: false }, restore: true, saveAsImage: true }
    },
    series: [{
      name: 'Confirmed',
      type: 'map',
      map: 'china',
      roam: false,
      label: { show: true, color: '#fff' },
      data: []
    }]
  };
  chart.setOption(option);

  // Fetch data from Tencent API
  fetch('https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5')
    .then(response => response.json())
    .then(result => {
      const raw = result.data || '{}';
      const parsed = JSON.parse(raw);
      const provinces = parsed.areaTree[0].children;
      const data = provinces.map(p => ({ name: p.name, value: p.total.confirm }));
      chart.setOption({ series: [{ data: data }] });
    })
    .catch(console.error);
</script>
</body>
</html>

The API returns a nested structure; we extract province names and confirmed counts. Note that ECharts map built-in names must match exactly (e.g., "北京" not "北京市"). The Tencent API uses short names that align with the China map, so no nameMap is required.

Approach 2: Using Server-Side Data (Java/JSP)

If your data comes from a backend (e.g., a Java servlet), you can embed the data as a JSON array in the page. Below is a simplified JSP snippet that renders the map with server-provided province data.

<%@ page import="java.util.List" %>
<!-- Assume "list" attribute contains ProvinceData objects with name and confirmed -->
<html>
<head>
  <meta charset="UTF-8">
  <title>Server-Side China Map</title>
  <style>
    #chart { width: 800px; height: 500px; margin: auto; }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5/map/json/china.json"></script>
</head>
<body>
<div id="chart"></div>
<script>
  const chart = echarts.init(document.getElementById('chart'));
  const serverData = [
    <% 
      List<ProvinceData> list = (List<ProvinceData>) request.getAttribute("list");
      if (list != null) {
        for (int i = 0; i < list.size(); i++) {
          ProvinceData p = list.get(i);
          // Escape names properly
          String name = p.getName().replace("'", "\\'");
          out.print("{ name: '" + name + "', value: " + p.getConfirmed() + " }");
          if (i < list.size() - 1) out.print(", ");
        }
      }
    %>
  ];
  const option = {
    title: { text: 'Confirmed Cases (Server Data)', left: 'center' },
    tooltip: { trigger: 'item' },
    visualMap: {
      type: 'piecewise',
      pieces: [
        { min: 10000, label: '≥10k', color: '#4e160f' },
        { min: 1000, max: 9999, label: '1k-9,999', color: '#974236' },
        { min: 100, max: 999, label: '100-999', color: '#ee7263' },
        { min: 1, max: 99, label: '1-99', color: '#f5bba7' }
      ]
    },
    series: [{
      type: 'map',
      map: 'china',
      data: serverData,
      label: { show: true, color: '#fff' }
    }]
  };
  chart.setOption(option);
</script>
</body>
</html>

If the backend uses province full names (e.g., "北京市") that differ from the map's built-in names, you can apply a nameMap to translate. Alternatively, store the data using the map's default short names to avoid mapping.

Key Considerations

  • Map Registration: Always load the China JSON map file after ECharts. As of ECharts 5, you can use echarts.registerMap('china', chinaJson) if you load the JSON directly.
  • Data Matching: Province names in the data array must match exactly the names used in the map. The built-in China map uses short names like "北京", "天津", "上海", etc.
  • API Changes: The Tencent API endpoint may change. Always handle errors and check resposne structure.
  • Province Drill-Down: To allow clicking into a province, you can listen to the click event and load a sub-map (city-level data). This is a advanced extension not covered here.

Tags: echarts China map COVID-19 Tencent API javascript

Posted on Tue, 23 Jun 2026 17:07:41 +0000 by Will Poulson