Echarts加载2D地图
echarts除了可以实现基础的图标数据可视化渲染,还可以实现地图的可视化渲染。包括中国地图、行政区域、街道等等。普通Echart只能画出省市区的的地图不能提供具体的街道、镇级数据。
本案列在设计的过程中采用html+css的代码来设计,如果要在框架中使用,可以自行改造。
我们先将echarts的环境搭建好,并下载对应需要包。
整体运行的效果图如下:
源代码开源:有需要请联系博主
一、创建项目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
效果如下:
你可以在datav里面选择你要的区域,并获取对应的json数据
五、封装请求获取数据
根据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这个配置项需要我们着重研究
代码结构如下:
对应的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
}]
}
效果如下:
七、option配置的详细解析
(1)tooltip提示框组件
这个组件可以实现,鼠标移入到图表中,实现数据提示框展示。
配置如下:
//整个图表的背景颜色,这个根据自己需求来决定是否需要配置
backgroundColor: "#90c7f5",
//提示框组件配置
tooltip: {
//提示框组件的背景颜色
backgroundColor: "#062444",
//提示框组件的边框颜色
borderColor: "#ff2b73",
//触发事件,填写事件名字 比如:mousemove、click等等
triggerOn: 'mousemove',
//鼠标是否可进入提示框浮层中,默认为false
enterable: false
},
这个配置完成后,我们可以当鼠标移入到地图中,你可以看到提示框组件
每个城市的提示框组件样式都是我们自己设置的样式。
当然你还可以设置更加复杂的提示框组件布局和样式。
自定义提示框组件配置代码如下:
tooltip: {
//提示框组件的背景颜色
backgroundColor: "#062444",
//提示框组件的边框颜色
borderColor: "#ff2b73",
//触发事件,填写事件名字 比如:mousemove、click等等
triggerOn: 'mousemove',
//鼠标是否可进入提示框浮层中,默认为false
enterable: false,
//自定义提示框组件
formatter: `<div style="color:pink;font-size:30px">模拟数据</div>`
},
效果如下:
官网还支持我们采用函数的形式来设置提示组件。
//提示框组件配置
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
表示城市的名字,数据为模拟数据,仅供参考参考。
效果如下:
(2)geo地理坐标系组件
我们整个地图其实有两层,geo可以配置一层地图,series也会配置一层地图。
geo:{},
series:{}
如果两个配置属性都存在的话,地图就出现了两层,下层地图有阴影效果,两层叠在一起我们可以看到之前地图的整体效果+阴影效果。
效果如下:
如果你只配置geo,不配置series的话,那地图效果如下
你会发现刚刚第二层地图就消失不见了。当然这个时候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配置后,我们看到的效果如下:
()series定义图表中的数据
当把series的所有配置定义好了过后,我们可以看到第二层地图,两层地图的大小是一致的,上层地图就覆盖了下层地图的显示。只能看到部分阴影效果。
对应的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格式
image2图片的效果如下:
(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)效果图
默认加载出来效果:
鼠标移入后的切换效果:替换了切换后显示的图片
九、事件绑定
我们可以给地图绑定事件来满足我们业务要求。
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",()=>{
})
实现的效果如下:
。。。持续更新细节。