meface/docs/article/visual/echarts_map.md

563 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: ECharts地图图表
date: 2021-04-06
author: ac
sticky: 3
tags:
- ECharts
- BMap
categories:
- 可视化
---
> 很多数据具有很强区域的属性,如果想从宏观的角度去分析在不同地区的对比情况,这时候就需要使用到地图了。
<!-- more -->
## 1. 简介
在`ECharts`中地图图表的使用方式有两种方式:
- 使用百度地图的API进行连网的在线展示
- 矢量地图,使用矢量数据(`geojson`)绘制地图
使用百度地图的API需要申请一个ak坐标系是百度的`BD09`
矢量地图图表使用的数据是`geojson`,坐标系是`WGS84`的地理坐标。
## 2. 矢量图表
### 2.1 数据获取
需要的`geojson`数据可以从 [地图选择器](http://datav.aliyun.com/tools/atlas/#&lat=30.332329214580188&lng=106.72278672066881&zoom=3.5) 中下载;
![image-20210406112712156](./images/image-20210406112712156.png)
### 2.2 绘制图形
绘制步骤:
1. 加载地图数据
2. 将`geojson`对象注册到`ECharts`的全局对象中
3. 配置地理坐标系组件
示例:
<VectorMap></VectorMap>
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入在线CDN echarts.js -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/echarts.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小宽高的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
fetch('/data/china.json').then(function(response){
return response.json();
}).then(function(result){
// console.log(result);
// 基于准备好的dom初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
//在echarts中注册地图矢量数据
echarts.registerMap('china',result);
// 指定图表的配置项和数据
var option = {
//配置地理坐标系组件
geo:{
type: 'map',
map: 'china',
roam: true, //设置允许缩放以及拖动的效果
label:{
show: true
},
zoom: 4, //初始化缩放比例
center: [113,23], //设置初始化中心点
itemStyle: { // 定义样式
areaColor: '#f4f1de', // 普通状态下的样式
borderColor: '#111'
},
emphasis: { // 高亮状态下的样式
itemStyle:{
areaColor: '#f5cac3'
},
label:{
color:'#000',
fontSize:14
}
}
}
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
});
</script>
</body>
</html>
```
### 2.3 常见效果
- 唯一值渲染根据name属性不同城市显示不同的颜色步骤
1. 准备数据,矢量数据`china.json`,城市空气质量数据`airData`。
2. 显示基本的中国地图
3. 将城市空气质量数据设置给series
4. 设置`geoIndex`和`type` 将series下的数据和geo关联起来
5. 结合`visualMap`配合使用,达到过滤的效果
示例:
<UniqueRender></UniqueRender>
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入在线CDN echarts.js -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/echarts.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小宽高的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
let airData = [
{ name: '北京市', value: 39.92 },
{ name: '天津市', value: 39.13 },
{ name: '上海市', value: 31.22 },
{ name: '重庆市', value: 66 },
{ name: '河北省', value: 147 },
{ name: '河南省', value: 113 },
{ name: '云南省', value: 25.04 },
{ name: '辽宁省', value: 50 },
{ name: '黑龙江省', value: 114 },
{ name: '湖南省', value: 175 },
{ name: '安徽省', value: 117 },
{ name: '山东省', value: 92 },
{ name: '新疆维吾尔自治区', value: 84 },
{ name: '江苏省', value: 67 },
{ name: '浙江省', value: 84 },
{ name: '江西省', value: 96 },
{ name: '湖北省', value: 273 },
{ name: '广西壮族自治区', value: 59 },
{ name: '甘肃省', value: 99 },
{ name: '山西省', value: 39 },
{ name: '内蒙古自治区', value: 58 },
{ name: '陕西省', value: 61 },
{ name: '吉林省', value: 51 },
{ name: '福建省', value: 29 },
{ name: '贵州省', value: 71 },
{ name: '广东省', value: 38 },
{ name: '青海省', value: 57 },
{ name: '西藏自治区', value: 24 },
{ name: '四川省', value: 58 },
{ name: '宁夏回族自治区', value: 52 },
{ name: '海南省', value: 54 },
{ name: '台湾省', value: 88 },
{ name: '香港特别行政区', value: 66 },
{ name: '澳门特别行政区', value: 77 },
{ name: '南海诸岛', value: 55 }
];
fetch('/data/china.json').then(function(response){
return response.json();
}).then(function(result){
console.log(result);
// 基于准备好的dom初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
//在echarts中注册地图矢量数据
echarts.registerMap('china',result);
// 指定图表的配置项和数据
var option = {
//配置地理坐标系组件
geo:{
type: 'map',
map: 'china',
roam: true, //设置允许缩放以及拖动的效果
label:{
show: false,
fontSize: 10
},
// zoom: 4, //初始化缩放比例
center: [108.948024,34.263161] //设置初始化中心点
},
series: [
{
data: airData,
geoIndex: 0, // 将空气质量的数据和第0个geo配置关联在一起
type: 'map'
}
],
visualMap: {
min: 0,
max: 300,
inRange: {
symbolSize: [30, 100],
color: ['white', 'red'] // 控制颜色渐变的范围
},
calculable: true // 出现滑块
}
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
});
</script>
</body>
</html>
```
- 地图与散点图结合,即在一个`echarts`实例里面绘制多个图表,所以在`series`数组里面增加一个元素,且类型`type`为`effectScatter`。
1. 给`series`下增加新的对象
2. 准备好散点数据设置给新的对象data
3. 配置新对象的type为`effectScatter`
4. 让散点图使用地理坐标系统:`coordinateSystem: 'geo'`
5. 让涟漪的效果更加明显`rippleEffect:{scale:10}`
<ScatterCharts></ScatterCharts>
```javascript
let airData = [
{ name: '北京市', value: 39.92 },
{ name: '天津市', value: 39.13 },
{ name: '上海市', value: 31.22 },
{ name: '重庆市', value: 66 },
{ name: '河北省', value: 147 },
{ name: '河南省', value: 113 },
{ name: '云南省', value: 25.04 },
{ name: '辽宁省', value: 50 },
{ name: '黑龙江省', value: 114 },
{ name: '湖南省', value: 175 },
{ name: '安徽省', value: 117 },
{ name: '山东省', value: 92 },
{ name: '新疆维吾尔自治区', value: 84 },
{ name: '江苏省', value: 67 },
{ name: '浙江省', value: 84 },
{ name: '江西省', value: 96 },
{ name: '湖北省', value: 273 },
{ name: '广西壮族自治区', value: 59 },
{ name: '甘肃省', value: 99 },
{ name: '山西省', value: 39 },
{ name: '内蒙古自治区', value: 58 },
{ name: '陕西省', value: 61 },
{ name: '吉林省', value: 51 },
{ name: '福建省', value: 29 },
{ name: '贵州省', value: 71 },
{ name: '广东省', value: 38 },
{ name: '青海省', value: 57 },
{ name: '西藏自治区', value: 24 },
{ name: '四川省', value: 58 },
{ name: '宁夏回族自治区', value: 52 },
{ name: '海南省', value: 54 },
{ name: '台湾省', value: 88 },
{ name: '香港特别行政区', value: 66 },
{ name: '澳门特别行政区', value: 77 },
{ name: '南海诸岛', value: 55 }
];
let scatterData = [
// { name: '成都', value: [104.06, 30.67] },
// { name: '重庆', value: [106.54, 29.59] },
// { name: '杭州', value: [120.19, 30.26] },
// { name: '武汉', value: [114.31, 30.52] },
// { name: '西安', value: [108.95, 34.27] },
// { name: '天津', value: [117.2, 39.13] },
// { name: '苏州', value: [120.62, 31.32] },
// { name: '南京', value: [118.78, 32.04] },
// { name: '郑州', value: [113.65, 34.76] },
// { name: '长沙', value: [113, 28.21] },
{ name: '东莞', value: [113.75, 23.04] },
// { name: '沈阳', value: [123.38, 41.8] },
// { name: '青岛', value: [120.33, 36.07] },
// { name: '合肥', value: [117.27, 31.86] },
// { name: '佛山', value: [113.11, 23.05] },
];
fetch('/data/china.json').then(function (response) {
return response.json();
}).then(function (result) {
console.log(result);
// 基于准备好的dom初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
//在echarts中注册地图矢量数据
echarts.registerMap('china', result);
// 指定图表的配置项和数据
var option = {
//配置地理坐标系组件
geo: {
type: 'map',
map: 'china',
roam: true, //设置允许缩放以及拖动的效果
label: {
show: false,
fontSize: 10
},
zoom: 4, //初始化缩放比例
center: [113.75, 23.04] //设置初始化中心点
},
series: [
{
data: airData,
geoIndex: 0, // 将空气质量的数据和第0个geo配置关联在一起
type: 'map'
}, {
// 配置散点的坐标数据
data: scatterData,
type: 'effectScatter',
// 指明散点使用的坐标系统 geo的坐标系统
// 可选值:'cartesian2d'、'polar'、'geo'、'bmap'
coordinateSystem: 'geo',
rippleEffect: {
color: '#ccc',//涟漪动画的颜色
scale: 3 // 设置涟漪动画的缩放比例
},
// symbolSize:[10,20],
// showEffectOn: 'emphasis',
label:{
color: '#219ebc',
show: true,
formatter:function(row){
return row.name;
}
},
itemStyle:{
color: '#ccc'
}
}
],
visualMap: {
min: 0,
max: 300,
inRange: {
symbolSize: [30, 100],
color: ['white', 'red'] // 控制颜色渐变的范围
},
calculable: true // 出现滑块
}
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
});
```
看起来效果不佳,因为同时配置了`visualMap`参数,影响了一些参数的表现,如`symbolSize``itemStyle`等。
## 3. 结合百度地图
> 百度地图很多API都需要连网使用如果是一些简单的数据加载、图标绘制、控件等在客户端就可以完成的可以不需要网络但对于百度地图提供的一些接口、服务类像地理编码、POI 查询、出行路线规划等需要服务端处理并返回结果。
### 3.1 ak与坐标
首先需要在[百度开发平台](http://lbsyun.baidu.com/index.php) 上用百度账号[创建应用](http://lbsyun.baidu.com/index.php?title=jspopularGL/guide/getkey)获取ak。
目前国内主要有以下三种坐标系:
- WGS84为一种大地坐标系也是目前广泛使用的GPS全球卫星定位系统使用的坐标系。
- GCJ02又称火星坐标系是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。
- BD09为百度坐标系在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标bd09mc表示百度墨卡托米制坐标。
非中国地区地图服务坐标统一使用WGS84坐标。
> 百度官方提供了其他坐标系与BD09的坐标转换接口
### 3.2 基础配置
`ECharts`中使用百度地图还需要引入`echarts`对百度地图的扩展包`bmap.js`
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入在线CDN echarts.js -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/echarts.js"></script>
<!-- 引入百度地图API-->
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=<Your Key Here>"></script>
<!-- 引入echarts百度地图扩展包-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js"></script>
<style>
html,
body {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<!-- 为ECharts准备一个具备大小宽高的Dom -->
<div id="main" style="width: 100%;height:100%;"></div>
<script type="text/javascript">
var bmapChart = echarts.init(document.getElementById('main'));
var option = {
bmap: {
center: [113.9702, 22.47971], // 中心位置坐标
zoom: 12, // 地图缩放比例
roam: true // 开启用户缩放
}
}
bmapChart.setOption(option);
</script>
</body>
</html>
```
`ECharts`将百度地图部分配置集成在了bmap中包括
| 参数 | 说明 | 格式 |
| -------- | -------------------- | ------------------------------------- |
| center | 中心点的百度坐标 | 坐标数组, 如:[116.307698, 40.056975] |
| zoom | 初始缩放比 | number |
| roam | 是否允许用户缩放操作 | boolean |
| mapStyle | 地图自定义样式 | object, 如:{ styleJson: [...] } |
![3133](./images/3133.png)
### 3.3 百度地图主题
`echarts`通过`bmap`在内部已经创建了一个百度地图的实例,如果想在地图添加控件或修改样式,需要先获取内部的地图实例:
```javascript
// 通过echarts实例获取地图实例的方法
var bmap = bmapChart.getModel().getComponent('bmap').getBMap();
//修改样式
//百度提供的样式有normal、light、dark、redalert、googlelite、
//grassgreen、midnight、pink、darkgreen、bluish、grayscale、hardedge
bmap.setMapStyle({style:'midnight'});
//添加控件
bmap.addControl(new BMap.NavigationControl());
```
[百度地图个性化模板列表](http://lbsyun.baidu.com/custom/list.htm)
![5838085](./images/5838085.png)
### 3.3 绘制散点图
跟矢量地图类似提供一个series但`coordinateSystem`参数需要配置为`bmap`。
完整代码:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入在线CDN echarts.js -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/echarts.js"></script>
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=<Your Key Here>"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js"></script>
<style>
html,body {width: 100%;height: 100%;}
</style>
</head>
<body>
<!-- 为ECharts准备一个具备大小宽高的Dom -->
<div id="main" style="width: 100%;height:100%;"></div>
<script type="text/javascript">
//新一线城市,坐标不对,这里只是演示效果
let scatterData = [
{ name: '成都', value: [104.06, 30.67] },
{ name: '重庆', value: [106.54, 29.59] },
{ name: '杭州', value: [120.19, 30.26] },
{ name: '武汉', value: [114.31, 30.52] },
{ name: '西安', value: [108.95, 34.27] },
{ name: '天津', value: [117.2, 39.13] },
{ name: '苏州', value: [120.62, 31.32] },
{ name: '南京', value: [118.78, 32.04] },
{ name: '郑州', value: [113.65, 34.76] },
{ name: '长沙', value: [113, 28.21] },
{ name: '东莞', value: [113.75, 23.04] },
{ name: '沈阳', value: [123.38, 41.8] },
{ name: '青岛', value: [120.33, 36.07] },
{ name: '合肥', value: [117.27, 31.86] },
{ name: '佛山', value: [113.11, 23.05] },
];
let bmapChart = echarts.init(document.getElementById('main'));
let option = {
bmap: {
center: [108.95, 34.27], // 中心位置坐标
zoom: 5, // 地图缩放比例
roam: true // 开启用户缩放
},
series: [{
// 配置散点的坐标数据
data: scatterData,
type: 'effectScatter',
// 指明散点使用的坐标系统 geo的坐标系统
// 可选值:'cartesian2d'、'polar'、'geo'、'bmap'
coordinateSystem: 'bmap',
rippleEffect: {
color: '#ccc',//涟漪动画的颜色
scale: 3 // 设置涟漪动画的缩放比例
},
symbolSize: 20,
showEffectOn: 'render',
label: {
color: '#219ebc',
show: true,
formatter: function (row) {
return row.name;
}
},
itemStyle: {
color: '#ccc'
}
}]
}
bmapChart.setOption(option);
// 通过echarts实例获取地图实例的方法
let bmap = bmapChart.getModel().getComponent('bmap').getBMap();
//修改样式
//百度提供的样式有normal、light、dark、redalert、googlelite、
//grassgreen、midnight、pink、darkgreen、bluish、grayscale、hardedge
bmap.setMapStyle({ style: 'midnight' });
//添加控件
bmap.addControl(new BMap.NavigationControl());
</script>
</body>
</html>
```
![image-20210407102942158](./images/image-20210407102942158.png)
## 参考文章
[1] ECharts 实现地图散点图(下) https://efe.baidu.com/blog/echarts-map-tutorial-2/
[2] 坐标转换 http://lbsyun.baidu.com/index.php?title=jspopular/guide/coorinfo