Agent Skill
2/7/2026

dashboard-maps

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.

B
blsq
0GitHub Stars
1Views
npx skills add BLSQ/mcp_servers

SKILL.md

Namedashboard-maps
DescriptionGuide 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.

name: dashboard-maps description: 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.

Dashboard Maps

Create geographic visualizations with ECharts maps.

Detecting Geographic Data

Column Name Patterns

Search for columns matching these patterns:

TypeColumn Names
Latitudelat, latitude, y, lat_coord, geo_lat
Longitudelon, lng, longitude, x, lon_coord, geo_lon
Combinedgeolocation, coordinates, geo, location, geometry
Shapespolygon, shape, boundary, geojson, geometry
Regionregion, district, country, province, admin_level

Inspecting Data Values

After 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'))
);

Map Type Decision

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

Shape-Based Maps (Choropleth)

Use when data contains polygon geometries (boundaries, regions).

GeoJSON Registration

// 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 }
        ]
    }]
};

Converting Data to GeoJSON

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
        }))
    };
}

Point-Based Maps

Use when data contains latitude/longitude coordinates without shapes.

World Map Background

Load the world map GeoJSON:

// Fetch world map
const worldMap = await fetch('https://cdn.jsdelivr.net/npm/echarts-map@3.0.1/json/world.json')
    .then(r => r.json());
echarts.registerMap('world', worldMap);

Scatter Map Configuration

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]}`;
        }
    }
};

Effectscatter for Animated Points

series: [{
    type: 'effectScatter',
    coordinateSystem: 'geo',
    data: pointData,
    symbolSize: 10,
    rippleEffect: {
        brushType: 'stroke',
        scale: 3
    },
    itemStyle: {
        color: '#ED4B82'
    }
}]

Visual Mapping (Colors by Value)

visualMap: {
    min: 0,
    max: 1000,
    left: 'left',
    top: 'bottom',
    text: ['High', 'Low'],
    calculable: true,
    inRange: {
        color: ['#FDF2F8', '#F472B6', '#ED4B82', '#BE185D']  // Light to dark pink
    }
}

Map Controls

Zoom and Pan

geo: {
    roam: true,           // Enable both zoom and pan
    // OR
    roam: 'move',         // Pan only
    // OR
    roam: 'scale',        // Zoom only

    scaleLimit: {
        min: 0.5,
        max: 10
    },
    center: [0, 20],      // Initial center [lon, lat]
    zoom: 1.5             // Initial zoom level
}

Reset View Button

<button onclick="resetMapView()" class="bg-[#4361EE] text-white px-3 py-1 rounded">
    Reset View
</button>

<script>
function resetMapView() {
    chart.setOption({
        geo: { center: [0, 20], zoom: 1.5 }
    });
}
</script>

Complete Map Example

async function createMap(containerId, data) {
    // Load world map background
    const worldGeo = await fetch('https://cdn.jsdelivr.net/npm/echarts-map@3.0.1/json/world.json')
        .then(r => r.json());
    echarts.registerMap('world', worldGeo);

    const chart = echarts.init(document.getElementById(containerId));

    chart.setOption({
        backgroundColor: 'transparent',
        geo: {
            map: 'world',
            roam: true,
            itemStyle: {
                areaColor: '#F3F4F6',
                borderColor: '#E5E7EB'
            }
        },
        tooltip: {
            trigger: 'item'
        },
        visualMap: {
            min: 0,
            max: Math.max(...data.map(d => d.value)),
            inRange: { color: ['#FDF2F8', '#ED4B82'] },
            calculable: true
        },
        series: [{
            type: 'scatter',
            coordinateSystem: 'geo',
            data: data.map(d => ({
                name: d.name,
                value: [d.lon, d.lat, d.value]
            })),
            symbolSize: val => Math.sqrt(val[2]) * 2,
            itemStyle: { color: '#ED4B82' }
        }]
    });

    return chart;
}
Skills Info
Original Name:dashboard-mapsAuthor:blsq