Guide for creating map visualizations in dashboards. Covers geographic data detection, shape-based maps (polygons/GeoJSON), point-based maps (lat/lon coordinates), and world map backgrounds. Referenced by dashboard-builder skill. Do not use directly - use dashboard-builder instead.
Create geographic visualizations with ECharts maps.
Search for columns matching these patterns:
| Type | Column Names |
|---|---|
| Latitude | lat, latitude, y, lat_coord, geo_lat |
| Longitude | lon, lng, longitude, x, lon_coord, geo_lon |
| Combined | geolocation, coordinates, geo, location, geometry |
| Shapes | polygon, shape, boundary, geojson, geometry |
| Region | region, , , , |
districtcountryprovinceadmin_levelAfter fetching sample data, check the actual values:
// Check if values look like coordinates
const sample = data[0];
const hasLatLon = (
(typeof sample.lat === 'number' && Math.abs(sample.lat) <= 90) &&
(typeof sample.lon === 'number' && Math.abs(sample.lon) <= 180)
);
// Check if values are GeoJSON or WKT
const hasShapes = (
typeof sample.geometry === 'string' &&
(sample.geometry.startsWith('{') || sample.geometry.startsWith('POLYGON'))
);
Geographic data detected?
├── YES: Contains shapes (polygons/GeoJSON)?
│ ├── YES → Use Shape-Based Map (choropleth)
│ └── NO: Contains lat/lon points?
│ ├── YES → Use Point-Based Map with world background
│ └── NO → Cannot create map
└── NO → Cannot create map
Use when data contains polygon geometries (boundaries, regions).
// Register custom GeoJSON
echarts.registerMap('customMap', geoJsonData);
const option = {
geo: {
map: 'customMap',
roam: true, // Enable zoom/pan
itemStyle: {
areaColor: '#FDF2F8',
borderColor: '#ED4B82'
},
emphasis: {
itemStyle: {
areaColor: '#F472B6'
}
}
},
series: [{
type: 'map',
map: 'customMap',
data: [
{ name: 'Region A', value: 100 },
{ name: 'Region B', value: 200 }
]
}]
};
If shapes are in WKT format or separate columns:
function toGeoJSON(data) {
return {
type: 'FeatureCollection',
features: data.map(row => ({
type: 'Feature',
properties: {
name: row.name,
value: row.value
},
geometry: typeof row.geometry === 'string'
? JSON.parse(row.geometry)
: row.geometry
}))
};
}
Use when data contains latitude/longitude coordinates without shapes.
Load the world map GeoJSON:
// Fetch world map
const worldMap = await fetch('https://cdn.jsdelivr.net/npm/[email protected]/json/world.json')
.then(r => r.json());
echarts.registerMap('world', worldMap);
const option = {
geo: {
map: 'world',
roam: true,
itemStyle: {
areaColor: '#F3F4F6',
borderColor: '#E5E7EB'
},
emphasis: {
itemStyle: {
areaColor: '#FDF2F8'
}
}
},
series: [{
type: 'scatter',
coordinateSystem: 'geo',
data: data.map(row => ({
name: row.name,
value: [row.lon, row.lat, row.value], // [longitude, latitude, value]
itemStyle: {
color: '#ED4B82'
}
})),
symbolSize: function(val) {
return Math.max(6, Math.min(30, val[2] / 10)); // Size based on value
},
encode: {
value: 2
}
}],
tooltip: {
formatter: function(params) {
return `${params.name}<br/>Value: ${params.value[2]}`;
}
}
};