Echarts加载2D地图(图文)

Echarts加载2D地图

echarts除了可以实现基础的图标数据可视化渲染,还可以实现地图的可视化渲染。包括中国地图、行政区域、街道等等。普通Echart只能画出省市区的的地图不能提供具体的街道、镇级数据。

本案列在设计的过程中采用html+css的代码来设计,如果要在框架中使用,可以自行改造。

我们先将echarts的环境搭建好,并下载对应需要包。

整体运行的效果图如下:

源代码开源:有需要请联系博主

image-20230916172227258

一、创建项目Echarts2DMap

进行初始化项目,这一步目的生成package.json,方便我们本地下载依赖

npm init -y

这一步的目的是为了初始化项目,并准备下载依赖包。

二、下载需要依赖包

echarts依赖包下载:

npm i axios@5.4.2

axios依赖包的下载

npm i axios

下载axios包的目的是为了方便我们后续动态获取地图的json数据。

三、基础代码结构

先将echarts的基础代码结构搭建好。

其中option的配置我们可以暂时不用,如果你要显示的是echarts官方的图标,你只需去echarts官网找到对应option的配置,复制给option对象就可以实现了。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./node_modules/echarts/dist/echarts.min.js"></script>
    <script src="./node_modules/axios/dist/axios.min.js"></script>
</head>

<body>
    <div id="map" style="height: 100%;width: 100%"></div>
    <script>
        var dom = document.getElementById("chart-panel");
        var myChart = echarts.init(dom);
        const option = {
            //配置内容,在后面详细讲解
        }
        myChart.setOption(option)
    </script>
</body>

</html>

四、获取地图json数据

Echarts 的地图绘制是基于 SVG 或 Canvas 技术实现的。如果你要绘制指定的地图区域。你需要告诉echarts区域范围和值。

地址:https://datav.aliyun.com/portal/school/atlas/area_selector

效果如下:

image-20230906112857235

你可以在datav里面选择你要的区域,并获取对应的json数据

image-20230906113037086

五、封装请求获取数据

根据datav的地图选项,获取到你想要的地图格式后,我们能得到对应的json数据

你可以下载json数据并放在代码中,也可以根据网络请求来获取json数据

<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
   <script src="./node_modules/echarts/dist/echarts.min.js"></script>
   <script src="./node_modules/axios/dist/axios.min.js"></script>
</head>

<body>
   <div id="map" style="height: 100vh;width: 100%"></div>
   <script>
       // (1)初始化容器
       var dom = document.getElementById("map");
       var myChart = echarts.init(dom);

       // (2)发送异步请求获取数据
       async function fetchData() {
           //获取地图的json数据
         	const url = "https://geo.datav.aliyun.com/areas_v3/bound/510000_full.json"
           const { data } = await axios.get(url)
           console.log(data);
           //注册echarts地图数据
           echarts.registerMap('map', data, {});
       }
       fetchData()
   </script>
</body>

</html>

echarts.registerMap 是 Echarts 中用于注册自定义地图的 API。它允许你将自定义的地图数据注册到 Echarts 中,以便在图表中使用该地图。

参数解析如下:

参数一(mapName):注册的地图名称,作为地图的唯一标识符,之后在图表配置项中可以使用该名称来引用这个地图

参数二(geoJson):地图的 GeoJSON 数据,可以是一个包含地图边界和区域坐标信息的 JavaScript 对象。通常来说,你需要提前获取或准备一个符合 GeoJSON 格式的地图数据。

参数三(可选):注册地图时,可以指定特定的区域样式配置。它是一个数组,每个元素是一个对象,表示一个特定区域的样式配置。例如,你可以设置某个特定区域的颜色或边界样式

这个地图注册后,后续在地图数据渲染的时候,会调用

// 在图表配置项中使用注册的地图
var option = {
  series: [{
    type: 'map',
    map: '',
    // 其他图表配置项...
  }]
};

六、配置option

option的配置就是参考echarts官方文档的配置。其中geo这个配置项需要我们着重研究

代码结构如下:

image-20230906121736252

对应的option配置数据如下:

