![cover](https://img-blog.csdnimg.cn/38ea1a90e379447c8da753df2f7cc458.png)
vue echarts5.0版本使用appendData大数据量分片加载60万个GPS点
需求:将大量GPS数据点渲染在中国地图上 (后续数据量可达百万级,目前未实验,国庆节以后再进行测试)数据格式: [[118.17681,39.66119], [117.88331, 33.195477], ...]echarts版本:5.0.2效果(10W)。渲染速度非常快,这与我们设置的large和largeThreshold有关;<script>// charts实例不要放在dat
·
需求:将大量GPS数据点渲染在中国地图上 (后续数据量可达百万级,目前未实验,国庆节以后再进行测试)
数据格式:
[[118.17681,39.66119], [117.88331, 33.195477], ...]
echarts版本:5.0.2
效果(10W)。渲染速度非常快,这与我们设置的large和largeThreshold有关;
<script>
// charts实例不要放在data里,echarts.init原型链绑一大堆对性能不友好
let charts = null;
export default {
data() {
return {
// ES5新增特性,冻结对象,阻止修改现有属性;
// 如果你有非常庞大的数组,确定不会修改他们,可以使用Object.freeze()大幅提升性能。
dataList: Object.freeze([]),
// 模拟批次请求
xmlPath: [
"gis_1.txt",
"gix_2.txt",
"gis_3.txt",
"gis_4.txt",
"gis_5.txt",
],
xmlCount: 0,
}
}
}
</script>
切换页面销毁echarts实例(未使用keepAlive请使用beforeDestroy)
// 销毁时清除计时器,释放内存
deactivated() {
charts && this.$echarts.dispose(charts);
},
后台未提供接口,给出了几个txt文件先请求测试一下(部分截图)
init() {
// 初始化,因为使用了keepAlive来回切换dataList不会清空;
this.xmlCount = 0;
this.dataList = Object.freeze([]);
this.getXml(this.xmlPath[0]);
// ...省略部分代码,直接贴出来setOptions
charts.setOption({
tooltip: {
show: false,
},
geo: [
{
map: "china-contour",
zoom: 1.2, //当前视角的缩放比例
zlevel: 0,
center: [105, 36], // 调整地图位置
label: {
show: false,
},
silent: true,
itemStyle: {
areaColor: "rgba(0,0,0,0.45)",
borderColor: "#2F5DBE", // 地图边框颜色
borderWidth: 4,
shadowColor: "rgba(46,255,243,0.6)",
shadowBlur: 100,
},
},
{
map: "china",
zoom: 1.2, //当前视角的缩放比例
center: [105, 36], // 调整地图位置
label: {
show: true, // 省份名称展示
textStyle: {
color: "#AFB7C9", // 省份文字颜色
fontSize: 10,
},
},
// 高亮
emphasis: {
label: {
show: true,
textStyle: {
color: "#AFB7C9", // 省份文字颜色
fontSize: 10,
},
},
itemStyle: {
areaColor: "rgba(0,0,0,0.8)",
borderColor: "#204CA3",
borderWidth: 1,
color: "rgba(0,0,0,0.5)",
},
},
itemStyle: {
areaColor: {},
borderColor: "#204CA3", // 地图内边框颜色
borderWidth: 1,
},
},
],
series: [
{
type: "scatter",
coordinateSystem: "geo",
// 'lttb' 采用 Largest-Triangle-Three-Bucket 算法,可以最大程度保证采样后线条的趋势,形状和极值。
// 'average' 取过滤点的平均值
// 'max' 取过滤点的最大值
// 'min' 取过滤点的最小值
// 'sum' 取过滤点的和
sampling: "lttb", // 数据量远大于像素点时候的降采样策略
data: [],
itemStyle: {
color: "#27d5ec",
shadowBlur: 10,
shadowColor: "#333",
},
symbolSize: 1,
large: true,
// 大规模阀值,large为true且数据量>largeThreshold才启用大规模模式
largeThreshold: 500,
},
],
});
this.$resize.on(byId, () => charts && charts.resize());
}
}
模拟请求
getXml(path) {
let xhr = newXMLHttpRequest();
xhr.open("get", path, true);
xhr.responseType = "arraybuffer";
let that = this;
xhr.onload = function (e) {
let unit8_msg = new Uint8Array(this.response);
let len = unit8_msg.length;
// 解码为字符串
let binary = "";
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(unit8_msg[i]);
}
let res = JSON.parse(binary);
let data = [];
// 因为文件里数据格式不符合我们想要的格式,所以需要对数据格式进行处理
// 这里判断奇偶数来判断经纬度提取为一组
res.forEach((item, index) => {
if (index % 2 === 0) data.push([item, res[index + 1]]);
});
that.dataList = Object.freeze(data);
// 分片渲染
charts.appendData({
seriesIndex: 0,
data: that.dataList,
});
};
xhr.send();
xhr.onloadend = function () {
that.xmlCount += 1;
if (that.xmlPath.length > that.xmlCount) {
that.getXml(that.xmlPath[that.xmlCount]);
} else {
console.log("请求完成");
}
};
}
如果浏览器打开了多个标签页,我们在切换其他标签页时候或者使浏览器缩在后台,长时间会使项目挂在后台会导致echarts内存不断增加,导致崩溃(原因是只有打开当前标签页时,内存才会释放),此时可使用visibilitychange来监听是否切换标签页进行清除和渲染的操作;
// 监听窗口变化
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
// 隐藏
// 清除示例
} else {
// 显示
// 渲染
}
});
总结:
- 使用Object.freeze()大幅提升性能。
- large 和 largeThreshold
- appendData分片渲染,多次渲染不会覆盖之前的数据
- echarts实例的性能优化
a: charts实例不要放在data里
b: 及时销毁实例
————————11.19日——分批次请求接口
<script>
let dataList = []; 放在script里
export default { ... }
...
methods:
// 获取gps点
getGeoPoint(index) {
GeoPoint({ page: index }).then((res) => {
// console.log(res);
// 渲染
const data = res.data;
charts.appendData({
seriesIndex: 0,
data,
});
index--;
dataList.push(Object.freeze(data));
if (index < 0) {
return;
}
this.getGeoPoint(index);
});
},
appendData() {
if (dataList.length) {
const list = Object.freeze(dataList);
// 增加timeout原因是,dataList变量存有大量数据,来回切换页面会卡顿一下,增加timeout延迟foreach循环 为的就是先把页面加载出来
setTimeout(() => {
list.forEach((data) => {
charts.appendData({
seriesIndex: 0,
data: data,
});
});
}, 1200);
} else {
this.getGeoPoint(103);
}
},```
更多推荐
所有评论(0)