当前位置: 首页 > news >正文

《QT实用小工具·五十》动态增删数据与平滑缩放移动的折线图

1、概述
源码放在文章末尾

该项目实现了带动画、带交互的折线图,包含如下特点:
动态增删数值
自适应显示坐标轴数值
鼠标悬浮显示十字对准线
鼠标靠近点自动贴附
支持直线与平滑曲线效果
自定义点的显示类型与大小
自适应点的数值显示位置
根据指定锚点缩放
平滑的横向移动
选中的纵向渐变效果

项目demo演示如下所示:
在这里插入图片描述

项目部分代码如下所示:

#ifndef LINECHART_H
#define LINECHART_H#include <QObject>
#include <QWidget>
#include <QList>
#include <QPainter>
#include <QPainterPath>
#include <QPropertyAnimation>
#include <QtMath>struct ChartData
{QString title;QColor color = Qt::black;int xMin = 0;int xMax = 0;int yMin = 0;int yMax = 0;QList<QPoint> points;QList<QString> xLabels; // X显示的名字,可空,比如日期
};struct Vector2D : public QPointF
{Vector2D(double x, double y) : QPointF(x, y){}Vector2D(QPointF p) : QPointF(p){}/// 向量长度double length(){return sqrt(x() * x() + y() * y());}/// 转单位向量Vector2D normalize(){double len = length();double inv;if (len < 1e-4)inv = 0;elseinv = 1 / length();return Vector2D(x() * inv, y() * inv);}/// 向量相加Vector2D operator+ (Vector2D v){return Vector2D(x() + v.x(), y() + v.y());}/// 向量翻倍Vector2D operator* (double f){return Vector2D(x() * f, y() * f);}/// 内积double dot(Vector2D v){return x() * v.x() + y() * v.y();}/// 两个向量夹角double angle(Vector2D v){return acos(dot(v) / (length() * v.length())) * 180 / M_PI;}
};class LineChart : public QWidget
{Q_OBJECTQ_PROPERTY(int display_x_min READ getDisplayXMin WRITE setDisplayXMin)Q_PROPERTY(int display_x_max READ getDisplayXMax WRITE setDisplayXMax)Q_PROPERTY(int display_y_min READ getDisplayYMin WRITE setDisplayYMin)Q_PROPERTY(int display_y_max READ getDisplayYMax WRITE setDisplayYMax)public:LineChart(QWidget *parent = nullptr);int lineCount() const;void setPointLineType(int t);void setPointValueType(int t);void setPointDotType(int t);void setPointDotRadius(int r);void setLabelSpacing(int s);void addLine(ChartData data);void removeLine(int index);void addPoint(int index, int x, int y);void addPoint(int index, int x, int y, const QString& label);void removeFirst(int index);void updateAnchors();void zoom(double prop);void moveHorizontal(int x);signals:void signalSelectRangeChanged(int start, int end);public slots:void zoomIn();void zoomOut();protected:void paintEvent(QPaintEvent *event) override;void enterEvent(QEvent *event) override;void leaveEvent(QEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;void wheelEvent(QWheelEvent *event) override;private:void setDisplayXMin(int v);int getDisplayXMin() const;void setDisplayXMax(int v);int getDisplayXMax() const;void setDisplayYMin(int v);int getDisplayYMin() const;void setDisplayYMax(int v);int getDisplayYMax() const;void saveRange();void startRangeAnimation();QPropertyAnimation* startAnimation(const QByteArray &property, int start, int end, bool* flag, int duration = 300, QEasingCurve curve = QEasingCurve::OutQuad);int getValueByCursorPos(QPoint pos);private:// 数据QList<ChartData> datas;                 // 所有折线的数据// 界面QRect contentRect;                      // 显示的范围,实时刷新QRect paddings = QRect(32, 32, 32, 32); // 四周留白(width=right,height=bottom)QColor borderColor = Qt::gray;          // 边界线颜色int labelSpacing = 2;                   // 标签间距// 信息显示bool autoResize = true;                 // 自动调整大小int displayXMin = 0, displayXMax = 0;   // 显示的X轴范围int displayYMin = 0, displayYMax = 0;   // 显示的Y轴范围bool usePointXLabels = true;            // 优先使用点对应的label,还是相同间距的数值QList<QString> xLabels;                 // 显示的文字(可能少于值数量)QList<int> xLabelPoss;int pointLineType = 3;                  // 连线类型:1直线,2二次贝塞尔曲线,3三次贝塞尔曲线(更精确但吃性能)int pointValueType = 2;                 // 数值显示位置:0无,1强制上方,2自动附近int pointDotType = 1;                   // 圆点类型:0无,1空心圆,2实心圆,3小方块int pointDotRadius = 2;                 // 圆点半径// 动画效果bool enableAnimation = true;int _savedXMin, _savedXMax;             // 修改前的数值int _savedYMin, _savedYMax;bool animatingXMin = false, animatingXMax = false; // 是否正在动画中bool animatingYMin = false, animatingYMax = false;int _animatedXMin, _animatedXMax;       // 动画中的数值(仅影响显示)int _animatedYMin, _animatedYMax;// 交互数据bool pressing = false;QPoint pressPos, releasePos;bool hovering = false;QPoint hoverPos;int nearDis = 8;                        // 四周这些距离内算是“附近”// 悬浮提示bool showCrossOnPressing = true;        // 按下显示十字对准线QColor hightlightColor = QColor("#FF7300");       // 高亮颜色// 鼠标选择bool enableSelect = true;bool selecting = false;int selectPos = 0;                      // 最后一次鼠标点击的X像素(相对显示矩形)int selectXStart = 0, selectXEnd = 0;   // 鼠标按下/松开的对应X值位置QColor selectColor = QColor("#F08080"); // 选择区域颜色// 缩放(仅针对X轴)bool enableScale = true;int displayXStart = 0, displayXEnd = 0;
};#endif // LINECHART_H

源码下载

相关文章:

《QT实用小工具·五十》动态增删数据与平滑缩放移动的折线图

1、概述 源码放在文章末尾 该项目实现了带动画、带交互的折线图&#xff0c;包含如下特点&#xff1a; 动态增删数值 自适应显示坐标轴数值 鼠标悬浮显示十字对准线 鼠标靠近点自动贴附 支持直线与平滑曲线效果 自定义点的显示类型与大小 自适应点的数值显示位置 根据指定锚点…...

【qt】核心机制信号槽(下)

这里写目录标题 自定义的信号自定义的槽自定义的信号和槽的结合使用信号和槽的断开总结&#xff1a; 自定义的信号 信号就是一个函数声明 前面咱们都用的qt组件自带的信号&#xff0c;接下来我们自己写一个信号。 信号只需要在前面加一个signals即可 这个函数不需要实现 参数传…...

C++ 基础 输入输出

一 C 的基本IO 系统中的预定义流对象cin和cout: 输入流&#xff1a;cin处理标准输入&#xff0c;即键盘输入&#xff1b; 输出流&#xff1a;cout处理标准输出&#xff0c;即屏幕输出&#xff1b; 流&#xff1a;从某种IO设备上读入或写出的字符系列 使用cin、cout这两个流对…...

八股文(C#篇)

C#中的数值类型 堆和栈 值类型的数据被保存在栈&#xff08;stack)上&#xff0c;而引用类型的数据被保存在堆&#xff08;heap&#xff09;上&#xff0c;当值类型作为参数传递给函数时&#xff0c;会将其复制到新的内存空间中&#xff0c;因此在函数中对该值类型的修改不会影…...

【YOLOv9算法原理简介】

YOLOv9算法原理 单阶段检测器:YOLOv9延续了YOLO系列的单阶段检测器设计,即在单次前向传播中同时预测边界框和类别概率,这使得它能够实现快速的检测速度。通用高效层聚合网络(GELAN) :YOLOv9引入了一种新的模型架构GELAN,它通过高效的层聚合块和计算模块,以较小的参数量…...

2010NOIP普及组真题 2. 接水问题

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1950 解法一、朴素模拟 核心思想&#xff1a; 朴素模拟&#xff1a; 1、先给每个b[i]水龙头分配一个人a[i]&#xff0c;b[i] 表示水龙头的剩余时间。同时标记该水龙头为 used 使用中 2…...

ElementUI从unpkg.com完整下载到本地的方法 - 解决unpkg.com不稳定的问题 - 自建镜像站 - 不想打包只想cdn一下

方法 方法1&#xff09;随便弄个文件夹&#xff0c;根据官网npm方法下载包&#xff0c;提取即可 npm i element-ui -S cd /node_modules/element-ui/ ls src 安装npm方法&#xff1a;https://nodejs.org/en 方法2&#xff09;不推荐 - 在github中搜索对应的库zip包&#xff0…...

什么是BFF API

BFF&#xff08;Backend For Frontend&#xff09;API 是一种架构模式&#xff0c;旨在为特定的前端应用&#xff08;如移动应用、桌面应用或网页应用&#xff09;提供定制化的后端服务。通过这种方式&#xff0c;后端可以根据前端的具体需求和特性&#xff0c;提供最优化的数据…...

分享自己一篇在亚马逊云科技AWS官网发的Blog技术文章

小李哥在亚马逊AWS官网&#xff0c;作为第一作者发了自己的第一篇AWS Blog文章&#xff0c;也是自己今年在AWS官网的第11篇文章。文章主要内容是描述为出海的金融企业&#xff0c;搭建满足PCI-DSS合规、FIPS 140-2 Level 3安全标准的传输中数据加密云端方案&#xff0c;主要用于…...

封装长按触发事件的uniapp组件

简单说一下原理 首先介绍三个针对触摸屏设备的事件&#xff0c;分别是&#xff1a; touchstart&#xff1a;当手指触摸屏幕时触发&#xff0c;即触摸开始的时候&#xff1b;touchend&#xff1a;当手指离开屏幕时触发&#xff0c;即触摸结束的时候&#xff1b;touchcancel&am…...

Docker 安装的MySQL迁移数据库

1. 导出数据库 docker ps :查看数据库对应的 CONTAINER ID docker exec -it id /bin/bash : 进入到mysql的docker实例中 cd /usr/bin : 进入到bin目录 mysqldump -u root -p123456 study > /root/study_backup0509.sql :使用mysqldump备份库&#xff0c;注意密码与-p之间…...

算法训练Day28 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

122.买卖股票的最佳时机II class Solution { public:int maxProfit(vector<int>& prices) {vector<int> dp(2,0);dp[0] -prices[0];for(int i1; i<prices.size(); i){dp[0] max(dp[0], dp[1]-prices[i]);dp[1] max(dp[1], prices[i]dp[0]);}return dp[1]…...

Linux(openEuler、CentOS8)基于chrony企业内网NTP服务器搭建实验

一、知识点 chrony 是由 守护进程 chronyd 以及 命令行工具 chronyc 组成的 chronyd 在后台静默运行并通过 123 端口与时间服务器定时同步时间&#xff0c;默认的配置文件是 /etc/chrony.conf chronyc 通过 323 端口与 chronyd 交互&#xff0c;可监控 chronyd 的性能并在运…...

前端开发框架Vue

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Vue概述 Vue.js&#xff08;简称Vue&#xff09;是由尤雨溪&#xff08;Evan You&#xff09;创建并维护的一款开源前端开发框架。Vue以其轻量级、易上手和高度灵活的特点&…...

Vue2中引入ElementUI

Vue中引入ElementUI 目录 Vue中引入ElementUI安装 全库导入main.py使用 仅引入样式文件main.py使用 安装 官方文档 npm i element-ui -S全库导入 main.py import ElementUI from element-ui;Vue.use(ElementUI)使用 <template> <div class"main">&l…...

华中科技大学雷达站部署

一&#xff1a;项目地址 GitHub - HUSTLYRM/HUST_Radar_2023: 华中科技大学狼牙战队 RoboMaster 2023赛季 雷达站 二&#xff1a;安装依赖 2.1创建虚拟环境 首先是程序是基于python3.8完成&#xff0c;所以创建虚拟环境的时候&#xff0c;选择3.8的虚拟环境 conda create -…...

小程序引入 Vant Weapp 极简教程

一切以 Vant Weapp 官方文档 为准 Vant Weapp 官方文档 - 快速入手 1. 安装nodejs 前往官网下载安装即可 nodejs官网 安装好后 在命令行&#xff08;winr&#xff0c;输入cmd&#xff09;输入 node -v若显示版本信息&#xff0c;即为安装成功 2. 在 小程序根目录 命令行/终端…...

labview技术交流-将时间字符串转换成时间格式

应用场景 我们在数据库中设计了datetime类型的字段&#xff0c;比如字段名就叫“保存时间”&#xff0c;当我们使用labview将表中数据读取出来后datetime类型的数据是以字符串的格式显示的。而我们想计算两条数据“保存时间”的间隔时间时&#xff0c;用字符串类型自然是没法计…...

算法提高之迷宫问题

算法提高之迷宫问题 核心思想&#xff1a;最短路问题 从(n-1,n-1)开始bfs 往前走一个就存入pre数组 之后再遍历pre数组输出 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 1010,M N*N;#define x first#def…...

泛微E9开发 通过点击按钮来复制选择的明细行

泛微E9开发 通过点击按钮来复制选择的明细行 复制明细行功能背景展示效果实现方法 复制明细行 功能背景 用户可以通过“复制明细”按钮来实现新增选择的明细行&#xff0c;并且新增明细行的数据跟选择的数据完全一样&#xff0c;具体操作如下图所示&#xff1a; 手动新增明细…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...