ECharts 地图坐标系
移动互联网时代,地理位置信息已经成为许多商业决策的重要参考依据,基于地图的图表需求也随之日益增长。ECharts 提供了一套完备的地图坐标体系,配合地图能够实现非常丰富的图表,下面一起看看吧。
ECharts 中提供了两种格式的地图数据,一种是可以直接 script 引入的 js ,引入后会地图名字和数据。还有一种是 JSON ,需要通过 AJAX 异步加载后手动。
解释
某种程度上 ECharts 中的地图坐标系可以看做一种特殊直角坐标系,它将现实世界的地理平面映射为二维平面,通过经纬度系统实现坐标定位,通过线段按规则勾画出各个独立的地理、行政区域。在地图坐标系平面上,可以使用散点图、热力图、线图等图表类型。
在 ECharts 上,地理坐标系可通过 geo
配置,配置项列表可参考 ,本文结合实例讨论地理坐标系中需要理解的知识点。
由于地图过大,ECharts 3 之后已经不再内置地图数据,所以使用地理坐标系前,需要通过 echarts.registerMap
接口地理信息,实例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
< charset="utf-8" />
< http-equiv="X-UA-Compatible" content="IE=edge" />
< name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: px;height: px"></div>
<script src="//cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
async function run() {
const myChart = echarts.init(document.getElementById('main'));
const usaGeo = await axios.get('//cdn.jsdelivr.net/gh/VanMess/echart-wiki-examples@1.0.0/11_geo/USA.json');
echarts.registerMap('USA', usaGeo.data, {
Alaska: {
// 把阿拉斯加移到美国主大陆左下方
left: -,
top: ,
width: ,
},
Hawaii: {
left: -, // 夏威夷
top: ,
width: ,
},
'Puerto Rico': {
// 波多黎各
left: -,
top: ,
width: ,
},
});
const option = {
geo: { map: 'USA' },
series: [
{
type: 'scatter',
coordinateSy: 'geo',
data: [
[-, , ],
[-, , ],
[-, , ],
[-, , ],
],
symbolSize: function (val) {
return val[];
},
},
],
};
myChart.setOption(option);
}
run();
</script>
</body>
</html>
实例中,地理信息完毕后,就可以使用 series.geo.map
指定坐标系所使用的地理数据。
Tips:
地图信息数据通过 json 格式定义,可参考 ,echarts 曾提供各种地图信息的 ,但由于不符合国家《测绘法》规定,目前已经暂时停止下载服务。
地理坐标系上的 data 通常是三维数组,数组第一项指定经度;第二项指定维度;前两项确定坐标位置后,第三项则指明数据点上的值。上例:
地理坐标系中,与缩放相关的配置项:
由于地理信息数据的精度有限,建议根据精度范围设定合理的缩放范围,例如:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
< charset="utf-8" />
< http-equiv="X-UA-Compatible" content="IE=edge" />
< name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: px;height: px"></div>
<script src="//cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
async function run() {
const myChart = echarts.init(document.getElementById('main'));
const usaGeo = await axios.get('//cdn.jsdelivr.net/gh/VanMess/echart-wiki-examples@1.0.0/11_geo/USA.json');
echarts.registerMap('USA', usaGeo.data, {
Alaska: {
// 把阿拉斯加移到美国主大陆左下方
left: -,
top: ,
width: ,
},
Hawaii: {
left: -, // 夏威夷
top: ,
width: ,
},
'Puerto Rico': {
// 波多黎各
left: -,
top: ,
width: ,
},
});
const option = {
geo: {
map: 'USA',
// 声明允许缩放与拖拽
roam: true,
scaleLimit: {
// 声明最小缩放比例
min: ,
// 声明最大缩放比例
max: ,
},
},
series: [
{
type: 'scatter',
coordinateSy: 'geo',
data: [
[-, , ],
[-, , ],
[-, , ],
[-, , ],
],
symbolSize: function (val) {
return val[];
},
},
],
};
myChart.setOption(option);
}
run();
</script>
</body>
</html>
地理坐标系中,与地图布局相关的较多,:
其中,left、top、right、bottom、width、height 是 echarts 中通用的定位手段,含义与配置都与其他组件一样。下面讨论列表中不太常见的。
aspectScale 用于控制地图缩放的宽高比例。这个概念并不复杂,使用经纬度定义的地理信息本身带有宽高比例 aspect = width/height
,那么渲染时若确定了地理坐标系的宽度为 x
,则 y = x * aspect
,形如:
是不是跟我们平常看到的不一样?这是因为经纬坐标系是建立在地球的三维椭圆体上的,映射到二维平面时会产生一定的形变,所以绘制时需要在经纬度比例基础上椭圆形变,在 echarts 上则是通过 y = x * aspect * aspectScale
实现,通常保持认值 0.75
即可:
layoutCenter、layoutSize 提供了另外一种布局,它们将地图坐标系调整为最长边等于 layoutSize`的盒子,并将盒子的中心点放置在 layoutCenter 位置上。基于 layoutCenter、layoutSize 的布局能够保持地图高宽比的情况下把地图放在某个盒形区域的正中间,并且保证不超出盒形的范围。使用上请注意:
例如:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
< charset="utf-8" />
< http-equiv="X-UA-Compatible" content="IE=edge" />
< name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: px;height: px"></div>
<script src="//cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
async function run() {
const myChart = echarts.init(document.getElementById('main'));
const usaGeo = await axios.get('//cdn.jsdelivr.net/gh/VanMess/echart-wiki-examples@1.0.0/11_geo/USA.json');
echarts.registerMap('USA', usaGeo.data, {
Alaska: { left: -, top: , width: },
Hawaii: { left: -, top: , width: },
'Puerto Rico': { left: -, top: , width: },
});
const option = {
tool@R_605_2@: { feature: { saveAsImage: {} } },
geo: {
map: 'USA',
roam: true,
// 设定布局中心点位置
layoutCenter: ['50%', '40%'],
// 设定坐标系大小
layoutSize: ,
},
series: [
{
type: 'scatter',
coordinateSy: 'geo',
data: [
[-, , ],
[-, , ],
[-, , ],
[-, , ],
],
symbolSize: function (val) {
return val[];
},
},
],
};
myChart.setOption(option);
}
run();
</script>
</body>
</html>
示例:
center 用于定义当前视图的中心点,以经纬度坐标表示,形如: center: [-80, 30]
; boundingCoords 则用于定义当前视图的、右下角经纬度,以二维数组表示,形如:
{
boundingCoords: [
// 定位经纬度
[-, ],
// 定位右下角经纬度
[-, ],
],
}
center 与 boundingCoords 互斥,当时,优先使用 center。
从定义可以看出,center 定义的是地图所展示的中心区域的位置,配合 zoom
可以控制视图中展示的地图多寡,例如下例中:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
< charset="utf-8" />
< http-equiv="X-UA-Compatible" content="IE=edge" />
< name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: px;height: px"></div>
<script src="//cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
async function run() {
const myChart = echarts.init(document.getElementById('main'));
const usaGeo = await axios.get('//cdn.jsdelivr.net/gh/VanMess/echart-wiki-examples@1.0.0/11_geo/USA.json');
echarts.registerMap('USA', usaGeo.data, {
Alaska: { left: -, top: , width: },
Hawaii: { left: -, top: , width: },
'Puerto Rico': { left: -, top: , width: },
});
const option = {
geo: {
map: 'USA',
roam: true,
// 地图中心点的经纬度坐标
center: [-, ],
// 地图初始时的缩放比例
zoom: ,
},
series: [
{
type: 'scatter',
coordinateSy: 'geo',
data: [
[-, , ],
[-, , ],
[-, , ],
[-, , ],
],
symbolSize: function (val) {
return val[];
},
},
],
};
myChart.setOption(option);
}
run();
</script>
</body>
</html>
示例:
而 boundingCoords 定义是地图坐标系所展现的整个区域的经纬度,使用时不需要考虑缩放比例,相对更简单。上例基础上, geo:
{
geo: {
map: 'USA',
roam: true,
boundingCoords: [
// 定位经纬度
[-, ],
// 定位右下角经纬度
[-, ],
],
},
}
示例:
geo 坐标系需要自行提供地理信息数据,使用上有一定的不便,因此 echarts 提供了另一种地理坐标系实现 —— 。bmap 扩展将地图带入 echarts,以地图为底图绘制地理坐标系,所以使用上就不用再关注地理数据了,而且依托于地图提供的强大,bmap 在伸缩、移动、精度等方面更出色。
使用时,除了 echarts 外,还需要引入地图依赖、bmap 扩展依赖,以 CDN 为例:
引入后,就可以通过 bmap 配置地理坐标系。bmap 所的配置项比较少,:
bmap 包含了地图所的所有地理区域信息,所以应用时只需通过 center 指定视图中心点,通过 zoom 控制视图区域,即可实现地理坐标系,示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
< charset="utf-8" />
< http-equiv="X-UA-Compatible" content="IE=edge" />
< name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: px;height: px"></div>
<script src="//api.map.baidu.com/api?v=2.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu&__ec_v__=20190126"></script>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script src="//cdn.bootcss.com/echarts/4.5.0/extension/bmap.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var data = [
{ name: '平顶山', value: [, , , , ] },
{ name: '邢台', value: [, , , , ] },
{ name: '德州', value: [, , , , ] },
{ name: '济宁', value: [, , , , ] },
{ name: '荆州', value: [, , , , ] },
{ name: '宜昌', value: [, , , , ] },
{ name: '义乌', value: [, , , , ] },
{ name: '丽水', value: [, , , , ] },
{ name: '洛阳', value: [, , , , ] },
{ name: '秦皇岛', value: [, , , , ] },
{ name: '株洲', value: [, , , , ] },
{ name: '石家庄', value: [, , , , ] },
{ name: '莱芜', value: [, , , , ] },
{ name: '常德', value: [, , , , ] },
{ name: '保定', value: [, , , , ] },
{ name: '湘潭', value: [, , , , ] },
{ name: '金华', value: [, , , , ] },
{ name: '岳阳', value: [, , , , ] },
{ name: '长沙', value: [, , , , ] },
{ name: '衢州', value: [, , , , ] },
{ name: '廊坊', value: [, , , , ] },
{ name: '菏泽', value: [, , , , ] },
{ name: '合肥', value: [, , , , ] },
{ name: '武汉', value: [, , , , ] },
{ name: '大庆', value: [, , , , ] },
];
var option = {
bmap: {
// 指定中心点
center: [, ],
// 指定缩放比例
zoom: ,
roam: true,
},
series: [
{
name: 'pm2.5',
type: 'scatter',
coordinateSy: 'bmap',
data: data,
symbolSize: function (val) {
return val[] / ;
},
},
],
};
myChart.setOption(option);
</script>
</body>
</html>
示例:
此外,还可以通过 myChart.getModel().getComponent('bmap').getBMap();
接口 bmap 对应的地图实例,实现与地图的交互。在上述示例基础上,额外:
// 地图实例
var map = myChart.getModel().getComponent('bmap').getBMap();
// 交通状况层
var traffic = new BMap.TrafficLayer();
map.addTileLayer(traffic);
// 重置视图中心
map.centerAndZoom(new BMap.Point(, ), );
示例;
@H_707_4@
完整的开发指南,请参考 。
地图坐标系常用于表达与地理位置密切相关的数据,比如新冠状病毒肆虐期间,许多实时疫情报告都会通过地图+热力图形式表现各地疫情发展情况。地图坐标系下,比较常见的图表类型有: