ECharts 散点图(Scatter)结合高德地图(AMap)和自定义地理数据(GeoJSON), 打造出炫酷的大屏地图效果
如何绘制自定义地图
ECharts 支持在 地理坐标系(geo) 和 地图系列(map series) 中使用 SVG 或者 GeoJSON 作为底图。
如何编辑自定义地图
在DataV.GeoAtlas地理小工具系列可以获取到省/市/县轮廓图的数据, 将其他类型中的内容复制到 geojson.io, 即可编辑地图, 包括调整区块, 增加标记等等, 还提供表格模式, 可以很方便地编辑数据.
注意: 由于在 geojson.io 中使用的是国外的地图服务(OpenStreetMap), 标记的元素要在高德地图上显示时, 需要转成国标, 或者考虑在 DataV.GeoAtlas 提供的边界生成器中编辑数据
如何渲染自定义地图
数据编辑好后, 将 GeoJSON 保存下来, 再通过 ECharts 就可以渲染出地图了
echarts.registerMap('mapName', {
"type":"FeatureCollection",
"features":[]
});
option = {
geo: {
map: 'mapName',
}
};
myChart.setOption(option);
结合高德地图
通过 echarts-extension-amap 我们可以让 ECharts 与高德地图结合在一起
结合自定义地理数据
我们先尝试通过渲染自定义地图的方式和高德地图结合在一起
echarts.registerMap('cs', {
"type":"FeatureCollection",
"features":[]
});
const option = {
amap: {
viewMode: '3D',
resizeEnable: true,
renderOnMoving: true,
echartsLayerZIndex: 2000,
echartsLayerInteractive: true,
largeMode: false
},
series: [
{
type: 'map',
map: 'cs',
roam: true,
},
]
};
myChart.setOption(option);
但发现这种方式不能很好地结合, 主要的问题如下
- 位置存在偏移
- 自定义地图无法随高德地图联动
- 当设置
roam:false
时拖动高德地图, 自定义地图不会动 - 当设置
roam:true
时自定义地图是可以拖动了, 但只是单纯的拖动他自己, 与高德地图的拖动是完全独立的, 即拖动自定义地图时, 高德地图不动; 拖动高德地图时, 自定义地图又不动
- 当设置
因此我们改用 AMap.GeoJSON 的方式将 GeoJSON 绘制到高德地图上
const aMapGeoJson = new AMap.GeoJSON({
geoJSON: geojson,
getPolygon: function(geojson, lnglats) {
return new AMap.Polygon({
path: lnglats,
fillOpacity: 0.6,
strokeColor: '#DCDFE6',
fillColor: '#409EFF',
});
}
});
aMapGeoJson.setMap(amap);
结合散点图
最后通过 effectScatter
绘制散点(气泡)图, 注意将 coordinateSystem
设置为 amap
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ECharts 散点图(Scatter)结合高德地图(AMap)和自定义地理数据(GeoJSON)</title>
</head>
<body style="margin: 0;">
<div id="main" style="width: 100vw; height: 100vh;"></div>
<script src="https://webapi.amap.com/maps?v=1.4.4&key={替换成你的KEY}"></script>
<script src="https://unpkg.com/echarts@5.4.3/dist/echarts.min.js"></script>
<script src="https://unpkg.com/echarts-extension-amap@1.11.0/dist/echarts-extension-amap.min.js"></script>
<script>
const myChart = echarts.init(document.getElementById('main'));
// 替换成你的 GeoJSON 格式的自定义地理数据
const geojson = {"type":"FeatureCollection","features":[]}
const option = {
title: {
text: 'ECharts 散点图(Scatter)结合高德地图(AMap)和自定义地理数据(GeoJSON)',
subtext: 'ECharts + AMap + GeoJSON + Scatter',
},
// 结合高德地图
amap: {
// enable 3D mode
// Note that it's suggested to enable 3D mode to improve echarts rendering.
viewMode: '3D',
// initial options of AMap
// See https://lbs.amap.com/api/javascript-api/reference/map#MapOption for details
resizeEnable: true,
// customized map style, see https://lbs.amap.com/dev/mapstyle/index for details
// https://lbs.amap.com/api/javascript-api/guide/map/map-style/
// mapStyle: 'amap://styles/dark',
// whether echarts layer should be rendered when the map is moving. Default is true.
// if false, it will only be re-rendered after the map `moveend`.
// It's better to set this option to false if data is large.
renderOnMoving: true,
// the zIndex of echarts layer for AMap, default value is 2000.
// deprecated since v1.9.0, use `echartsLayerInteractive` instead.
echartsLayerZIndex: 2000,
// whether echarts layer is interactive. Default value is true
// supported since v1.9.0
echartsLayerInteractive: true,
// whether to enable large mode. Default value is false
// supported since v1.9.0
largeMode: false
},
series: [
// 结合散点图
{
type: 'effectScatter',
coordinateSystem: 'amap',
symbolSize: function (params) {
return (params[2] / 100) * 15 + 5;
},
itemStyle: {
color: '#b02a02'
},
label: {
formatter: '{b}',
show: true,
},
data: [
{
name: 'demo',
value: [112.95905621695658, 28.21745411105819, 100],
}
]
}
]
};
myChart.setOption(option);
// get AMap extension component
const amapComponent = myChart.getModel().getComponent('amap');
// get the instance of AMap
const amap = amapComponent.getAMap();
// 结合 GeoJSON
// 将 geojson 绘制到地图上
// https://lbs.amap.com/demo/javascript-api/example/overlayers/geojson
const aMapGeoJson = new AMap.GeoJSON({
geoJSON: geojson,
getPolygon: function(geojson, lnglats) {
return new AMap.Polygon({
path: lnglats,
fillOpacity: 0.6,
strokeColor: '#DCDFE6',
fillColor: '#409EFF',
});
}
});
aMapGeoJson.setMap(amap);
// 根据地图上添加的覆盖物分布情况,自动缩放地图到合适的视野级别
amap.setFitView();
</script>
</body>
</html>