在echaerts中渲染50萬條資料的最佳化方案
感謝大家的點贊和轉發,歡迎大家關注本人的部落格。試用期指導,專案開發,簡歷最佳化,畢業設計/論文,歡迎新增本人微信。
新人作者,歡迎關注和收藏👏🏻👏🏻
背景:專案需求中要在頁面上渲染大約50萬條左右的波形資料圖表
那麼如何解決渲染中的卡頓呢?
肯定是要從服務端和前端一起最佳化這是毋庸置疑的。
1.服務端:
服務端耗時最多的一定是在資料庫的篩選資料的行為上,本次需求中資料的篩選是根據物理量的型別和時間來進行的。
為了提速,應當取消掉其他的篩選條件,並且使用mongodb和redis,還應該將資料分片傳送給前端。
2.前端:
首先我們要搞清楚,最佳化策略的重點是在資料的拿取上,因為渲染的速度其實遠快於資料互動的速度,要想提速首先要解決的是短板。
在資料拿取時我們應當進行輪詢,分片的拿到服務端傳輸的資料,然後進行渲染。
我們來整理一下思路:
1.第一次輪詢結束拿到資料後,我們需要進行繪圖。然後判斷是否進行下一次輪詢
2.第二次輪詢結束之後我們需要將拿到的資料,append到圖表之中,然後判斷否進行下一次輪詢
3.如何隨時的讓輪詢終止。
這三個就是目前我們需要解決的問題點。
第一次拿到資料之後我們判斷資料的長度是否為0,為0則終止輪詢,不為0則繼續。
後面繼續輪詢時,每次輪詢拿到資料都要判斷圖表是否存在,存在就dispose,然後重繪。
要注意的點時,我們的圖表是可以縮放的,所以在重繪時還需要將縮放條的位置進行記錄,然後設定到datazoom裡面,這樣可以提高使用者體驗。
下面貼出程式碼:
getListWaveformDat(count) {
this.loading = true;//載入loading動畫
//獲取波形圖資料
getListWaveformDat({
deviceId: this.queryPointParams.deviceId,
diId: this.diId,
reportedOn: this.orgTime,
keyName: this.dataAxis,
num: this.pageNum,
size: 10000,
count: count ? count : '',
}).then((res) => {
if (res.length > 0) {
this.noData = false//是否載入預設值圖片
console.log(this.orgchart)
if (this.orgchart) {
this.orgchart.dispose();
}
this.oscillograph = res;
let x = [];
for (let i = 0; i < this.oscillograph.length; i++) {
x[i] = this.oscillograph[i].count;
}//處理X軸資料
let y = [];
for (let i = 0; i < this.oscillograph.length; i++) {
y[this.oscillograph[i].count * 1 - 1] = this.oscillograph[i].value * 1
}
for (let i = 0; i < this.oscillographY.length; i++) {
if (this.oscillographY[i] == undefined) {
if (y[i]) {
this.oscillographY[i] = y[i]
}
}
}//處理Y軸資料
console.log(this.oscillographY)
this.pageNum = this.pageNum + 1;//輪詢次數加1
this.$nextTick(() => {
this.orgDraw();//繪製圖表
})
this.loading = false;//關閉載入loading
this.getListWaveformDat(x[x.length - 1])//繼續輪詢
}
else {
//如果載入的資料為空
this.loading = false;
console.log(this.orgchart)
if (this.pageNum == 1) {
//如果第一次輪詢就為空,載入預設圖片
this.noData = true;
if (this.orgchart) {
this.orgchart.dispose();//清除上一次載入的圖表
}
this.pageNum = 1;//請求完所有資料之後初始化一下
return
}
});
},
這是介面返回的資料來源,X就是count,Y就是Value。因為每次輪詢查到的資料都是亂序的,但是圖表要求X,Y必須對應所以需要對資料進行重新排序。
思路:
1.先獲取X軸的長度,然後根據長度生成X,Y兩個陣列。
2.將Y陣列的值都設定為undefined,X陣列的值設為1-X的長度3.遍歷介面的資料,將count作為Y的索引,將value塞入對應的元素中。
getX() {
getMaxCount(
{
deviceId: this.queryPointParams.deviceId,
reportedOn: this.orgTime,
keyName: this.dataAxis,
}
).then((res) => {
console.log(res, '======')
this.oscillographX = Array.from({ length: res * 1 }, (value, key) => key + 1)
this.oscillographY = Array.from({ length: res * 1 }, (value, key) => undefined)
console.log(this.oscillographX);
})
},
處理X,Y軸資料的程式碼在第一個程式碼塊中已經有就不貼了。
完成資料處理之後就是進行繪圖。
orgDraw() {
let that = this;
if (this.orgchart) {
this.orgchart.dispose();
}
console.log(this.start, this.end, 'xxx')
if (this.tabname !== "原始資料") {
return;
}
// if (this.orgchart) {
// this.orgchart.dispose()
// }
var chartDom = document.getElementById("orgChart");
var myChart = echarts.init(chartDom);
const option = {
title: {
left: "center",
text: "原始資料",
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
grid: {
bottom: 90,
},
dataZoom: [{
type: 'inside',//圖表下方的伸縮條
show: true, //是否顯示
realtime: true, //拖動時,是否實時更新系列的檢視
start: this.start, //伸縮條開始位置(1-100),可以隨時更改
end: this.end, //伸縮條結束位置(1-100),可以隨時更改
},
{
type: 'slider',//圖表下方的伸縮條
show: true, //是否顯示
realtime: true, //拖動時,是否實時更新系列的檢視
start: this.start, //伸縮條開始位置(1-100),可以隨時更改
end: this.end, //伸縮條結束位置(1-100),可以隨時更改
}
],
xAxis: {
data: this.oscillographX,
silent: false,
splitLine: {
show: false,
},
splitArea: {
show: false,
},
},
yAxis: {
},
series: [
{
// seriesIndex: 9,
type: "line",
data: this.oscillographY,
large: true,
},
],
};
console.log(myChart.appendData)
myChart.setOption(option, true);
// myChart.appendData({
// seriesIndex: 0,
// data: this.oscillographY
// })
myChart.on('datazoom', function (params) {
// let xAxis = myChart.getModel().option.xAxis[1];//獲取axis
console.log(params.batch[0].end, params.batch[0].start, 'xAxis')
that.start = params.batch[0].start;
that.end = params.batch[0].end;
});//記錄datazoom的滾動距離
this.orgchart = myChart;
this.isStart = false;
return;
},
繪圖中唯一需要做的就是記錄datazoom的滾動進度拿到start和end重繪之後進行賦值。
總結一下:處理的思路就行以一萬條資料為一次不斷進行輪詢,將資料不斷的拼接,然後重新繪圖。為什麼不用echarts提供的appendData()方法呢?因為根本不支援。
感謝大家的點贊和轉發,歡迎大家關注本人的部落格。試用期指導,專案開發,簡歷最佳化,畢業設計/論文,歡迎新增本人微信。
新人作者,歡迎關注和收藏👏🏻👏🏻
覺得作者寫的不錯或者心情愉悅的老闆也可以投幣打賞,感謝觀看,希望能給大家帶來幫助
相關文章
- 每頁500條資料的渲染優化思路(1)優化
- Oracle中的sql%rowcount在瀚高資料庫中的相容方案OracleSQL資料庫
- MySql資料庫最佳化的幾條核心建議MySql資料庫
- vue中echarts的動態渲染資料watchVueEcharts
- 在 Apache Cassandra 中定義和最佳化資料分割槽Apache
- 條件渲染
- Django form在模版中的渲染方式DjangoORM
- 在資料二十條中我們能夠發現什麼
- 二十三、資料庫效能最佳化方案資料庫
- 效能優化小冊 - 渲染十萬條資料:基於 IntersectionObserver 的虛擬列表優化Server
- react 條件渲染React
- SpreadJS 在資料填充時的公式填充方案JS公式
- Android ListView中複雜資料流的高效渲染(一)AndroidView
- DMap(諦聽)——實戰Vue百萬條資料渲染表格元件開發Vue元件
- 大資料交叉報表效能最佳化案例(方案)大資料
- 數字水印在資料安全保護中的應用實踐和最佳化
- 向資料庫中插入一條新的資料,並返回新增資料的ID資料庫
- 在Unity中渲染一個黑洞Unity
- 在小程式當中渲染樹
- sql 多組條資料取最新的一條資料SQL
- 遨翔在知識的海洋裡----(apicloud之dot模板渲染資料)APICloud
- MyBatis 查詢資料時屬性中多對一的問題(多條資料對應一條資料)MyBatis
- (資料科學學習手札91)在Python中妥善使用進度條資料科學Python
- 在Linux中,如何進行網路資源的最佳化?Linux
- 在Linux中,如何進行系統資源的最佳化?Linux
- Unity效能最佳化GPU渲染最佳化UnityGPU
- Elasticsearch在資料湖中的地位Elasticsearch
- 資料加密技術在資料安全中的作用加密
- Firedac 在資料表中插入BLOB資料的方法
- Vue 基礎自查——條件渲染和列表渲染Vue
- Mysql資料庫大表最佳化方案和Mysql大表最佳化步驟MySql資料庫
- 理解笛卡爾積在資料庫查詢中的實際應用與最佳化資料庫
- Vue基礎-條件渲染Vue
- Vue透過引入cdn方式請求介面,渲染資料,axios渲染資料VueiOS
- 【譯】React的8種條件渲染方法React
- WebGIS 利用 WebGL 在 MapboxGL 上渲染 DEM 三維空間資料Web
- 資料庫安全審計在資料安全中的功能資料庫
- Vue.js條件渲染與列表渲染指南Vue.js