ECharts地图下钻功能:从全国到省市的无缝切换

ECharts地图下钻功能实战:从全国到省市的无缝切换

效果预览

实现后的效果是:初始显示中国地图,用户点击某个省份后,地图会平滑过渡到该省的地图,显示该省的各个市区县数据。同时,界面上会出现"返回全国"按钮,点击后可返回全国视图。

完整实现步骤

1. 基础页面结构

首先,我们需要创建基础的页面结构,包括地图容器和返回按钮:

js 复制代码
<template>
    <div style="position: relative;">
        <div id="main" ref="mapRef" style="width: 100%; height: 800px;"></div>
        <button v-if="showBackButton" class="back-button" @click="backToCountry">返回全国</button>
    </div>
</template>

2. 引入必要的依赖和数据

js 复制代码
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
import chinaJson from '@/assets/map.json'  // 中国地图JSON数据
import cityJson from '@/assets/city.json'  // 省级行政区划数据

中国地图JSON数据和省级行政区划数据可以去网上下载,也可以用JSON API,我这里是下载到本地的。 datav.aliyun.com/portal/scho...

3. 定义状态变量

js 复制代码
// 添加状态变量,并明确指定类型
const currentLevel = ref('country'); // 'country' 或 'province'
const showBackButton = ref(false);
const myChartRef = ref<echarts.ECharts | null>(null);

4. 地图初始化

js 复制代码
onMounted(() => {
    initMap()
    // 处理窗口大小变化
    window.addEventListener('resize', function () {
        if (myChartRef.value) {
            myChartRef.value.resize()
        }
    });
})

// 初始化地图
const initMap = () => {
    // 初始化图表实例并保存引用
    myChartRef.value = echarts.init(document.getElementById('main'));
    try {
        // 初始化全国地图
        initCountryMap();
        
        // 省份下钻点击事件
        myChartRef.value.on('click', (params: any) => {
            if (params.name && currentLevel.value === 'country') {
                let data = cityJson.features.filter((item: any) => {
                    return item.properties.name == params.name
                })
                if (data.length > 0) {
                    let data2 = chinaJson.features.filter((item: any) => {
                        if (item.properties && item.properties.parent) {
                            return item.properties.parent.adcode === data[0].properties.adcode
                        }
                        return false
                    })
                    
                    // 计算省份的中心点
                    let centerPoint = calculateCenter(data[0].geometry.coordinates);
                    
                    let map = { type: "FeatureCollection", features: data2 }
                    echarts.registerMap('sheng', map);
                    const shiquData = randomData(data2, 30, 200)
                    
                    // 更新地图,传入计算的中心点
                    getOption(`${params.name}地区数据`, 'sheng', shiquData, 1.2, centerPoint)
                    
                    // 更新状态
                    currentLevel.value = 'province';
                    showBackButton.value = true;
                }
            }
        })
    } catch (error) {
        console.error('加载地图数据失败', error);
    }
}

5. 全国地图初始化

js 复制代码
// 初始化全国地图
const initCountryMap = () => {
    if (!myChartRef.value) return;
    // 处理地图数据格式,确保与ECharts兼容
    echarts.registerMap('china', cityJson);
    // 生成随机的省级数据
    const shengData = randomData(cityJson.features, 30, 200)
    let center = [104.0, 37.5]  // 中国地图的中心点
    getOption('中国各省份数据', 'china', shengData, 1.5, center)
}

6. 地图配置函数

js 复制代码
//封装配置信息
const getOption = (text: string, map: string, data: any, zoom: number = 1, center: any) => {
    return myChartRef.value.setOption({
        title: {
            text,
            left: 'center'
        },
        tooltip: {
            trigger: 'item',
            formatter: '{b}<br/>数据值: {c}'
        },
        // 添加视觉映射组件
        visualMap: {
            min: 0,
            max: 250,
            left: 'left',
            top: 'bottom',
            text: ['高', '低'],
            calculable: true,
            inRange: {
                color: ['#e0f3f8', '#43a2ca', '#0868ac']
            }
        },
        series: [
            {
                name: '省份数据',
                type: 'map',
                map,
                roam: false,
                zoom,
                center,  // 设置地图中心点
                emphasis: {
                    label: {
                        show: true
                    },
                },
                data
            }
        ]
    }, true);
}

