vue+高德地图AMap.Polyline画折线+大量数据渲染优化+echarts图表自适应容器
零、本文主要分享内容预先浏览,
1.vue中使用高德地图,画折线,以及给折线定义点击事件。
2. 大量数据加载时,边加载边渲染到页面。
3. vue中,echarts图表自适应容器宽度。
一、vue中的高德地图画线
高德文档:https://lbs.amap.com/api/javascript-api/reference/overlay#polyline
0、先看效果图:
1、在vue项目里的index.html 页面引入高德地图使用的**等过程略过...
2. 在methods对象里 地图初始化:
//在地图初始化的时候,进行地图相关配置
let map = new AMap.Map('map', {
zoom: 14,
center: [110.554465,19.805683],
resizeEnable: true,
rotateEnable: false,
pitchEnable: true,
rotation: 0,
buildingAnimation: true,
showLabel: true,
showTraffic:true,
expandZoomRange:true,
});
3、在methods对象里,使用AMap.Polyline 折线:
//初始化折线,进行折线先关属性配置
let that = this
let currentline = null //用于存放被点击的目标折线对象
let polyline = new AMap.Polyline({
map:map, //初始化的地图变量
path: path, //折线的存放数组,很重中。一般是好多经纬度组成的数组。
extData: { id:streetId} , //每段折线的id
outlineColor: 'orange',
strokeColor: "orange",
strokeOpacity: 0.6,
strokeWeight: 4,
borderWeight:1,
strokeStyle: "solid",
strokeDasharray: [0,0,0],
lineJoin: 'round',
lineCap: 'round',
zIndex: 20
});
// 折线的点击事件
polyline.on('click',function(event){
//当折线被点击时,设置当前折线的相关属性配置
polyline.setOptions({
outlineColor: '#31f4e6',
strokeColor: "#31f4e6",
strokeOpacity: 1,
strokeWeight: 8,
borderWeight:3,
zIndex: 25
});
//判断是否存在目标折线currentline ,有的话,重新进行属性配置。我这里是要恢复原样。
if(currentline){
that.currentline.setOptions({
outlineColor: 'orange',
strokeColor: "orange",
strokeOpacity: 0.6,
strokeWeight: 4,
borderWeight:1,
zIndex: 20
})
}
//将目标折线赋值给currentline 变量保存
currentline = polyline;
},lineId)
// 设置折线在地图上。
polyline.setMap(map)
二、vue中 大量数据渲染优化:
vue中高德地图要加载好多线路数据时,渲染时就会很卡,所以我们可以边加载边渲染。
0、效果图:
1、核心思想:
通过异步请求回调,将接口返回的数组进行分组渲染。
通过.then()方法,执行请求成功时的函数回调。只有当前的.then()方法执行完毕后,才去执行下一个.then()方法。
当前.then()方法,必须要有数据返回,供下一个.then()方法使用。负责,下一个.then()没有数据使用,没有存在的意义。
提示:此方法是一种思想,其它框架,类库都可以使用
//请求后端返回的线路数据
init_CityStreet(callback){
let that = this
let map = that.amap
// $.when() 方法来执行零个或多个( Thenable \ then \ Deferred ) 对象的回调函数,通常是表示异步事件, 如果没有参数传递给 jQuery.when(),它会返回一个resolved状态的Promise。
切记 : 如果传参数 那么 他将永远返回的是 成功 的状态, 失败定义的回调函数, 永远不会被执行, 因为不会遭到拒绝
如果传参是 不是一个 Deferred 或 Promise 对象, 那么他将永远返回的是 成功 的状态, 失败定义的回调函数, 永远不会被执行, 因为不会遭到拒绝。
//使用说明 $.when(参数1, 参数2, 参数3...)
此方法接受多个参数, 但是返回的结果却是不一样的, 但是无非还是两种状态, 一种成功时的状态, 一种失败时的状态
成功时的状态 : 必须所有的对象都返回成功, 才会返回成功的回调函数
失败时的状态 : 如果其中只要有一个返回失败, 都会返回失败的回调函数
如果定义函数的时候给了参数, 调用函数的时候没给参数, 那么值将会是 undefined
// 利用$.when() 方法执行多个 .then()方法的回调函数
$.when(
$.ajax({
type: 'GET',
url: './static/data/hkjiejing_GCJ02.json'
})
.then((data)=>{ //.then() 表示异步请求成功时的回调函数,支持链式编程。
data = data.features
let load1 =null
that.asyncLoadStreet(data,load1,0,50,map) //调用画图方法,首先加载渲染当前数据的50条数据。
return data // 数据渲染成功后,返回剩余的数据(去除已处理的50条)
})
.then((data)=>{
let load2 =null
that.asyncLoadStreet(data,load2,0,100,map) //调用画图方法,首先加载渲染当前数据的100条数据。 下面几个.then() 此处代码执行意义相同
return data // 数据渲染成功后,返回剩余的数据(去除已处理的50条+100条数据)。下面几个.then() 此处代码执行意义相同。
})
.then((data)=>{
let load3 =null
that.asyncLoadStreet(data,load3,0,250,map)
return data
})
.then((data)=>{
let load4 =null
that.asyncLoadStreet(data,load4,0,400,map)
return data
})
.then((data)=>{
let load5 =null
that.asyncLoadStreet(data,load5,0,400,map)
return data
})
.then((data)=>{
let load6 =null
that.asyncLoadStreet(data,load6,0,400,map)
return data
})
.then((data)=>{
let load7 =null
that.asyncLoadStreet(data,load7,0,400,map)
return data
})
.then((data)=>{
if(data){
let load7 = data
that.SplitArray(load7,map)
}else{
that.$message({
message: '没有数据返回',
type: 'warning'
})
}
})
.catch((err)=>{
that.$message({
message: '没有数据返回出现错误',
type: 'error'
})
})
)
},
// 将接口返回的总数据进行分组
asyncLoadStreet(data,loadNum,count1,count2,map){
let that = this
if(data){
loadNum = data.splice(count1,count2) //splice切割数组,将被切割的部分组成新数组,会改变原数组。
that.SplitArray(loadNum,map)
}else{
that.$message({
message: '没有数据返回',
type: 'warning'
})
}
},
SplitArray(features,map){
let that = this
let countArr = [] //存储被分割的临时数组
let count = 50 //以50条数组为一组,进行分割
for(let i=0;i<features.length;i+=count){
countArr.push(features.slice(i,i+count))
}
if(countArr.length === 0){
that.$message({
message: '没有分组数据',
type: 'warning'
})
}
for(let i=0;i<countArr.length;i++){
that.loadStreet(countArr[i],map) //循环加载地图折线。
}
},
// 高德地图 AMap.Polyline 渲染地图折线,详情见上面。
loadStreet(loadArr,map){
let that = this
if(loadArr.length === 0){
that.$message({
message: '没有路线数据',
type: 'warning'
})
}else{
for(let i =0;i<loadArr.length;i++){
let path = loadArr[i].geometry.coordinates
let streetId = loadArr[i].properties.ID
// 定义地图连接先
let polyline = new AMap.Polyline({
map:map,
path: path,
extData: { id:streetId} ,
outlineColor: 'orange',
strokeColor: "orange",
strokeOpacity: 0.6,
strokeWeight: 4,
borderWeight:1,
strokeStyle: "solid",
strokeDasharray: [0,0,0],
lineJoin: 'round',
lineCap: 'round',
zIndex: 20
});
let lineId = null;
polyline.on('click',function(event){
polyline.setOptions({
outlineColor: '#31f4e6',
strokeColor: "#31f4e6",
strokeOpacity: 1,
strokeWeight: 8,
borderWeight:3,
zIndex: 25
});
lineId = polyline.getExtData().id
that.dlid = lineId;
that.init_streetDataNew(lineId);
if(that.currentline){
that.currentline.setOptions({
outlineColor: 'orange',
strokeColor: "orange",
strokeOpacity: 0.6,
strokeWeight: 4,
borderWeight:1,
zIndex: 20
})
}
that.currentline = polyline;
},lineId)
polyline.setMap(map)
}
}
}
三、vue中echarts图表自自适应容器
echarts 图表自适应容器,一直是一个令人头痛的问题。我提供一个方法,仅仅三步,就可解决此问题。
0、先看效果图:
1. 复制该esresize.js文件到你项目里
文件提取(暂定为一段时间内有效):链接:https://pan.baidu.com/s/1wwUBD_8kdidmCVX92E0DYw
提取码:xgco
var EleResize = {
_handleResize: function (e) {
var ele = e.target || e.srcElement
var trigger = ele.__resizeTrigger__
if (trigger) {
var handlers = trigger.__z_resizeListeners
if (handlers) {
var size = handlers.length
for (var i = 0; i < size; i++) {
var h = handlers[i]
var handler = h.handler
var context = h.context
handler.apply(context, [e])
}
}
}
},
_removeHandler: function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (handlers) {
var size = handlers.length
for (var i = 0; i < size; i++) {
var h = handlers[i]
if (h.handler === handler && h.context === context) {
handlers.splice(i, 1)
return
}
}
}
},
_createResizeTrigger: function (ele) {
var obj = document.createElement('object')
obj.setAttribute('style',
'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden;opacity: 0; pointer-events: none; z-index: -1;')
obj.onload = EleResize._handleObjectLoad
obj.type = 'text/html'
ele.appendChild(obj)
obj.data = 'about:blank'
return obj
},
_handleObjectLoad: function (evt) {
this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__
this.contentDocument.defaultView.addEventListener('resize', EleResize._handleResize)
}
}
if (document.attachEvent) { // ie9-10
EleResize.on = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (!handlers) {
handlers = []
ele.__z_resizeListeners = handlers
ele.__resizeTrigger__ = ele
ele.attachEvent('onresize', EleResize._handleResize)
}
handlers.push({
handler: handler,
context: context
})
}
EleResize.off = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (handlers) {
EleResize._removeHandler(ele, handler, context)
if (handlers.length === 0) {
ele.detachEvent('onresize', EleResize._handleResize)
delete ele.__z_resizeListeners
}
}
}
} else {
EleResize.on = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (!handlers) {
handlers = []
ele.__z_resizeListeners = handlers
if (getComputedStyle(ele, null).position === 'static') {
ele.style.position = 'relative'
}
var obj = EleResize._createResizeTrigger(ele)
ele.__resizeTrigger__ = obj
obj.__resizeElement__ = ele
}
handlers.push({
handler: handler,
context: context
})
}
EleResize.off = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (handlers) {
EleResize._removeHandler(ele, handler, context)
if (handlers.length === 0) {
var trigger = ele.__resizeTrigger__
if (trigger) {
trigger.contentDocument.defaultView.removeEventListener('resize', EleResize._handleResize)
ele.removeChild(trigger)
delete ele.__resizeTrigger__
}
delete ele.__z_resizeListeners
}
}
}
}
export {EleResize}
2. 在编写echarts页面里引入该文件
3. 在echarts方法中调用EleResize方法。
四、js部分代码截图:
水平有限,如有错误请指出,如果更好的实现方法,感谢回复。感谢观看。