要求和预期结果:
实现贵州地市地图效果,并且鼠标过去有数据展示,贵安新区数据无法展示,弄个自定义地图展示出来
- 相关文件准备,加载地图和部分相关组件。echarts.min.js 和 guizhou.js可以从网上找.
.html文件引入相关js文件[有先后顺序],html文件准备一个div放地图,如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="./mapJs/echarts.min.js"></script>
<script type="text/javascript" src="./mapJs/guizhou.js"></script>
<script type="text/javascript" src="./mapIndexScript.js"></script>
<title>贵州地图页面</title>
</head>
<body>
<!-- div用来存放地图的容器 -->
<div id="mapContainer" style="width: 1000px; height: 700px;">
</div>
</body>
</html>
实现的功能在页面加载时就展示地图,所以在js文件初始化就载入地图,还没加数据:
var mapChart;
var data = [];//地图展示数据
window.onresize = function() {// 地图自适应
mapChart.resize();
// 如果有多个表变动在下方依次写下去就可以了
}
window.onload=function(){ // 初始化
//画地图
initMap('贵州','地市男女比例',data);
}
/**
* 初始化地图
* @param title
* @param subtext
* @param data
*/
function initMap(title,subtext,data){
if (mapChart && mapChart.dispose) {//二次绘图,销毁旧的
mapChart.dispose();
}
mapChart = echarts.init(document.getElementById('mapContainer'));
var option = {
title : { // 标题
text : title,//标题内容
subtext:subtext,//副标题内容
padding: 10,// 标题内边距,单位px,默认各方向内边距为5,接受数组分别设定上右下左边距
itemGap: 10, // 主副标题纵向间隔,单位px,默认为10
textStyle: { // 主标题文本样式
fontFamily: 'Arial',
fontSize: 18,
fontStyle: 'normal',
fontWeight: 'normal',
},
subtextStyle: {// 副标题文本样式{"color": "#aaa"}
fontFamily: 'Arial',
fontSize: 16,
fontStyle: 'normal',
fontWeight: 'normal',
}
},
toolbox : { // 工具箱
show : true,
itemSize :15,
feature : {
mark : {show: false},
dataView : {show: false,readOnly: false},
magicType : {show: false,type: ['line','bar','map']},
restore:{show:false},
// 还原,复位原始图表
restore : {
show : true,
title : '还原'
},
// 保存图片(IE8-不支持),可设置更多属性
saveAsImage : {
show : true,
title : '保存为图片',
type : 'png',
lang : ['点击保存']
}
}
},
visualMap: { //视觉映射器
type: 'continuous',
itemWidth:25, // 图形的宽度,即长条的宽度。
itemHeight:150, // 图形的高度,即长条的高度。
align:"right", // 手柄的位置
min: 0,
max: 1000,
right:"3%", // 组件离容器右侧的距离,'20%'
bottom:"1%", // 组件离容器下侧的距离,'20%'
text:['High','Low'+'\n'+'\n'+'总人数'],
realtime: false,
precision:2, // 数据展示的小数精度,默认为0,无小数点
calculable: true,
inRange: {
color: ['#C8E3FB','#91C6F7','#59AAF2']
},
outRange: {
color: ['#C8E3FB','#91C6F7','#59AAF2']
},
formatter: function (value) { // 标签的格式化工具。
return value; // 范围标签显示内容。
}
},
tooltip:{// 工具提示
},
series : [ //配置项
{
name : '地市男女比例',
type : 'map',
coordinateSystem: 'none',
roam : true,// 滚动缩放,拖拽漫游
scaleLimit : {
max : 3,
min : 0.9
},// 缩放比例
mapType : title,
selectedMode : 'single',
label: {
normal: {
show: true,
textStyle: { // 字体设置
fontWeight : 'lighter',
fontSize: 16,
color: 'black'// 'brown'//'black'
}
},
emphasis: { // 对应的鼠标悬浮效果
show: true,// 悬浮 地址名称 显示
textStyle: {
fontWeight : 'lighter',
fontSize: 16,
color: 'brown'// "#00a0c9"
}
}
},
itemStyle : {
normal : {
areaStyle:{color:'black'},
areaColor: '#DDDDDD',// '#83bff6',
borderColor:'#0074AD',// '#0066ba',white
borderWidth: 1,
label : {
show : true
}
},
emphasis : {
borderWidth: 1.5,
borderColor: '#0074AD',
areaColor: "#0494e1",
shadowColor: 'rgba(0, 0, 0, 0.5)',
label : {
show : true
}
}
} ,
markPoint : {//标注
},
data : data //数据
}
],
animation : true
};
mapChart.setOption(option);
}
然后显示出来是:
2.获取数据然后处理 显示在地图对应上,还是上一步的js文件,初始化获取数据并处理成想要的样子,通过补全tooltip实现展现的样式
window.onload=function(){ // 初始化
//1.获取数据[dataList这里 没有捏造一下]
//2.处理数据
data = makeData(dataList);
//3.画地图
initMap('贵州','地市男女比例',data);
}
/**
*捏造数据
*/
var dataList = new Array();
dataList[0] = {name:'贵阳市',allNum:'500',womanNum:'250',manNum:'250'};
dataList[1] = {name:'六盘水市',allNum:'480',womanNum:'200',manNum:'280'};
dataList[2] = {name:'遵义市',allNum:'490',womanNum:'190',manNum:'300'};
dataList[3] = {name:'安顺市',allNum:'800',womanNum:'420',manNum:'380'};
dataList[4] = {name:'毕节市',allNum:'665',womanNum:'365',manNum:'300'};
dataList[5] = {name:'铜仁市',allNum:'720',womanNum:'350',manNum:'370'};
dataList[6] = {name:'黔西南布依族苗族自治州',allNum:'250',womanNum:'150',manNum:'100'};
dataList[7] = {name:'黔东南苗族侗族自治州',allNum:'100',womanNum:'100',manNum:'100'};
dataList[8] = {name:'黔南布依族苗族自治州',allNum:'399',womanNum:'244',manNum:'155'};
dataList[9] = {name:'贵安新区',allNum:'180',womanNum:'90',manNum:'90'};
/**
* 数据处理成数组格式
* @param {Object} dataList
*/
function makeData(dataList){
for(var i = 0; i < dataList.length ; i++){
data.push( {
name : dataList[i].name,//和地图的地市名称对应
value : dataList[i].allNum,
allNum : dataList[i].allNum,
womanNum : dataList[i].womanNum,
manNum : dataList[i].manNum
});
}
return data;
}
/**
* 初始化地图
* @param title
* @param subtext
* @param data
*/
function initMap(title,subtext,data){
//...省略...
var option = {
//...省略...
tooltip:{// 工具提示
show: true,
showContent: true,
trigger: 'item',// 触发类型,默认数据触发,见下图,可选为:'item' | 'axis'
triggerOn : 'mousemove',
enterable: true,
formatter: function(params){
var str ='';
for(var i = 0 ; i < data.length;i++){
if(data[i].name==params.name){// 查询的地址数据包括该地址
str = params.name +'<br />'
+'总人数:'+params.data.allNum+'人'+'<br />'
+'男性数:'+params.data.manNum+'人'+'<br />'
+'女性数:'+params.data.womanNum+'人'+'<br />' ;
}
}
return str;
}
},
//...省略...
};
mapChart.setOption(option);
}
实现的样子:
3....贵安新区的数据没办法显示,有点浪费,人工抠出一个贵安新区;and,要给地市弄个标注点
标注点通过标注点+makePoint实现;
//标注数据数组,从guizhou.js的cp拿来的
var markPointData = [
{
name : '贵阳',
coord : [106.713478,26.578343]
},
{
name : "六盘水",
coord : [ 104.846743,26.584643 ]
},
{
name : '遵义',
coord : [106.937265,27.706626 ]
},
{
name : '安顺',
coord : [105.932188,26.245544]
},
{
name : '毕节',
coord : [105.28501,27.301693]
},
{
name : '铜仁',
coord : [109.191555,27.718346]
},
{
name : '黔西南',
coord : [104.897971,25.08812]
},
{
name : '黔东南',
coord : [107.977488,26.583352]
},
{
name : '黔南',
coord : [107.517156,26.258219]
}
];
/**
* 初始化地图
* @param title
* @param subtext
* @param data
*/
function initMap(title,subtext,data){
var option = {
// ...省略...
//如果鼠标放到标注点要显示经纬的话,改一下工具提示
tooltip:{// 工具提示
// ...省略...
formatter: function(params){
var str ='';
if(params.componentType == 'markPoint'){// 如果是标注点
str = params.name +'<br />'+params.data.coord;
}else{
for(var i = 0 ; i < data.length;i++){
if(data[i].name==params.name){// 查询的地址数据包括该地址
str = params.name +'<br />'
+'总人数:'+params.data.allNum+'人'+'<br />'
+'男性数:'+params.data.manNum+'人'+'<br />'
+'女性数:'+params.data.womanNum+'人'+'<br />' ;
}
}
}
return str;
}
},
series : [ //配置项
{
// ...省略...
markPoint : {//标注
symbol: 'circle',
symbolSize: 12,
symbolOffset : [0,'100%'],
itemStyle : {
normal: {
'color': 'yellow',
label : {
show : false
}
}
},
data : markPointData
},
data : data //数据
}
],
animation : true
};
mapChart.setOption(option);
}
效果如:
贵安新区,目前没有贵安新区经纬度等边界数据,只能通过自定义地图实现
1).http://geojson.io/#map=10/26.3587/106.5578 这个网站可以用来自定义地图,贵安新区在贵阳和安顺之间,所以我引入了贵阳.json来找位置,Open-File,选中贵阳.json,在地图上画出自定义的地图,我画了个五角星,如下:右侧得到五角星的坐标数据,如下下:
2).下载guizhou.js的内容如下,拿到五角星的坐标后,刚开始直接弄成一样的格式放进去,一直报一个好像是t.charCodeAt...的错误,以为是坐标数组的格式不对,的确Polygon 和 MultiPolygon是不同的,前面是三维数组,后者是四维数组,但是改了还是报错,不是这个原因(https://www.oschina.net/translate/geojson-spec#geometry-objects 关于GeoJson的几何类型)
后来发现是因为coordinates不是什么经纬度数据加密,是echarts的压缩算法来着....然后就找了这个压缩的算法,js的...
function encodePolygon(coordinate){
var prevX=0,prevY=0;
var coorstr="";
var encodeOffsets=[];
var result={'coordinate':coorstr,'encodeOffsets':encodeOffsets};
for(var i=coordinate.length-1;i>0;i--){
var x=coordinate[i][0];
var y=coordinate[i][1];
x=x*1024;y=y*1024;
x-=coordinate[i-1][0]*1024;
y-=coordinate[i-1][1]*1024;
x=(x << 1) ^ (x >> 31);
y=(y << 1) ^ (y >> 31);
coorstr=String.fromCharCode(x+64)+String.fromCharCode(y+64)+coorstr;
}
coorstr="@@"+coorstr;
encodeOffsets=[coordinate[0][0]*1024,coordinate[0][1]*1024]
return result;
}
然后就....拿到这两个值,合并到guizhou.js上,cp可以用geojson那个marker点一个
然后看最后的结果,画的有点小,又画了一个...,还有点丑...ε=(´ο`*))):
3)这样就弄完了,不过,鼠标挪到贵阳和安顺的时候,五角星那部分还是会被选中....还有就是这个自定义地图不是真的地图边界,也就是弄出来展示下贵安的数据....