7. 计算地图中心点

js 复制代码
// 计算多边形中心点
const calculateCentroid = (points: number[][]) => {
    if (!points || points.length === 0) return [104.0, 37.5];
    
    let sumLng = 0;
    let sumLat = 0;
    
    for (let i = 0; i < points.length; i++) {
        sumLng += points[i][0];
        sumLat += points[i][1];
    }
    
    return [sumLng / points.length, sumLat / points.length];
}

// 添加计算中心点的函数
const calculateCenter = (coordinates: any) => {
    // 处理多边形的情况
    if (coordinates && coordinates.length > 0) {
        // 如果是多多边形(如一些省份有离岛)
        if (coordinates[0][0] && Array.isArray(coordinates[0][0][0])) {
            // 取第一个多边形的坐标计算
            const points = coordinates[0][0];
            return calculateCentroid(points);
        } 
        // 如果是单多边形
        else if (coordinates[0] && Array.isArray(coordinates[0][0])) {
            const points = coordinates[0];
            return calculateCentroid(points);
        }
    }
    // 默认返回中国中心点
    return [104.0, 37.5];
}

9. 随机数据生成函数

js 复制代码
//随机生成数据
const randomData = (data: any, min: number, max: number) => {
    return data.map((item: any) => {
        const cityName = item.properties.name;
        // 生成min-max之间的随机数
        const value = Math.floor(Math.random() * (max - min + 1)) + min;
        return { name: cityName, value };
    });
}

核心技术点详解

1. 地图数据结构

本实例使用了两个主要的地图数据文件:

  • cityJson:包含中国各省级行政区的地理信息

  • chinaJson:包含各省内市级行政区的地理信息

这些文件的结构遵循GeoJSON格式,包含了地理坐标和行政区划信息。

2. 地图下钻原理

地图下钻的核心原理是:1. 用户点击省份时,从地图数据中筛选出该省的所有市级数据

  • 将这些数据注册为新的地图

  • 使用ECharts的setOption方法切换到新地图

3. 中心点计算

为了确保下钻后的地图居中显示,我们需要计算该省份的几何中心点:

  • 从GeoJSON数据中提取该省份的坐标信息

  • 针对不同格式的坐标数据(多边形、多多边形等)进行适当处理

  • 计算所有点的平均经纬度作为中心点

  • 将计算得到的中心点传入地图配置

4. 状态管理

我们使用两个关键状态变量:

  • currentLevel:记录当前地图层级(全国或省级)

  • showBackButton:控制返回按钮的显示与隐藏

实现注意事项

地图数据格式:确保GeoJSON数据格式正确,必要时需要进行预处理

总结

通过以上步骤,实现了一个完整的ECharts地图下钻功能,支持从全国到省级的无缝切换,并通过精确计算地图中心点确保了良好的显示效果。这种交互方式能提升用户体验,使数据展示更加直观、层次分明。在实际应用中,还可以根据业务需求扩展更多功能,如添加更多层级的下钻、整合真实数据源、自定义样式主题等,使地图可视化效果更加丰富多样。

相关推荐
Factor安全1 分钟前
Chrome漏洞可窃取数据并获得未经授权的访问权限
前端·chrome·web安全·网络安全·安全威胁分析·安全性测试
齐尹秦13 分钟前
CSS 文本样式学习笔记
前端
程序员皮蛋鸽鸽16 分钟前
从零配置 Linux 与 Windows 互通的开发环境
前端·后端
kovli20 分钟前
红宝书第十二讲:详解JavaScript中的工厂模式与原型模式等各种设计模式
前端·javascript
凯哥197020 分钟前
Sciter.js 指南-核心概念:GUI应用程序项目结构、视图切换与组件化
前端
jinzunqinjiu22 分钟前
学习react-native组件 1 Image加载图片的组件。
前端·react native
用户9623373845023 分钟前
CSS基础知识03
前端
SouthernWind24 分钟前
DeepSeek AI 聊天助手集成指南
前端·cursor
咪库咪库咪25 分钟前
表单验证
前端
xcLeigh1 小时前
HTML5好看的水果蔬菜在线商城网站源码系列模板5
java·前端·源码·html5