有一个方案完全满足你的需求,那就是 Echarts + 百度地图 API,首先我不太喜欢百度,也不做广告,不过 Echarts 却是我最喜欢的开源图表库。
Echarts 实现的地图是这样的,你可以在
Echarts 绘制地图
Echarts 是图表库,实现地图的呈现主要有两种方式:使用地图矢量数据呈现,好处是无需其他服务,数据均打包在 js 中,缺点是打包的代码过大,官方已不提供下载,需要自行寻找,且面临无法更新的困难。
结合百度地图 API 使用,好处是地图及时更新,数据极其丰富且快速,坏处是需要整合百度开放平台。
因为百度地图 API 完全满足你的需求(矢量,数据量全,个人基础免费),且我们生产环境也使用的是这种方式,我就简单讲解一下。
JS 依赖
首先需要下载 echarts 的依赖,引入方式有直接 script,webpack 等方式,可以参考这里。
然后需要注册一下百度地图开放平台,创建一个应用,记下 AK,供后面调用。
就可以在你的代码里添加百度地图的 js(替换生成的 AK)和 echarts 的百度地图扩展。所以一共需要添加三个 js 库,为了简化我这里使用了 CDN 的 js。
Echarts 绘制图表
接着就可以通过 echarts 调用百度地图 API 来绘制地图了。echarts 的使用非常简单,主要是提供一个 option 配置项对象。
ECharts// 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据 var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
// 使用刚指定的配置项和数据显示图表。 myChart.setOption(option);
上面是 echarts 基本的使用,而我们只需要修改配置项 option 对象,即可画出不同的图像。
Echarts 地图绘制
例如,我们画出最近比较常见的新型肺炎确诊地图(数据纯属虚构),并画一条迁移线路。
// 指定数据
let data = [
{name: '武汉', value: 38},
{name: '长沙', value: 28},
{name: '上海', value: 22},
]
// 指定坐标
let geo = {
'武汉': [114.31,30.52],
'长沙': [113,28.21],
'上海': [121.48,31.22]
}
// 数据转换
var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var geoCoord = geo[data[i].name];
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
});
}
}
return res;
}
// 配置项
let option = {
backgroundColor: 'transparent',
tooltip : {
show: false
},
// 百度地图配置
bmap: {
center: [104.114129, 37.550339],
zoom: 5,
roam: true,
// 地图样式
mapStyle: {
styleJson: [
{
"featureType": "water",
"elementType": "all",
"stylers": {
"color": "#17263cff"
}
},
{
"featureType": "land",
"elementType": "all",
"stylers": {
"color": "#242f3eff"
}
},
{
"featureType": "boundary",
"elementType": "geometry",
"stylers": {
"color": "#064f85"
}
},
{
"featureType": "railway",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "highway",
"elementType": "geometry",
"stylers": {
"color": "#004981"
}
},
{
"featureType": "highway",
"elementType": "geometry.fill",
"stylers": {
"color": "#005b96",
"lightness": 1
}
},
{
"featureType": "highway",
"elementType": "labels",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "arterial",
"elementType": "geometry",
"stylers": {
"color": "#004981"
}
},
{
"featureType": "arterial",
"elementType": "geometry.fill",
"stylers": {
"color": "#00508b"
}
},
{
"featureType": "poi",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "green",
"elementType": "all",
"stylers": {
"color": "#056197",
"visibility": "off"
}
},
{
"featureType": "subway",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "manmade",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "local",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "arterial",
"elementType": "labels",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "boundary",
"elementType": "geometry.fill",
"stylers": {
"color": "#029fd4"
}
},
{
"featureType": "building",
"elementType": "all",
"stylers": {
"color": "#1a5787"
}
},
{
"featureType": "label",
"elementType": "all",
"stylers": {
"visibility": "off"
}
}]
}
},
series : [
{
name: '确诊数量',
type: 'scatter',
coordinateSystem: 'bmap',
data: convertData(data),
symbolSize: function (val) {
return val[2];
},
label: {
show: true,
formatter: '{b}',
position: 'inside',
fontSize: 10,
color: '#333333'
},
itemStyle: {
color: '#ddb926'
},
emphasis: {
label: {
show: true,
formatter: '{@[2]}',
}
}
},
{
name: '线路',
type: 'lines',
coordinateSystem: 'bmap',
zlevel: 2,
effect: {
show: true,
constantSpeed: 30,
symbol: 'pin',
symbolSize: 10,
trailLength: 0,
},
data: [
{'coords': [[114.31,30.52],[121.48,31.22]]}
]
}
]
}
实现的效果如下所示
地图上的点和线等就可以根据我们的需求添加了。
代码里有几个疑问了。坐标怎么获取?
百度地图有个工具可以帮助我们快速获取地图坐标。拾取坐标系统api.map.baidu.com地图样式(mapStyle)一堆 JSON 怎么配置?
百度地图开放平台有个工具可供我们自定义样式。
完整示例
完整的代码如下,替换百度地图 AK,即可保存成 html 网页在浏览器中查看。
ECharts 地图// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定数据
let data = [
{name: '武汉', value: 38},
{name: '长沙', value: 28},
{name: '上海', value: 22},
]
// 指定坐标
let geo = {
'武汉': [114.31,30.52],
'长沙': [113,28.21],
'上海': [121.48,31.22]
}
// 数据转换
var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var geoCoord = geo[data[i].name];
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
});
}
}
return res;
}
// 配置项
let option = {
backgroundColor: 'transparent',
tooltip : {
show: false
},
// 百度地图配置
bmap: {
center: [104.114129, 37.550339],
zoom: 5,
roam: true,
// 地图样式
mapStyle: {
styleJson: [
{
"featureType": "water",
"elementType": "all",
"stylers": {
"color": "#17263cff"
}
},
{
"featureType": "land",
"elementType": "all",
"stylers": {
"color": "#242f3eff"
}
},
{
"featureType": "boundary",
"elementType": "geometry",
"stylers": {
"color": "#064f85"
}
},
{
"featureType": "railway",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "highway",
"elementType": "geometry",
"stylers": {
"color": "#004981"
}
},
{
"featureType": "highway",
"elementType": "geometry.fill",
"stylers": {
"color": "#005b96",
"lightness": 1
}
},
{
"featureType": "highway",
"elementType": "labels",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "arterial",
"elementType": "geometry",
"stylers": {
"color": "#004981"
}
},
{
"featureType": "arterial",
"elementType": "geometry.fill",
"stylers": {
"color": "#00508b"
}
},
{
"featureType": "poi",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "green",
"elementType": "all",
"stylers": {
"color": "#056197",
"visibility": "off"
}
},
{
"featureType": "subway",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "manmade",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "local",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "arterial",
"elementType": "labels",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "boundary",
"elementType": "geometry.fill",
"stylers": {
"color": "#029fd4"
}
},
{
"featureType": "building",
"elementType": "all",
"stylers": {
"color": "#1a5787"
}
},
{
"featureType": "label",
"elementType": "all",
"stylers": {
"visibility": "off"
}
}]
}
},
series : [
{
name: '确诊数量',
type: 'scatter',
coordinateSystem: 'bmap',
data: convertData(data),
symbolSize: function (val) {
return val[2];
},
label: {
show: true,
formatter: '{b}',
position: 'inside',
fontSize: 10,
color: '#333333'
},
itemStyle: {
color: '#ddb926'
},
emphasis: {
label: {
show: true,
formatter: '{@[2]}',
}
}
},
{
name: '线路',
type: 'lines',
coordinateSystem: 'bmap',
zlevel: 2,
effect: {
show: true,
constantSpeed: 30,
symbol: 'pin',
symbolSize: 10,
trailLength: 0,
},
data: [
{'coords': [[114.31,30.52],[121.48,31.22]]}
]
}
]
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
参考