背景:项目需求中要在页面上渲染大约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()方法呢?因为根本不支持。

在echaerts中渲染50万条数据的优化方案的更多相关文章

  1. 性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿

    列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表 思路 列表中固定只显示少量的数据,比如60条 在列表滚动的时 ...

  2. 数据库已经最优,每次操作50万条数据,怎么提高API接口的速度?

    第一种可以使用负载均衡,10台,就每台5W条数据第二种每台机器.可以把添加任务队列.利用多线程解决IO密集型任务的特点.第三种利用异步协程方式提高调度行为

  3. mysql如何在一张表中插入一万条数据?(用存储过程解决)

    写一个存储过程,里面写一个循环,就可以了.主键你现在不是自增的,所以写语句的时候,就Insert到3个字段中. DELIMITER $$ DROP PROCEDURE IF EXISTS `proc_ ...

  4. Oracle中插入100万条数据

    在做项目的工程中,需要数据库中存在大量的数据进行程序的验证,但是我们又没有数据,这时就需要我们自己手动建一个表,插入大量数据,进行验证. 那么插入大量数据的sql语句如下: insert into E ...

  5. Qt中提高sqlite的读写速度(使用事务一次性写入100万条数据)

    SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度.例如:向数据库中插入100万条数 ...

  6. JavaScript如何一次性展示几万条数据

    有一位同事跟大家说他在网上看到一道面试题:“如果后台传给前端几万条数据,前端怎么渲染到页面上?”,如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成 ...

  7. 极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

    链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量 ...

  8. 主要看思路:区域数据去重 + JavaScript一次性展示几万条数据实例代码

    近期做1功能,Gis地图 基于百度地图api , 会遇到的问题的, 如后台接口给的数据很多,大几千上万的,如果拿了数据直接渲染dom ,这滋味爽爽的. 再遇上 客户端浏览器悲催的,这卡顿就来了... ...

  9. 插入1000万条数据到mysql数据库表

    转自:https://www.cnblogs.com/fanwencong/p/5765136.html 我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入100 ...

  10. [Python] 通过采集两万条数据,对《无名之辈》影评分析

    一.说明 本文主要讲述采集猫眼电影用户评论进行分析,相关爬虫采集程序可以爬取多个电影评论. 运行环境:Win10/Python3.5. 分析工具:jieba.wordcloud.pyecharts.m ...

随机推荐

  1. 点击div实现选中效果

    先上一份效果图.原来的checked多选框还是存在的,我只不过隐藏了,让他的整个div的范围都是可以点击的,右上角三个点是可以删除当前元素,左下角的播放按钮可以点击播放语音,主要是利用z-index把 ...

  2. 12. Redis 安装

    参考http://www.runoob.com/redis/redis-install.html Window 下安装 下载地址:https://github.com/MSOpenTech/redis ...

  3. 新centos6 静态ip 放行端口 hosts主机名 jdk环境变量

    0 jdk 环境变量 vi  /etc/profile source /etc/profile 刷新环境变量 在尾部增加如下代码: #JDK全局环境变量配置export JAVA_HOME=/usr/ ...

  4. LCP 34. 二叉树染色

    class Solution: def maxValue(self, root: TreeNode, k: int) -> int: def dfs(root): # 空节点价值全为0 res ...

  5. 【python基础笔记-3】decimal模块解决浮点数计算精度问题

    通过Decimal('123.456')对象实例化后做 + - * / 等运算符操作计算结果不会出现精度问题. Tips:值得注意的2点是 1.Decimal接收的入参是str,所以如果原本操作的数据 ...

  6. 【Android异常】关于Notification启动时,startForeground报错

    遇到两个报错: 第一个权限问题报错,好解决 startForeground requires android.permission.FOREGROUND_SERVICE Manifest给下权限就行 ...

  7. PINNs的网络大小与过拟合

    PINNs中网络越大时,会不会产生过拟合呢 虽然PINNs可以不用到数据,但是我认为物理约束所带来的信息也是有限的 因此当网络变得很大时,也有可能产生过拟合现象吧 但是在神经元分裂那篇文章中,训练停滞 ...

  8. ssh问题、原理及diffie hellman算法

    1.普通用户无法使用证书登录:原因是权限设置问题 将.ssh目录设为700,authorized_keys设为600即可. 2.查看ssh支持的算法 ssh -Q help ssh -Q kex/ke ...

  9. 阿里云centos7 磁盘挂载

    适用于多磁盘的情况 1. 查看本地所有磁盘 fdisk -l 2.格式化磁盘系统 mkfs.ext3 /dev/vdb  (/dev/vdb  为未挂载的磁盘路径) 2.创建挂载点 mkdir /ho ...

  10. .NET实验二

    实验名称:实验二 面向对象程序设计 一. 实验目的 1. 理解类的定义.继承等面向对象的的基本概念: 2. 掌握 C#语言定义类及其各种成员(字段,属性,方法)的方法: 3. 掌握方法覆盖的应用: 4 ...