echart实现动态折线图(vue3+ts)

最近接到个任务,需要用vue3实现动态折线图。之前没有用过,所以一路坎坷,现在记录一下,以后也好回忆一下。

之前不清楚echart的绘制方式,以为是在第一秒的基础上绘制第二秒,后面实验过后,发现并不是,它是每秒都重新绘制整张图。比如现在data里只有一个数据,那他就是一个点;过一秒之后data里新增一个数据,那么就有两个点,一条线段,依次类推。

话说回来,怎么实现动态的折线图,回想视频的原理,也就是一帧帧的图片快速切换,欺骗人眼产生动态的效果。所以折线图,也是如此,需要设定一个重要的maxLength,当data里的数据长度到达这个maxLength,使用shift()函数去掉data里的第一个数据,新的data数组和旧的data数组不同,这样两个画面绘制切换,就形成了动态的效果。

好了,现在有了基本理论,该干活了。任务是生成一段折线图如图所示:

t0是当前时刻点,左边实线是历史数据,右侧数据是预测数据,预测数据根据当前时刻点进行变化。但是echart没办法实现一个数据前面实线后面虚线,只能分成两个数据来拼接,假设现在只需要一个静态的画面,那么可以这样实现:建立一个数组data,[历史数据,预测数据]这样的形式划分,然后分别绘制不同的线段。但是现在需要动态展示。。。

        折腾了许久,有了第一版的设计:设计历史数据只显示在x轴的2/3,预测数据全部显示,那么超出的预测数据部分就好像是对历史数据的一种预测,效果如图:

        对面在看了这种效果之后,觉得还可以。我也就草草实现,没管细节了。结果过了几天告诉我,增加需求:要求可以显示距离报警时间还有多久以及报警之后还有多久报警解除。这个逻辑上是好加的,很简单。按照这样的思路:

        第一如果dataPoint小于outlier且predictions数组里的值都小于outlier的时候显示“状态正常”;第二如果dataPoint小于outlier,但是predictions数组里的值有值大于等于outlier的时候,取第一个满足这个条件的值的索引x,显示“距离实际报警还有x分钟”;第三如果dataPoint大于等于outlier且predictions数组里的值都大于等于outlier的时候显示“已报警,未来持续一段时间”;第四如果dataPoint大于等于outlier,但是predictions数组里的值有值小于outlier的时候,取第一个满足这个条件的值的索引x,显示“已报警,距离警报解除还有x分钟”; dataPoint和predictions都是在updateData中定义变化的。

        dataPoint表示实时值,outlier表示阈值,predictions表示实时值对应的预测数据数组。

        实战显示,折线图真实情况和对应标题总是对不齐,说明这两条线有大问题。之前只是大概满足这个形式,这回需要精确到点,所以暴露问题了。

        问题1:历史数据每秒增加1个点,预测数据每秒增加15个点(大于1个点)

        问题2:根据echart的绘制机制,二者动起来的方式都是先到达设定的最大长度,且刚开始都是从最左边开始绘制,所以如果按照一般形式,二者根本对不齐。

        这里开始尝试很多解决办法,首先是预测数据的存储方式。比如现在是

第一秒:历史数据是a,预测数据是1,2,3,那么预测队列为1,2,3;

第二秒:历史数据是b,预测数据是4,5,6,那么预测队列为1,4,5,6;

第三秒:历史数据是c,预测数据是7,8,9,那么预测队列为1,4,7,8,9;

以此类推,对应算法:

