The ECharts chart isn't showing

ECharts fails in two ways: loudly, with an error in the console, or silently, with a perfectly empty <div>. The silent case is the common one, and it is almost always about size. Open DevTools (F12), check the Console, then inspect the container in Elements — if ECharts ran, there is a <canvas> (or <svg>) inside it, and its width and height tell you most of the story.

One thing to know first: the minified build hides the hints. echarts.min.js strips ECharts' development warnings, including the one about zero-size containers. Swap in echarts.js while you debug.

Match the symptom

What you see Cause
Uncaught ReferenceError: echarts is not defined The library never loaded
Error: Initialize failed: invalid dom. echarts.init() got null
Empty <div>, no error (minified build) Container is 0px tall
Can't get DOM width or height… (unminified build) Container is 0px tall
Chart blank until the window is resized Initialised while hidden (display: none)
… is used but not imported echarts/core without echarts.use([...])
Map … not exists. The GeoJSON of the map must be provided Map not registered
There is a chart instance already initialized on the dom. init() called twice on one element
Old series still drawn after setOption setOption merges by default
Axes drawn, no bars or lines Data arrived after setOption, or wrong axis type
Access to fetch at 'file:///…' … blocked by CORS policy Loading data or GeoJSON from a local file

The library didn't load

echarts exists only after its <script> has run. Load it above your code and pin the major version you built against:

<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

If the Network tab shows that request failing, the CDN is blocked — a corporate proxy, an offline laptop, or a viewer whose Content-Security-Policy refuses third-party scripts. A local echarts.min.js works for you and 404s for everyone you send just the .html to; the same trap as lost CSS.

With a bundler, import * as echarts from "echarts" is the full build. import echarts from "echarts" is undefined in ECharts 5 — there is no default export.

The container is 0px tall

<div id="chart"></div>
<!-- height: auto, no content → 0px -->

ECharts reads clientWidth and clientHeight once, at init(). A div with no explicit height has none, so the canvas is created at 0 pixels and nothing is visible. Give it a size:

<div id="chart" style="width: 100%; height: 420px"></div>

height: 100% only works if every ancestor up to one with a fixed height also has a height. Inside a flex column, use flex: 1; min-height: 0 on the container and make sure the flex parent itself is sized.

Initialize failed: invalid dom

document.getElementById("chart") returned null — the script ran in <head> before the div existed, or the id doesn't match. Put the script after the element, add defer, or wrap the code:

document.addEventListener("DOMContentLoaded", () => {
  const chart = echarts.init(document.getElementById("chart"));
  chart.setOption(option);
});

Blank in a tab, modal or accordion

A container that is display: none at init() measures 0×0 — same bug, different cause. When the panel opens, tell the chart to measure again:

tabButton.addEventListener("click", () => {
  showPanel();
  chart.resize();
});

Charts that should follow their container — sidebars collapsing, split panes, window resizing — want a ResizeObserver:

new ResizeObserver(() => chart.resize()).observe(chart.getDom());

In React or Vue, also call chart.dispose() on unmount. Re-running echarts.init() on an element that already has a chart logs "There is a chart instance already initialized on the dom" and reuses the old instance; use echarts.getInstanceByDom(el) ?? echarts.init(el).

… is used but not imported

The echarts/core entry point is tree-shakeable: it ships nothing until you register it. Every series type, every component the option mentions (grid, tooltip, legend, dataZoom, title…) and one renderer have to be passed to echarts.use:

import * as echarts from "echarts/core";
import { BarChart, LineChart } from "echarts/charts";
import {
  GridComponent,
  TooltipComponent,
  LegendComponent,
  DatasetComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";

echarts.use([
  BarChart,
  LineChart,
  GridComponent,
  TooltipComponent,
  LegendComponent,
  DatasetComponent,
  CanvasRenderer,
]);

A missing component is quieter than a missing series: forget TooltipComponent and the chart draws, it just never shows a tooltip.

The map is empty

ECharts 5 removed the bundled world and country maps. A geo component or map series that names "world" draws nothing until you register the GeoJSON yourself:

const geoJson = await fetch("/maps/world.json").then((r) => r.json());
echarts.registerMap("world", geoJson);
chart.setOption({ series: [{ type: "map", map: "world", data }] });

The name in registerMap and the map: option must match exactly, and the region names in your data must match the name properties in the GeoJSON — "United States" and "United States of America" are different regions.

setOption kept the old data

setOption merges into the existing option. Removing a series, or switching from four series to two, leaves the extras on screen. Replace instead of merge:

chart.setOption(option, { notMerge: true });
// or only replace the series array:
chart.setOption(option, { replaceMerge: ["series"] });

If data comes from fetch, set the option after it resolves — or set the axes first, call chart.showLoading(), and hideLoading() plus setOption({ series: [...] }) when the data lands. And check the axis type: a category axis needs labels (xAxis.data or a dataset), while numeric x values belong on a value or time axis.

Data or GeoJSON from a local file

Opened as file://, the page has an opaque origin and the browser blocks fetch() of neighbouring files — the CORS error from origin 'null'. Serve the folder over HTTP while developing (python3 -m http.server) and inline the data into the page for anything you send.

pyecharts HTML is blank

Bar().render("chart.html") writes a page whose <script> points at the pyecharts assets host on the web. No network, a proxy, or a strict CSP, and the file opens empty. Point it at a CDN you know is reachable before rendering:

from pyecharts.globals import CurrentConfig

CurrentConfig.ONLINE_HOST = "https://cdn.jsdelivr.net/npm/echarts@5/dist/"

Or copy echarts.min.js next to the HTML and set ONLINE_HOST to that folder — then send the folder, not just the file.

Or skip the script for this chart

If the chart only has to be read — a bar, line or pie in a report or a PR comment — it may not need a charting runtime at all. Paste the numbers into CSV to chart or JSON to chart and get a static SVG that can't fail to load.

Sharing an ECharts chart that works

When it renders, send a link instead of the file. Published to Comma, the page runs in a sandboxed iframe (allow-scripts, no allow-same-origin), so tooltips, legend toggles and dataZoom keep working, and reviewers comment on the exact bar or data point they mean. Two caveats: a published report can't fetch() sibling files, so inline the data and GeoJSON; and vendor the library if your readers sit behind a proxy that blocks CDNs.

Publish an ECharts report →

Related