背景:项目需求中要在页面上渲染大约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()方法呢?因为根本不支持。
标签:end,轮询,echaerts,50,start,万条,console,数据,orgchart From: https://www.cnblogs.com/SadicZhou/p/17191138.html