Echarts中国地图三级钻取

我的原创地址:https://dongkelun.com/2018/11/27/echartsChinaMap/

前言

最近其实一直在用Echarts写前端,之前也想过总结一下Echarts的用法,但是官网的例子已经很全了。写这篇博客是因为Echarts官网把很多地图的例子都去掉了,且不能下载地图Json的数据,而相关的博客又很少,搜到两个,但是不很符合自己的想法,所以就想自己实现总结一下最基本的地图钻取,代码上传到GitHub,这样便于后面再有相关需求的时候,直接从GitHub上下载下来,在这个基础上修改添加功能就好了。

1、演示地址

暂时在没有下级地图的时候会直接返回到第一级中国地图,后面可能改为:提示没有下级地图,然后增加一个回到一级地图的按钮

http://front-end.dongkelun.com/echarts-map

2、动图演示

一张一张的截图,图片太多了,就先学了一下录制gif

Echarts中国地图三级钻取

3、代码

其中地图的json数据是同事之前下载的(可能不全,几个没用的Json没有去掉),在别人的GitHub上也可以找到

代码已上传到GitHub:https://github.com/dongkelun/echarts-map

4、部署

本项目为静态网页,但由于需要获取.json文件的数据,所以不能直接打开index.html(会报js的错误,可以自己试试)

将本项目复制到服务器下,如tomcat的webapps目录下,启动tomcat,然后在浏览器里输入http://localhost:8080/echarts-map即可

因为自己在学Vue,后面可能会用Vue重新实现一下,并添加一些相对复杂的功能,比如添加数据,使每个省的颜色不一样,更多样化一些。
之所以没有先用Vue实现,也没有实现比较复杂的效果,是因为考虑到不是每个人都会Vue,所以用最简单的静态html+css+js实现,这样能使每个人都能看懂,而且可以最基础的地图钻取的模版。后面如果用Vue实现的话,会新建一个项目并上传到GitHub,并及时更新本博客。

附录

附上核心代码:

index.html


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Echarts 地图钻取</title>
    <link rel="shortcut icon" href=./favicon.ico>
    <link rel="stylesheet" href="./css/index.css" type="text/css">
    <script type="text/javascript" src="./js/echarts.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
    <script type="text/javascript" src="./js/index.js"></script>
    <script type="text/javascript" src="./js/china-main-city-map.js"></script>
    <script type="text/javascript" src="./js/rem.js"></script>
  </head>
  <body>

    <div class='title'>Echarts中国地图三级钻取</div>
    <div class="box">
      <button class= "backBtn" onclick="back()">返回上级</button>
      <div id="mapChart" class="chart"></div>
    </div>

  </body>
  
</html>

index.css


body{
    background-image: url('../asset/images/beijingtupian.png');
}

.title{

    width: 100%;
    height: 10vh;
    text-align: center;
    color:#fff;
    font-size: 2em;
    line-height: 10vh;
}
.box {

    position: absolute;
    width: 90%;
    height: 80vh;
    left:5%;
    top:10%;
    background-color:rgba(24,27,52,0.62);
}

.chart{
	position: relative;
	height: 90%;
	top:10%;
}
.backBtn{
    position: absolute;
    top:0;
    background-color: #00C298;
    border: 0;
    color:#fff;
    height: 27px;
    font-family: Microsoft Yahei;
    font-size: 1em;
    cursor: pointer;
}


index.js

$(function() {//dom加载后执行
    mapChart('mapChart')
})



/**
 * 根据Json里的数据构造Echarts地图所需要的数据
 * @param {} mapJson 
 */
function initMapData(mapJson){
    var mapData = [];
    for( var i=0;i<mapJson.features.length;i++ ){
        mapData.push({
            name:mapJson.features[i].properties.name,
            //id:mapJson.features[i].id
        })
    }
    return mapData;    
}

/**
 * 返回上一级地图
 */
function back(){
    if(mapStack.length!=0){//如果有上级目录则执行
        var map = mapStack.pop();
        $.get('./asset/json/map/'+map.mapId+'.json', function (mapJson,status) {
                
            registerAndsetOption(myChart,map.mapId,map.mapName,mapJson,false)

            //返回上一级后,父级的ID、Name随之改变
            parentId = map.mapId;
            parentName = map.mapName;
            
        })

    }
    
}
/**
 * Echarts地图
 */

//中国地图(第一级地图)的ID、Name、Json数据
 var chinaId = 100000;
 var chinaName = 'china'
 var chinaJson = null;
 
 //记录父级ID、Name
 var mapStack = [];
 var parentId = null;
 var parentName = null;

 //Echarts地图全局变量,主要是在返回上级地图的方法中会用到
 var myChart = null;
 function mapChart(divid){
   
    $.get('./asset/json/map/'+chinaId+'.json', function (mapJson) {
        chinaJson = mapJson;
        myChart = echarts.init(document.getElementById(divid));
        registerAndsetOption(myChart,chinaId,chinaName,mapJson,false)
        parentId = chinaId;
        parentName = 'china'
        myChart.on('click', function(param,t) {

            var cityId = cityMap[param.name]
            if(cityId){//代表有下级地图
                $.get('./asset/json/map/'+cityId+'.json', function (mapJson,status) {
                    registerAndsetOption(myChart,cityId,param.name,mapJson,true)
                })
            }else{
                //没有下级地图,回到一级中国地图,并将mapStack清空
                registerAndsetOption(myChart,chinaId,chinaName,chinaJson,false)
                mapStack=[]
                parentId = chinaId;
                parentName = chinaName;
                

            }
            // $.get('./asset/json/map/'+param.data.id+'.json', function (mapJson,status) {
               
            //     registerAndsetOption(myChart,param.data.id,param.name,mapJson,true)
        
            // }).fail(function () {
            //     registerAndsetOption(myChart,chinaId,'china',chinaJson,false)
            // });

        });
    
    
    })
}

/**
 * 
 * @param {*} myChart 
 * @param {*} id        省市县Id
 * @param {*} name      省市县名称
 * @param {*} mapJson   地图Json数据
 * @param {*} flag      是否往mapStack里添加parentId,parentName
 */
function registerAndsetOption(myChart,id,name,mapJson,flag)
{
    
    echarts.registerMap(name, mapJson);
    myChart.setOption({
        series: [{
            type: 'map',
            map: name,
            itemStyle: {
                normal: {
                    areaColor: 'rgba(23, 27, 57,0)',
                    borderColor: '#1dc199',
                    borderWidth: 1,
                },
            },
            data:initMapData(mapJson)
        }]
    });

    if(flag){//往mapStack里添加parentId,parentName,返回上一级使用
        mapStack.push({
            mapId: parentId,
            mapName: parentName
        }); 
        parentId = id;
        parentName = name;
    }
}