How to Load and Display Custom GeoJSON Data for Map Charts in ECharts
To display custom GeoJSON data in ECharts, register the map using echarts.registerMap() with a unique name, then reference that name in a map series via the map property.
ECharts renders map charts by converting GeoJSON (or SVG) resources into an internal geo coordinate system. According to the apache/echarts source code, this process involves registering the geographic data, lazy-loading it via GeoJSONResource.load, and rendering through the MapView component. This guide explains the complete workflow with practical code examples derived from the actual implementation.
Understanding the GeoJSON Registration Flow
The lifecycle of custom map data follows a strict pipeline defined in the ECharts source code. When you call echarts.registerMap(), the implementation forwards to geoSourceManager.registerMap in [src/coord/geo/geoSourceManager.ts](https://github.com/apache/echarts/blob/master/src/coord/geo/geoSourceManager.ts) (lines 81‑115).
On the first render, ECharts invokes GeoJSONResource.load from [src/coord/geo/GeoJSONResource.ts](https://github.com/apache/echarts/blob/master/src/coord/geo/GeoJSONResource.ts) (lines 62‑95) to parse the raw GeoJSON. The loader converts features into GeoJSONRegion objects, applies fixes for known coordinate issues (such as Nanhai or Diaoyu Island adjustments), and supplies the data to MapView for rendering. This architecture ensures that geographic resources are loaded lazily and cached efficiently.
How to Register Custom GeoJSON Maps
ECharts provides multiple signatures for registerMap to support backward compatibility and different data formats. The method accepts three distinct calling patterns:
- Raw GeoJSON + specialAreas:
echarts.registerMap('name', geoJson, specialAreas) - Object wrapper:
echarts.registerMap('name', { geoJSON: geoJson, specialAreas }) - SVG maps: Using
svgproperty instead ofgeoJSON(not covered here)
The map name must be unique within the ECharts instance. Registering the same name overwrites the previous resource.
Synchronous Registration
For GeoJSON data already available in your JavaScript context, register synchronously before setting the chart option.
// Prepare a GeoJSON object (or JSON string)
const customGeoJson = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "name": "RegionA" }, "geometry": { "type": "Polygon", "coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1]]] } }
]
};
// Register with a unique name
echarts.registerMap('customRegion', customGeoJson);
// Configure the map series
const option = {
series: [{
type: 'map',
map: 'customRegion', // References the registered name
roam: true,
label: { show: true },
data: [
{ name: 'RegionA', value: 120 }
]
}]
};
myChart.setOption(option);
This registration maps directly to the internal geoSourceManager.registerMap implementation.
Asynchronous Loading from a URL
For large geographic datasets, fetch the GeoJSON asynchronously and register it before initializing the series.
fetch('https://example.com/maps/custom-country.json')
.then(res => res.json())
.then(geoJson => {
// Optional: Define special areas to reposition distant regions
const specialAreas = {
'Alaska': { left: 0, top: 0.2, width: 0.2, height: 0.2 }
};
echarts.registerMap('customCountry', geoJson, specialAreas);
myChart.setOption({
series: [{
type: 'map',
map: 'customCountry',
roam: true,
data: [{ name: 'RegionA', value: 75 }]
}]
});
})
.catch(err => console.error('Failed to load GeoJSON:', err));
The registerMap call handles both raw GeoJSON and the specialAreas object. The actual loading logic executes lazily when the chart first requires the map resource.
Using the Object-Style Registration
For future-proofing and clarity, use the object-style syntax that explicitly names the GeoJSON property.
echarts.registerMap('myMap', {
geoJSON: myGeoJson, // Accepts object or JSON string
specialAreas: {
'IslandX': { left: 0.8, top: 0.1, width: 0.2, height: 0.2 }
}
});
This signature matches the second parameter pattern described in the geoSourceManager implementation.
Configuring Special Areas and Region Positioning
The specialAreas parameter allows you to reposition or resize specific regions that would otherwise render far from the main landmass. This is commonly used for overseas territories or islands.
Each key in specialAreas corresponds to a region name in your GeoJSON's properties.name. The value is an object with left, top, width, and height specified as ratios (0‑1) relative to the bounding box.
const specialAreas = {
'Hainan': { left: 0.6, top: 0.7, width: 0.1, height: 0.1 }
};
echarts.registerMap('china', chinaGeoJson, specialAreas);
When GeoJSONResource.load processes the data, it applies these transformations to create the final GeoJSONRegion objects used by the rendering pipeline.
Summary
- Registration is mandatory: Use
echarts.registerMap()to bind a GeoJSON resource to a unique name before creating a map series. - Three API signatures: Pass raw GeoJSON with optional
specialAreas, use an object wrapper withgeoJSONkey, or register SVG data. - Lazy loading: The actual parsing and region creation happens in
GeoJSONResource.loadduring the first render cycle. - Special areas: Reposition distant regions using the
specialAreasparameter to keep the map visualization compact. - Series configuration: Reference the registered map name in the series
mapproperty, not the GeoJSON object itself.
Frequently Asked Questions
Can I update a registered map dynamically after the chart is rendered?
Yes, but you must re-register the map and then call setOption again. Registering the same map name overwrites the previous entry in geoSourceManager. After calling echarts.registerMap('myMap', newGeoJson), execute myChart.setOption({ series: [{ map: 'myMap' }] }) to trigger a re-render with the new geographic data.
What is the difference between geoJSON and geoJson in the registerMap parameters?
ECharts accepts both casing variations for backward compatibility. In the object-style registration, you can use either geoJSON or geoJson as the property key. The implementation normalizes these to the same internal handler in [geoSourceManager.ts](https://github.com/apache/echarts/blob/master/src/coord/geo/geoSourceManager.ts).
How do I handle GeoJSON files that are too large for synchronous loading?
For large GeoJSON files, always use asynchronous loading with fetch() or XMLHttpRequest. Register the map only after the data arrives, then call setOption. ECharts caches the processed GeoJSONRegion objects internally, so subsequent renders of the same map name do not reload the file.
Why are some regions not displaying even though they exist in my GeoJSON?
Ensure that the name property in your GeoJSON features matches exactly (case-sensitive) the names referenced in your series data and any specialAreas configuration. The GeoJSONResource loader indexes regions by their properties.name field. If names mismatch, the region renders but data binding fails, or the region may be filtered out during the coordinate system conversion.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →