最近在工作项目中遇到一个绘制地图轮廓,并且在地图上根据需求里的学校位置打点,从最初的无从下手到最后完成,中间是边看echarts([echarts官网文档][1])文档边尝试,开了一个好头后面越写越顺利,因此谨以此篇文章记录下我本次学习的过程。
然后说说地图的实现思路:
- 首先需要绘制出地图轮廓;
- 请求接口数据,然后在地图上打点;
- 地图上的学校点击时异步加载学校数据
现在开始说正经的:
第一步:绘制地图轮廓
在绘制地图的准备工作中,需要事先准备好需要绘制的地区的json文件(主要是区域轮廓图的一些重要拐点经纬度,地图就是依靠它一个点一个点连线绘制出来滴),大概长这样:
然后在代码导入并中注册:
import echarts from 'echarts'
var config = require('../../../../static/mock/conf')
var dingnan = require(`../../../../static/mock/${config.map}`)
echarts.registerMap('dingnan', dingnan)
前两句代码基本上可以合并成一句,其意思是说给这个地图Json起了个名字,引入的时候要对号入座(还有其他地域地图)。。。
这一步完成之后,相当于地图已经注册了,但是需要一个载体来呈现它,这时候echarts就出场了:
当程序解析到
mounted() {
this.mapChart = this.$refs.map.chart
this.mapOption = makeMapOption()
},
第二步:地图打点
这里就需要异步请求接口了,根据后台返回的数据看看该在哪里打点,打点最重要的两个参数就是经度和纬度啦,接口返回的数据大概长这样:
这个latitude和longitude就是每个学校的经纬度了,而schoolCode则是我们在第三步需要用到的重要参数,接下来就是拿着这些数据封装成我们地图中所需要的结构:
分别是打点的学校的名字,学校id,经纬度,学校类别...
之后传到刚才说的方法中去,echaerts图表参数主要部分series中其中一个项大概就是这样滴(这个截图对应的是文章开头第一张图中的黄色点学校,该地区高中中职在我们系统中的就这两...,同理小学初中,完全中学,教育局也是一样滴,不同就是经纬度和颜色啦,看到这里如果懵了的话,不要捉急,代码被我截图拆的四零八散,最后我会附上完整代码滴~~~~):
到这地图打点算是完成了,效果就是图一的样子,但是只有地图和点,没有其他信息,看官也不知道这些点到底是干嘛滴不是吗,所以再看
第三步:异步获取地图上某个点的信息
其实本来是很简单的一个echarts图表中的tooltip,就是像echarts官网中的许多例子一样,鼠标放上去出现一个小tips,有什么系统名啊,本item的值啊,百分比啊云云,but我们的需求不按常理出牌啊,tips上的文字是自定义滴,需要展示的数据还是需要请求滴,一开始我还是不会滴...
就是图上红框框里那个玩意儿~~
于是我又去看了看echarts官网关于formatter链接描述的部分,
划重点aaaaaa
第二个参数 ticket 是异步回调标识,配合第三个参数 callback 使用。 第三个参数 callback 是异步回调,在提示框浮层内容是异步获取的时候,可以通过 callback 传入上述的 ticket 和 html 更新提示框浮层内容。
(感谢官网大大)
然后怎么办?--硬着头皮写啊,异步请求啊,连接字符串啊,显示啊,上代码:
tooltip: {
show: true,
triggerOn: 'click',
backgroundColor: 'rgba(10, 17, 64, 0.8)',
formatter(value, ticket, callback) {
let _this = this
fetchSchoolDeatail({ unitCode: value.data.schoolCode }).then(({ data, headers }) => {
let info = data.data
let str = `
${value.name}
${info.bxTypeName}
在册学生
${info.studentNum}人
在册职工数
${info.teacherNum}人
今日到校学生数
${info.studentArriveSchoolNum} 人
今日到校职工数
${info.teacherArriveSchoolNum}人
`
callback(ticket, str)
}).catch(err => {
console.dir(err)
_this.$message.error(err.message || '获取学校信息失败,请稍后再试')
}).finally(() => {
console.log(1)
})
return '加载中...'
}
},
有几点说明:
- 为了避免鼠标划过地图点就请求接口导致接口卡顿,触发tooltip的方法改成了click,也就是点击一下学校点才会加载学校信息接口数据;
- 由于接口请求发送到成功返回需要一点时间,刚一点上去可能是空白或者tips没出来,所以点击那一瞬间tips显示的是“加载中...”,这就是最外层的return;
- 当数据加载完成之后必须要写callback(ticket, str),这是人家formatter回调函数规定滴,ticket异步标识不能改,否则不返回任何东西。
至此呢,整个地图绘制,打点,加载点信息就完成了,下面补充几个我在写代码时的注意项:
- 绘制图表的点的样式可以是一般的ciecle圆点或者rect方形,也可以自定义,比如我地图中的教育局图表,就是引入了一张图片
const starImg = require('../../../assets/images/secondBg/star.png')
引入以后vue自己转化成了base64的编码,然后我们在需要使用的地方是“image://http://xxx.xxx.xxx/a/b.png”这种格式,我们自己需要加上'image://'这段字符,
icon: `image://${starImg}`
- 为了方便操作地图上的点,不和页面上其他部分重叠,我设置了地图鼠标缩放和平移漫游(geo坐标系中的roam),也就是鼠标在地图区域内的时候可以拖拽地图移动位置,也可以通过滑轮放大缩小地图面积,有个小瑕疵是有时候拖拽完之后鼠标已经没有左键右键控制了,但是鼠标一挪动,地图还是会跟着走,只有在地图之外的空白处点一下才会丢下拖拽。。。
- 本地图series中共有4个不同类型的数据组合,有的点经纬度离得近,地图缩小时会看上去重合,这时候就需要设置好每个类型的zlevel值,这是为了给每个类型绘制canvas时分层,不至于累在一起看不到别的点
最后附上我的全部代码
最后再啰嗦一下,我的地图小点点是一颗颗闪亮的小星星,这个主要设置好散点的颜色,涟漪点的圈圈数量,闪动的时间,就很好看啦,我的代码里都有注释。
第一次写这么多字,有点小鸡冻,分享就这么多了,如果您有幸看到了我的文章,希望能对您遇到的问题有所帮助,与君共勉,fighting!