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.