const option = {
  backgroundColor: "#99d7f5",
  tooltip: {
    backgroundColor: "#062444",
    borderColor: "#ff2b73",
    triggerOn: 'mousemove', //click
    enterable: true,
  },
  geo: {
    show: true,
    aspectScale: 0.95, //地图长度比
    zoom: 1.1,
    map: 'map',
    label: {
      normal: {
        show: false
      },
      emphasis: {
        show: false,
      }
    },
    roam: false, //地图设置不可拖拽,固定的
    itemStyle: {
      // normal: {
      // 	areaColor: '#00406b',
      // 	borderWidth: 1,
      // 	shadowColor: '#00406b',
      // 	shadowBlur: 100,
      // }
      normal: {
        areaColor: '#7ef2ff',
        shadowColor: '#fff',
        shadowOffsetX: -6,
        shadowOffsetY: 6,
        shadowBlur: 12,
      },
      emphasis: {
        show: false,
        areaColor: '#00684d',
        borderWidth: 0,
        color: '',
        label: {
          show: false
        }
      }
    }
  },
  series: [{
    select: {
      label: {
        color: '#fff'
      },
      itemStyle: { //选择后的样式
        borderColor: '#a5f2fc',
        borderWidth: 1,
        color: '#267df2', //设置地图点击后的颜色
        shadowColor: "#00684d", //阴影颜色
        shadowBlur: 10, //阴影浓度
      }
    },
    name: '',
    itemStyle: {
      normal: { //未选中状态
        borderWidth: 1, //边框大小
        borderColor: '#a5f2fc',
        areaColor: '#267df2', //背景颜色
        label: {
          show: true, //显示名称
          formatter: function (params) {
            return params.name
          }
        },
        // shadowColor: `#00406b`,
        // shadowOffsetX: -20,
        // shadowOffsetY: 10,
        // shadowBlur: 20
      },
      emphasis: { // 移动样式
        borderWidth: 1,
        borderColor: '#a5f2fc',
        shadowColor: "rgba(0,0,0,.6)", //阴影颜色
        shadowBlur: 10, //阴影浓度
        areaColor: '#267df2',
        label: {
          show: true,
          textStyle: {
            color: '#fff'
          }
        }
      }
    },
    type: 'map',
    mapType: 'map',
    aspectScale: 0.95, //地图长度比
    zoom: 1.1,
    label: {
      normal: {
        show: true,
        textStyle: {
          color: '#000',
          fontSize: 12,
          fontWeight: 'bold'
        }
      },
      emphasis: {
        show: true,
        textStyle: {
          color: '#fff'
        }
      }
    },
    // data: dataArr
  }]
}

效果如下:

image-20230916121735517

七、option配置的详细解析

(1)tooltip提示框组件

这个组件可以实现,鼠标移入到图表中,实现数据提示框展示。

配置如下:

//整个图表的背景颜色,这个根据自己需求来决定是否需要配置
backgroundColor: "#90c7f5",
//提示框组件配置
tooltip: {
  //提示框组件的背景颜色
  backgroundColor: "#062444",
  //提示框组件的边框颜色
  borderColor: "#ff2b73",
  //触发事件,填写事件名字 比如:mousemove、click等等
  triggerOn: 'mousemove',
  //鼠标是否可进入提示框浮层中,默认为false
  enterable: false
},

这个配置完成后,我们可以当鼠标移入到地图中,你可以看到提示框组件

每个城市的提示框组件样式都是我们自己设置的样式。

image-20230916141522723

当然你还可以设置更加复杂的提示框组件布局和样式。

自定义提示框组件配置代码如下:

tooltip: {
  //提示框组件的背景颜色
  backgroundColor: "#062444",
  //提示框组件的边框颜色
  borderColor: "#ff2b73",
  //触发事件,填写事件名字 比如:mousemove、click等等
  triggerOn: 'mousemove',
  //鼠标是否可进入提示框浮层中,默认为false
  enterable: false,
  //自定义提示框组件
  formatter: `<div style="color:pink;font-size:30px">模拟数据</div>`
},

效果如下:

image-20230916141721525

官网还支持我们采用函数的形式来设置提示组件。

