echarts-gl 3D地图下钻(省/市)

效果:

 一、获取GeoJson地图数据:

DataV.GeoAtlas 地理工具icon-default.png?t=O83Ahttps://datav.aliyun.com/portal/school/atlas/area_selector

这里只下载了是省、市的数据,要下载县/区的话需要指定市单独下载(或者直接找网上资源),然后放在本地目录下:

二、核心代码: 

1.注册地图数据:
const initMap = (fileName) => { 
    // JSON文件(地图数据)路径
    let dataURL = `GeoJSON/${fileName}.json`;

    fetch(dataURL).then((res) => res.json()).then((geoJson) => {
        // 如果是下钻到市级,则注册的registerGeoJSON为当前省下面的所有市级数据范围
        let registerGeoJSON = fileName === 'city' ? getCitys(geoJson) : geoJson;

        // 注册地图名字(fileName)和数据(registerGeoJSON)
        echarts.registerMap(fileName, registerGeoJSON);
        
        //配置echarts
        let options = {
            series: [{
                type: 'map3D',
                map: fileName,// 注册的地图名字
                ...
            }]
        }
        options && chartDom.value.setOption(options);
    })
}

// 获取当前省的市级数据
const getCitys = (geoJson) => {
    let cityArr = geoJson.features.filter(feature => {
        return feature.properties?.parent?.adcode === curProvince.adcode;
    });
    return {
        features: cityArr
    }
}
2.阻止右键,返回到省层级:
<div id="echartsDom" @contextmenu.prevent="initMap('province')"></div>

三、完整代码: 

<template>
    <div id="echartsDom" @contextmenu.prevent="initMap('province')"></div>
</template>

<script setup>
import { onMounted, ref, shallowRef } from "vue"
//echarts
import * as echarts from 'echarts'
import 'echarts-gl'
import { message } from 'ant-design-vue'

let curProvince = { //当前省数据
    name: '',
    adcode: null,
}
const chartDom = shallowRef();
const echartsRef = ref();

onMounted(() => {
    initEcharts();
    initMap('province');
})

const initEcharts = () => {
    chartDom.value = echarts.init(document.getElementById('echartsDom'));
    chartDom.value.on('click',function (params) {
        console.log('点击',params)
        // 点击省区域,下钻
        if(params.data.level === 'province') {
            curProvince = {
                name: params.name,
                adcode: params.value
            }
            initMap('city');
            return;
        }
        message.warning('已经是最后一层');
    })
}

// 初始化地图
const initMap = (fileName) => {
    // JSON文件(地图数据)路径
    let dataURL = `GeoJSON/${fileName}.json`;
    // 引入JSON文件
    fetch(dataURL).then((res) => res.json()).then((geoJson) => {
        chartDom.value.clear();
        let registerGeoJSON = fileName === 'city' ? getCitys(geoJson) : geoJson;
        // 注册地图名字(fileName)和数据(registerGeoJSON)
        echarts.registerMap(fileName, registerGeoJSON);

        let regions = dataFormat(registerGeoJSON);
        console.log('regions',regions);
        
        if(!regions) return;
        let colorOptions = {
            environment: '#ccc', // 环境背景颜色
            borderColor: '#787c80', // 区域边界颜色
            labelColor: '#000', // 区域名称颜色
            hoverLabelColor: '#6c6f73' // 鼠标划入区域高亮颜色
        }

        let options = {
            series: [
                {
                    type: 'map3D',
                    map: fileName,// 注册的地图名字
                    shading: 'realistic', 
                    environment: colorOptions.environment,
                    itemStyle: {
                        borderColor: colorOptions.borderColor,
                        borderWidth: 1
                    },
                    label: {
                        show: true,
                        formatter: '{b} ', // 加个空格,否则不会直接显示name
                        textStyle: {
                            color: colorOptions.labelColor
                        }
                    },
                    emphasis: { // 鼠标hover高亮时区域颜色
                        itemStyle: {
                            color: colorOptions.hoverLabelColor,
                            opacity: .8
                        }
                    },
                    viewControl: { // 视角距离主体的距离
                        distance: fileName == 'city' ? 200 : 100
                    },
                    instancing: true,
                    boxWidth: 200,
                    boxHeight: 1,
                    data: regions
                }
            ]
        }
        
        options && chartDom.value.setOption(options);
    })
}

// 返回echarts展示数据格式
const dataFormat = (geoJson) => {
    return (geoJson.features || []).map((feature) => {
        return {
            name: feature.properties.name,
            value: feature.properties.adcode,
            level: feature.properties.level //自定义层级标识
        };
    });
}

// 获取当前省的市级数据
const getCitys = (geoJson) => {
    let cityArr = geoJson.features.filter(feature => {
        return feature.properties?.parent?.adcode === curProvince.adcode;
    });
    return {
        features: cityArr
    }
}

</script>

<style lang="less" scoped>
#echartsDom {
    width: 100%;
    height: 100%;
}
</style>

 四、补充H5无法点击的Bug: 

问题描述:

        关于H5端无法触发点击事件的问题,在github上查阅了相关问题,发现是普遍存在的,源码上的缺陷。

解决方案:

github关于此问题的讨论https://github.com/apache/echarts/issues/9906

修改源码,将文件 node_modules\zrender\lib\dom\HandlerProxy.js 中的一行代码注释掉: 

 H5端即可实现正常点击:

附:修改源码较好的方式:

通过patch-package补丁修改node_modules包文件-CSDN博客

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值