前言
在之前的博客中,有介绍如何进行Leaflet展示的,也有介绍Echarts如何进行高效图表展示的。针对一些时空类的场景,比如需要跟随GIS地图一起进行图表展示,如何在地图上集成图表插件。本文将以常用的Leaflet为例,重点讲解在Leaflet中如何集成Echarts进行模拟迁徙的地图展示,最后通过分析前端调用示例以代码的形式给出实例,希望对需要将两者进行集成的朋友有所帮助。
一、相关基础知识
1、leaflet-echarts插件
基于leaflet 扩展echarts,使ECharts的地图可以加到leaflet上,根据百度地图echarts的扩展改写,在事件联动这个地方以及echarts的容器与地图容器在拖动和缩放中的适应上耗费了很长时间,为了兼容echarts的map其他类型的数据又下了不少功夫。leaflet-echarts3 github地址。有兴趣朋友可以独立下载。
2、依赖插件说明
在Leaflet-charts中,其依赖的组件包还是比较少的。主要的包如下:
序号 | 组件 | 备注 |
1 | leaflet-echarts.js | 集成插件 |
2 | echarts.source.js | echarts组件 |
3 | jquery.js | jquery组件 |
需要注意的是,当前提供的echarts版本跟Echarts官网提供的版本有一定差异,如果需要使用最新的一些图表及API,谨慎升级或者需要自己手动调试代码,改成兼容新版本的才可以,否则会报错。示例提供的echarts的版本是2.2.6。
二、页面集成
1、新建html页面
在个人电脑任意盘符中新建index3.html,关键代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>leaflet-echarts集成特效</title>
<link rel="stylesheet" href="http://cdn.bootcss.com/leaflet/0.7.7/leaflet.css">
<style>
html, body, #map {
height: 100%;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="http://cdn.bootcss.com/leaflet/0.7.7/leaflet.js"></script>
<script src="../src/leaflet-echarts.js"></script>
<script src="../lib/echarts.source.js"></script>
<script src="http://cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script>
</script>
</body>
</html>
2、leaflet地图初始化
在上面的Script脚本中进行Leaflet地图的初始化操作,示例代码如下所示:
var map = L.map('map');
var baseLayers = {
"高德地图": L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
subdomains: "1234"
}),
'高德影像': L.layerGroup([L.tileLayer('http://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
subdomains: "1234"
}), L.tileLayer('http://t{s}.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}', {
subdomains: "1234"
})]),
"立体地图": L.tileLayer('https://a.tiles.mapbox.com/v3/examples.c7d2024a/{z}/{x}/{y}.png', {
attribution: 'Map © Pacific Rim Coordination Center (PRCC). Certain data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
key: 'BC9A493B41014CAABB98F0471D759707',
styleId: 22677
}),
"Foursquare": L.tileLayer('https://a.tiles.mapbox.com/v3/foursquare.map-0y1jh28j/{z}/{x}/{y}.png', {
attribution: 'Map © Pacific Rim Coordination Center (PRCC). Certain data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
key: 'BC9A493B41014CAABB98F0471D759707',
styleId: 22677
}),
'GeoQ灰色底图': L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}').addTo(map)
};
L.tileLayer('https://a.tiles.mapbox.com/v3/foursquare.map-0y1jh28j/{z}/{x}/{y}.png', {
attribution: 'Map © Pacific Rim Coordination Center (PRCC). Certain data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
key: 'BC9A493B41014CAABB98F0471D759707',
styleId: 22677
});
var layercontrol = L.control.layers(baseLayers, {
position: "topleft"
}).addTo(map);
map.setView(L.latLng(37.550339, 104.114129), 4);
var overlay = new L.echartsLayer(map, echarts);
这里地图引用了GeoQ的灰色底图、高德的影像和电子地图等在线地图,如需离线访问的需要下载相应的图源或者接入自己的离线地图资源。
3、Echarts与地图集成
经过第二个步骤的初始化,已经完成Leaflet地图的定义,在这里进行Echarts地的集成。核心代码如下所示:
var chartsContainer=overlay.getEchartsContainer();
var myChart=overlay.initECharts(chartsContainer);
window.onresize = myChart.onresize;
var option = {
color: ['gold','aqua','lime'],
title : {
text: 'Leaflet和Echarts集成模拟迁徙',
subtext:'数据纯属虚构',
x:'center',
textStyle : {
color: '#fff'
}
},
tooltip : {
trigger: 'item',
formatter: '{b}'
},
legend: {
orient: 'vertical',
x:'left',
data:['北京 Top10', '上海 Top10', '广州 Top10'],
selectedMode: 'single',
selected:{
'上海 Top10' : false,
'广州 Top10' : false
},
textStyle : {
color: '#fff'
}
},
toolbox: {
show : true,
orient : 'vertical',
x: 'right',
y: 'center',
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
restore : {show: true},
saveAsImage : {show: true}
}
},
dataRange: {
min : 0,
max : 100,
calculable : true,
color: ['#ff3333', 'orange', 'yellow','lime','aqua'],
textStyle:{
color:'#fff'
}
},
series : [
{
name: '全国',
type: 'map',
roam: true,
hoverable: false,
mapType: 'none',
itemStyle:{
normal:{
borderColor:'rgba(100,149,237,1)',
borderWidth:0.5,
areaStyle:{
color: '#1b1b1b'
}
}
},
data:[],
markLine : {
smooth:true,
symbol: ['none', 'circle'],
symbolSize : 1,
itemStyle : {
normal: {
color:'#fff',
borderWidth:1,
borderColor:'rgba(30,144,255,0.5)'
}
},
data : [
[{name:'北京'},{name:'包头'}],
[{name:'北京'},{name:'北海'}],
[{name:'北京'},{name:'广州'}],
[{name:'北京'},{name:'郑州'}],
[{name:'北京'},{name:'长春'}],
[{name:'北京'},{name:'长治'}],
[{name:'北京'},{name:'重庆'}],
[{name:'北京'},{name:'长沙'}],
[{name:'广州'},{name:'烟台'}],
[{name:'广州'},{name:'盐城'}]
],
},
geoCoord: {
'上海': [121.4648,31.2891],
'东莞': [113.8953,22.901],
'东营': [118.7073,37.5513],
'中山': [113.4229,22.478],
'临汾': [111.4783,36.1615],
'临沂': [118.3118,35.2936],
'丹东': [124.541,40.4242],
'丽水': [119.5642,28.1854],
'乌鲁木齐': [87.9236,43.5883],
'佛山': [112.8955,23.1097],
'保定': [115.0488,39.0948],
'兰州': [103.5901,36.3043],
'包头': [110.3467,41.4899],
'泉州': [118.3228,25.1147],
'泰安': [117.0264,36.0516],
'泰州': [120.0586,32.5525],
'济南': [117.1582,36.8701],
'济宁': [116.8286,35.3375],
'海口': [110.3893,19.8516],
'淄博': [118.0371,36.6064],
'淮安': [118.927,33.4039],
'深圳': [114.5435,22.5439],
'清远': [112.9175,24.3292],
'温州': [120.498,27.8119],
'渭南': [109.7864,35.0299],
'湖州': [119.8608,30.7782],
'湘潭': [112.5439,27.7075],
'铜川': [109.0393,35.1947],
'银川': [106.3586,38.1775],
'镇江': [119.4763,31.9702],
'长春': [125.8154,44.2584],
'长沙': [113.0823,28.2568],
'长治': [112.8625,36.4746],
'阳泉': [113.4778,38.0951],
'青岛': [120.4651,36.3373],
'韶关': [113.7964,24.7028]
}
},
{
name: '北京 Top10',
type: 'map',
mapType: 'none',
data:[],
markLine : {
smooth:true,
effect : {
show: true,
scaleSize: 1,
period: 30,
color: '#fff',
shadowBlur: 10
},
itemStyle : {
normal: {
borderWidth:1,
lineStyle: {
type: 'solid',
shadowBlur: 10
}
}
},
data : [
[{name:'北京'}, {name:'上海',value:95}],
[{name:'北京'}, {name:'广州',value:90}],
[{name:'北京'}, {name:'大连',value:80}],
[{name:'北京'}, {name:'南宁',value:70}],
[{name:'北京'}, {name:'南昌',value:60}],
[{name:'北京'}, {name:'拉萨',value:50}],
[{name:'北京'}, {name:'长春',value:40}],
[{name:'北京'}, {name:'包头',value:30}],
[{name:'北京'}, {name:'重庆',value:20}],
[{name:'北京'}, {name:'常州',value:10}]
]
},
markPoint : {
symbol:'emptyCircle',
symbolSize : function (v){
return 10 + v/10
},
effect : {
show: true,
shadowBlur : 0
},
itemStyle:{
normal:{
label:{show:false}
},
emphasis: {
label:{position:'top'}
}
},
data : [
{name:'上海',value:95},
{name:'广州',value:90},
{name:'大连',value:80},
{name:'南宁',value:70},
{name:'南昌',value:60},
{name:'拉萨',value:50},
{name:'长春',value:40},
{name:'包头',value:30},
{name:'重庆',value:20},
{name:'常州',value:10}
]
}
},
{
name: '上海 Top10',
type: 'map',
mapType: 'none',
data:[],
markLine : {
smooth:true,
effect : {
show: true,
scaleSize: 1,
period: 30,
color: '#fff',
shadowBlur: 10
},
itemStyle : {
normal: {
borderWidth:1,
lineStyle: {
type: 'solid',
shadowBlur: 10
}
}
},
data : [
[{name:'上海'},{name:'包头',value:95}],
[{name:'上海'},{name:'昆明',value:90}],
[{name:'上海'},{name:'广州',value:80}],
[{name:'上海'},{name:'郑州',value:70}],
[{name:'上海'},{name:'长春',value:60}],
[{name:'上海'},{name:'重庆',value:50}],
[{name:'上海'},{name:'长沙',value:40}],
[{name:'上海'},{name:'北京',value:30}],
[{name:'上海'},{name:'丹东',value:20}],
[{name:'上海'},{name:'大连',value:10}]
]
},
markPoint : {
symbol:'emptyCircle',
symbolSize : function (v){
return 10 + v/10
},
effect : {
show: true,
shadowBlur : 0
},
itemStyle:{
normal:{
label:{show:false}
},
emphasis: {
label:{position:'top'}
}
},
data : [
{name:'包头',value:95},
{name:'昆明',value:90},
{name:'广州',value:80},
{name:'郑州',value:70},
{name:'长春',value:60},
{name:'重庆',value:50},
{name:'长沙',value:40},
{name:'北京',value:30},
{name:'丹东',value:20},
{name:'大连',value:10}
]
}
},
{
name: '广州 Top10',
type: 'map',
mapType: 'none',
data:[],
markLine : {
smooth:true,
effect : {
show: true,
scaleSize: 1,
period: 30,
color: '#fff',
shadowBlur: 10
},
itemStyle : {
normal: {
borderWidth:1,
lineStyle: {
type: 'solid',
shadowBlur: 10
}
}
},
data : [
[{name:'广州'},{name:'福州',value:95}],
[{name:'广州'},{name:'太原',value:90}],
[{name:'广州'},{name:'长春',value:80}],
[{name:'广州'},{name:'重庆',value:70}],
[{name:'广州'},{name:'西安',value:60}],
[{name:'广州'},{name:'成都',value:50}],
[{name:'广州'},{name:'常州',value:40}],
[{name:'广州'},{name:'北京',value:30}],
[{name:'广州'},{name:'北海',value:20}],
[{name:'广州'},{name:'海口',value:10}]
]
},
markPoint : {
symbol:'emptyCircle',
symbolSize : function (v){
return 10 + v/10
},
effect : {
show: true,
shadowBlur : 0
},
itemStyle:{
normal:{
label:{show:false}
},
emphasis: {
label:{position:'top'}
}
},
data : [
{name:'福州',value:95},
{name:'太原',value:90},
{name:'长春',value:80},
{name:'重庆',value:70},
{name:'西安',value:60},
{name:'成都',value:50},
{name:'常州',value:40},
{name:'北京',value:30},
{name:'北海',value:20},
{name:'海口',value:10}
]
}
}
]
};
overlay.setOption(option);
三、功能展示
1、地图首页
将完成的index3.html页面直接在浏览器中打开,即可看到将地图和图表进行完美融合的界面,支持地图的缩放,迁徙功能支持与地图无缝衔接。
2、底图切换
在右侧的在线地图中,可以支持不同的地图进行切换,比如可以实现GeoQ的灰色底图切换到高德的高线地图展示,如果您有离线的地图图源,也是可以接入进行展示的。
四、渲染分析
下面通过在浏览器中进行Debug断点调试,跟踪相关代码的执行流程。
页面元素初始化,执行以下代码:
var overlay = new L.echartsLayer(map, echarts);
var chartsContainer=overlay.getEchartsContainer();
charts初始化,与map进行元素绑定,将map的元素大小赋值给图表,保持两者一致。
initialize: function(map, ec) {
this._map = map;
var size = map.getSize();
var div = this._echartsContainer = document.createElement('div');
div.style.position = 'absolute';
div.style.height = size.y + 'px';
div.style.width = size.x + 'px';
div.style.top = 0;
div.style.left = 0;
map.getPanes().overlayPane.appendChild(div);
this._init(map, ec);
},
事件绑定
setOption设置报表展示参数
总结
以上就是本文的主要内容,本文将以常用的Leaflet为例,重点讲解在Leaflet中如何集成Echarts进行模拟迁徙的地图展示,最后通过分析前端调用示例以代码的形式给出实例,希望对需要将两者进行集成的朋友有所帮助。行文仓促,如有不当之处,欢迎朋友在评论区留言批评指正。