//提示框组件配置
tooltip: {
  //提示框组件的背景颜色
  backgroundColor: "#062444",
  //提示框组件的边框颜色
  borderColor: "#ff2b73",
  //触发事件,填写事件名字 比如:mousemove、click等等
  triggerOn: 'mousemove',
  //鼠标是否可进入提示框浮层中,默认为false
  enterable: false,
  // formatter: `<div style="color:pink;font-size:30px">模拟数据</div>`
  formatter: function (params) { //用于显示多个数据
    console.log(params);
    tipHtml = `
      <div style="background-color:#062444;color:#fff;display:flex;align-items:center;font-size:14px;">
      <img src=""/>
      <div style="margin-left:10px;">
      <div style="color:#ff2b73;font-weight:600;">地区人口数量:${10}w</div>
      <div style="font-weight:600;">地区名字:${params.name}</div>
      </div>
      </div>
		`
    return tipHtml;
  }
},

其中函数params属性可以获取到当前这个城市的基础信息。params.name表示城市的名字,数据为模拟数据,仅供参考参考。

效果如下:

image-20230916142022506

(2)geo地理坐标系组件

我们整个地图其实有两层,geo可以配置一层地图,series也会配置一层地图。

geo:{},
series:{}

如果两个配置属性都存在的话,地图就出现了两层,下层地图有阴影效果,两层叠在一起我们可以看到之前地图的整体效果+阴影效果。

效果如下:

image-20230916151540807

如果你只配置geo,不配置series的话,那地图效果如下

image-20230916151747098

你会发现刚刚第二层地图就消失不见了。当然这个时候tooltip的配置也无法生效。

geo的配置如下:

geo: {
  //是否显示地理坐标系组件
  show: true,
  //这个参数用于 scale 地图的长宽比
  aspectScale: 0.95,
  //当前视角的缩放比例,地图有两层,主要控制下层
  zoom: 1.1,
  //使用 registerMap 注册的地图名称。
  map: 'map',
  //图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
  label: {
   	//默认的文本是否显示,可以显示地图上区域名字
    normal: {
      show: true
    },
    //高亮的文本是否显示,鼠标移入后显示
    emphasis: {
      show: true,
    }
  },
  //地图设置不可拖拽,固定的
  roam: false, 
  // 地图区域的多边形 图形样式。
  itemStyle: {
    //基础配置
    normal: {
      //区域颜色
      areaColor: '#7ef2ff',
      //区域阴影效果
      shadowColor: '#fff',
      //阴影的x轴偏移量
      shadowOffsetX: -6,
      //阴影的y轴偏移量
      shadowOffsetY: 6,
      //图形阴影的模糊大小
      shadowBlur: 12,
    },
    //高亮状态下的多边形和标签样式,也就是鼠标移入后效果
    emphasis: {
      // 鼠标移入后的颜色效果
      areaColor: '#00684d',
      //鼠标移入后,区域模块的边框大小
      borderWidth: 10,
    }
  }
},

根据上面geo配置后,我们看到的效果如下:

image-20230916152650048

()series定义图表中的数据

当把series的所有配置定义好了过后,我们可以看到第二层地图,两层地图的大小是一致的,上层地图就覆盖了下层地图的显示。只能看到部分阴影效果。

image-20230916160333484

对应的series的配置如下