保留原预测数据的第一个值,加上新的预测数据if (currentState.currentResponse === null) {// 第一次接收数据currentState.currentResponse = response;allPredictedData.value[extractedName] = [...response];} else {// 将前一次的response第一个值添加到历史currentState.prevFirsts.push(currentState.currentResponse[0]);// 更新当前响应currentState.currentResponse = response;// 合并历史数据和新数据allPredictedData.value[extractedName] = [...currentState.prevFirsts,...currentState.currentResponse];}

        由于数据预测的折线图是子组件,所以传值也是个问题。之前值都是存在子组件的,但是这个样子和父组件失去同步,因为父组件有个实时值显示,模拟真实情况传感器的数据。如果分开的话,父组件的值都走完了,点开数据预测界面发现从第一秒开始,那么就露馅了。由于父组件不是我写的,所以看起来也是脑袋大。

        可算改完了,这回实时值和预测值都由父组件提供,子组件只负责数据的显示。蛋疼的是数据预测是向服务器请求的,所以其实实时值和对应的预测数据如果不加处理,无法直接对其,故将实时值的时间戳和对应的预测数据保存,子组件通过监测道名称和时间戳获取对应数据。

const currentTimestamp = item.data[currentIndex.value]?.timestamp;allPredictedData.value[extractedName].push({timestamp: currentTimestamp,prediction: response
});

        这么尝试多次后(一两天把。。),发现问题仍然无法解决,一度怀疑是不是echart的问题,还是什么玄学。后面静下心来想想,在纸上debug了一下,理清逻辑之后发现问题所在。设计出来了最终版:

        

报警时间预测不准的原因是因为两个问题:1.二者起始没对齐 2.每秒增加的点数不同。

所以想到了使用填充的方式来使二者在开始对齐,右边是历史数据的方式。

第一步:获取监测道的全部数据(模拟传感器的实时数据,所以是有全部数据)

第二步:打开折线图的时候,获取当前点的dataPoint;

2.1 结合data,从dataPoint向前进行判断有多个点x;

2.2填充null,形式为[null,x,dataPoint]共20个点;这三步便生成了初始的20个点,后面更新的步骤为:

2.3获取新的dataPoint,加入初始数组,初始数组.shift()

左边则是预测数据:

第一步:初始化和历史数据相同,到2.2生成了一个[null,x,dataPoint]初始历史数据数组,此时加入当前点的预测数据生成新的数组:[初始历史数据数组,实时点对应的预测数据],这就是一个初始预测数据数组;
第二步:初始历史数组.shift(),追加上一个点对应预测数据的第一个点,生成第二个历史数据数组;

追加实时值的预测数据:[第二个历史数据数组,实时点对应的预测数据]。

下图为打开折线图的示意图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java学习——day24(反射进阶:注解与动态代理)

文章目录 1. 反射与注解2. 动态代理3. 实践:编写动态代理示例4. 注解定义与使用5. 动态代理6. 小结与思考 1. 反射与注解 注解:注解是 Java 提供的用于在代码中添加元数据的机制。它不会影响程序的执行,但可以在运行时通过反射获取和处理。反…

C++之nullptr

文章目录 前言 一、NULL 1、代码 2、结果 二、nullptr 1、代码 2、结果 总结 前言 当我们谈论空指针时,很难避免谈及nullptr。nullptr是C++11引入的一个关键字,用来表示空指针。在C++中,空指针一直是一个容易引起混淆的问题,因为在早期版本的C++中,通常使用NULL来…

JavaScript惰性加载优化实例

这是之前的一位朋友的酒桌之谈,他之前负责的一个电商项目,刚刚开发万,首页加载时间特别长,体验很差,所以就开始排查,发现是在首页一次性加载所有js导致的问题,这个问题在自己学习的时候并不明显…

苹果内购支付 Java 接口

支付流程&#xff0c;APP支付成功后 前端调用后端接口&#xff0c;后端接口将前端支付成功后拿到的凭据传给苹果服务器检查&#xff0c;如果接口返回成功了&#xff0c;就视为支付。 代码&#xff0c;productId就是苹果开发者后台提前设置好的 产品id public CommonResult<S…

数据库中的数组: MySQL与StarRocks的数组操作解析

在现代数据处理中, 数组 (Array) 作为一种高效存储和操作结构化数据的方式, 被广泛应用于日志分析, 用户行为统计, 标签系统等场景. 然而, 不同数据库对数组的支持差异显著. 本文将以MySQL和StarRocks为例, 深入解析它们的数组操作能力, 并对比其适用场景. 文章目录 一 为什么需…

LeetCode零钱兑换(动态规划)

题目描述 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是无…

/sys/fs/cgroup/memory/memory.stat 关键指标说明

目录 1. **total_rss**2. **total_inactive_file**3. **total_active_file**4. **shmem**5. **其他相关指标**总结 以下是/sys/fs/cgroup/memory/memory.stat文件中一些关键指标的详细介绍&#xff0c;特别是与PostgreSQL相关的指标&#xff1a; 1. total_rss 定义&#xff1…

C++第14届蓝桥杯b组学习笔记

1. 日期统计 小蓝现在有一个长度为 100100 的数组&#xff0c;数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示&#xff1a; 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4…

[Effective C++]条款28:避免返回handles指向对象内部成分

. 在C中&#xff0c;返回指向对象内部成分的引用&#xff08;handles&#xff09;可能会导致封装性降低和对象空悬问题。为了避免這些问题&#xff0c;可以通过返回const引用来限制对内部数据的修改&#xff0c;从而确保只读访问 1、返回内部引用对象 下面代码中getData函数返…

PyTorch 学习笔记

环境&#xff1a;python3.8 PyTorch2.4.1cpu PyCharm 参考链接&#xff1a; 快速入门 — PyTorch 教程 2.6.0cu124 文档 PyTorch 文档 — PyTorch 2.4 文档 快速入门 导入库 import torch from torch import nn from torch.utils.data import DataLoader from torchvision …

windows开启wsl与轻量级虚拟机管理

基于win 10 打造K8S应用开发环境&#xff08;wsl & kind&#xff09; 一、wsl子系统安装 1.1 确认windows系统版本 cmd/powershell 或者win r 运行winver 操作系统要> 19044 1.2 开启wsl功能 控制面板 -> 程序 -> 启用或关闭Windows功能 开启适用于Linux的…

C++ -异常之除以 0 问题(整数除以 0 编译时检测、整数除以 0 运行时检测、浮点数除以 0 编译时检测、浮点数除以 0 运行时检测)

一、整数除以 0&#xff08;编译时检测&#xff09; 1、演示 #include <iostream>using namespace std;int main() {int result 10 / 0;cout << result << endl;return 0; }程序无法运行&#xff0c;输出结果 error C2124: 被零除或对零求模2、演示解读 …

【蓝桥杯】搜索算法:剪枝技巧+记忆化搜索

1. 可行性剪枝应用 1.1. 题目 题目描述: 给定一个正整数n和一个正整数目标值target,以及一个由不同正整数组成的数组nums。要求从nums中选出若干个数,每个数可以被选多次,使得这些数的和恰好等于target。问有多少种不同的组合方式? 输入: 第一行:n和target,表示数组…

Uniapp 集成极光推送(JPush)完整指南

文章目录 前言一、准备工作1. 注册极光开发者账号2. 创建应用3. Uniapp项目准备 二、集成极光推送插件方法一&#xff1a;使用UniPush&#xff08;推荐&#xff09;方法二&#xff1a;手动集成极光推送SDK 三、配置原生平台参数四、核心功能实现1. 获取RegistrationID2. 设置别…

Linux中进程

一、认识进程 进程(PCB)内核数据结构(task_struct)程序的代码和数据 每一个进程都有其独立的task_struct,OS对众多的task_struct进行管理&#xff0c;如何管理&#xff1f;先描述再组织&#xff0c;所有运⾏在系统⾥的进程都以task_struct链表的形式存在内核⾥&#xff0c;而…

国外的AI工具

一 OpenAI &#xff1a; &#x1f4a1; 总览&#xff1a; 名称全称/代号简介GPT-4o“o” omniOpenAI 最新的旗舰多模态模型&#xff08;文字、图像、音频三模态&#xff09;&#xff0c;比 GPT-4 更强、更快、更便宜。GPT-4o-mini精简版 GPT-4o轻量级版本&#xff0c;推测为性…

企业级Java开发工具MyEclipse v2025.1——支持AI编码辅助

MyEclipse一次性提供了巨量的Eclipse插件库&#xff0c;无需学习任何新的开发语言和工具&#xff0c;便可在一体化的IDE下进行Java EE、Web和PhoneGap移动应用的开发&#xff1b;强大的智能代码补齐功能&#xff0c;让企业开发化繁为简。 立即获取MyEclipse v2025.1正式版 具…

按键长按代码

这些代码都存放在定时器中断中。中断为100ms中断一次。 数据判断&#xff0c;看的懂就看吧

在 macOS 上连接 PostgreSQL 数据库(pgAdmin、DBeaver)

在 macOS 上连接 PostgreSQL 数据库 pgAdmin 官方提供的图形化管理工具&#xff0c;支持 macOS。 下载地址&#xff1a;https://www.pgadmin.org/ pgAdmin 4 是对 pgAdmin 的完全重写&#xff0c;使用 Python、ReactJs 和 Javascript 构建。一个用 Electron 编写的桌面运行时…

FTP协议和win server2022安装ftp

FTP协议简介 FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09;是一种用于在网络上的计算机之间传输文件的标准网络协议。它被广泛应用于服务器与客户端之间的文件上传、下载以及管理操作。FTP支持多种文件类型和结构&#xff0c;并提供了相对简单的…