series: [{
  //数据选中时的图形样式和标签样式
  select: {
    //选择后的文本样式
    label: {
      color: '#fff'
    },
    //选择后的样式其他样式
    itemStyle: { 
      //边框颜色
      borderColor: '#a5f2fc',
      //边框大小
      borderWidth: 0,
      //设置地图点击后的颜色
      color: 'red', 
      //阴影颜色
      shadowColor: "#00684d", 
      //阴影浓度
      shadowBlur: 10, 
    }
  },
  //系列名称,用于tooltip的显示,legend 的图例筛选,目前我们没有用到图例
  name: '',
  //图形样式
  itemStyle: {
    //未选中状态
    normal: {
      //边框大小
      borderWidth: 1, 
      borderColor: '#a5f2fc',
      //背景颜色
      areaColor: '#267df2', 
      label: {
        //显示名称
        show: true,
        //根据地图数据,显示每个区域的名字
        formatter: function (params) {
          return params.name
        }
      },
    },
    // 鼠标移动样式后的样式
    emphasis: { 
      borderWidth: 1,
      borderColor: '#a5f2fc',
      //阴影颜色
      shadowColor: "rgba(0,0,0,.6)", 
      //阴影浓度
      shadowBlur: 10, 
      //区域颜色
      areaColor: '#267df2',
      //文本样式
      label: {
        show: false,
        textStyle: {
          color: '#fff'
        }
      }
    }
  },
  //颜色的图表类型
  type: 'map',
  mapType: 'map',
  //地图长度比
  aspectScale: 0.95, 
  //地图的缩放级别
  zoom: 1.1,
  label: {
    normal: {
      show: true,
      textStyle: {
        color: '#000',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    emphasis: {
      show: true,
      textStyle: {
        color: '#fff',
        fontSize: 18,
      }
    }
  }
}]

八、地图贴图

目前地图显示出来的效果默认是2d平面,并切没有地势位置的渲染效果。如果要模拟真实的地图山地效果,我们需要给地图进行贴图显示。默认也就是把地图对应的地形图片,引入并加载到地图中

因为有两层地图,我们默认给最上层的地图贴图,这样才不会被遮挡

(1)image目录下面引入图片

在项目的image目录下面引入你需要的地形图。图片可以自己去百度、chrome地图寻找,或者UI设计师提供。

Image1图片效果如下:格式就是jpg格式

71693535066_.pic

image2图片的效果如下:

81693535067_.pic

(2)在代码中创建图片对象

因为echarts要求我们给地图贴图,必须提供HTMLImageElement, HTMLCanvasElement这种格式,不支持字符串路径,所有需要先创建图片节点

// (1)初始化容器
var dom = document.getElementById("map");
var myChart = echarts.init(dom);
//创建image1图片对象
const mapBg = document.createElement("img")
mapBg.src = "./image/71693535066_.pic.jpg"
//创建image2图片对象
const mapBg_2 = document.createElement("img")
mapBg_2.src = "./image/81693535067_.pic.jpg"

(3) 贴图

找到series这个配置项,并设置贴图

series: [{
  。。。省略其他配置             
  itemStyle: {
    normal: {
     	。。。省略其他配置
      // areaColor: '#267df2',
      areaColor: {
        image: mapBg, // 支持为 HTMLImageElement, HTMLCanvasElement,不支持路径字符串
        repeat: 'repeat' // 是否平铺, 可以是 'repeat-x', 'repeat-y', 'no-repeat'
      }
    },
    emphasis: {
      。。。省略其他配置
      // areaColor: '#267df2',
      areaColor: {
        // 支持为 HTMLImageElement, HTMLCanvasElement,不支持路径字符串
        image: mapBg_2,
        // 是否平铺, 可以是 'repeat-x', 'repeat-y', 'no-repeat'
        repeat: 'repeat'
      }
    }
  }                   
}]

其中核心的配置就是areaColor,之前我们默认设置的是颜色,现在换成图片。

mapBg就是第二个步骤中创建的图片对象,支持为 HTMLImageElement, HTMLCanvasElement,不支持路径字符串。

repeat 代表是否平铺

(4)效果图

默认加载出来效果:

image-20230916164201747

鼠标移入后的切换效果:替换了切换后显示的图片

image-20230916164232682

九、事件绑定

我们可以给地图绑定事件来满足我们业务要求。

ECharts 支持常规的鼠标事件类型,包括 'click''dblclick''mousedown''mousemove''mouseup''mouseover''mouseout''globalout''contextmenu' 事件

接下来我们要完成的业务是

点击其他城市正常显示人口和名字。点击成都市要显示不一样的文本和人口

代码如下

const option = {。。。省略代码}
myChart.setOption(option)
//添加事件绑定
//鼠标点击区块时,高亮且显示用户数
myChart.on('click', (e) => {
  //获取城市的名字
  console.log(e.name);
  if (e.componentSubType === 'map') {
    let tempOption = myChart.getOption();
    if (e.name == "成都市") {
      let obj = {
        //提示框组件的背景颜色
        backgroundColor: "pink",
        enterable: false,
        formatter: `<div style="color:yellow;font-size:30px">省会城市模拟人口1000</div>`
      }
      tempOption.tooltip = obj
      myChart.setOption(tempOption)
    }else{
      myChart.setOption(option)
    }
  }
})
//鼠标移出区块时,高亮且显示用户数
myChart.on("mouseout",()=>{

})

实现的效果如下:

image-20230916170628239

。。。持续更新细节。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值