《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

源码下载

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

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

相关文章

如何讲好ppt演讲技巧(4篇)

如何讲好ppt演讲技巧&#xff08;4篇&#xff09; 如何讲好PPT演讲技巧&#xff08;四篇&#xff09; **篇&#xff1a;精心准备&#xff0c;奠定演讲基础 一个成功的PPT演讲&#xff0c;离不开精心的准备。首先&#xff0c;要确定演讲的主题和目标&#xff0c;确保演讲内容清…

字典及GitHub字典爬取工具

红队API接口Fuzz字典可以用于WEB安全&#xff0c;渗透测试&#xff0c;SRC等场景 完整文件已上传知识星球&#xff0c;需要的朋友可加入查看。

Docker容器---Harbor私有仓库部署与管理

一、搭建本地私有仓库 1、下载registry镜像 [rootlocalhost ~]#docker pull registry Using default tag: latest latest: Pulling from library/registry 79e9f2f55bf5: Pull complete 0d96da54f60b: Pull complete 5b27040df4a2: Pull complete e2ead8259a04: Pull comp…

OPPO Reno10Pro/Reno11/K10手机强解BL刷root权限KSU内核抓包刷机救砖

OPPO Reno10Pro/Reno11/K10手机虽然发布时间并不久&#xff0c;但由于天玑处理器的体质&#xff0c;已经支持强制解锁BL了&#xff0c;该漏洞来自第三方工具适配&#xff0c;支持OPPO天机8100/8200刷机救砖解锁BL不需要等待官方深度测试直接实现。解锁BL后的OPPO Reno10Pro/Ren…

Android binder死亡通知机制

在Andorid 的binder系统中&#xff0c;当Bn端由于种种原因死亡时&#xff0c;需要通知Bp端&#xff0c;Bp端感知Bn端死亡后&#xff0c;做相应的处理。 使用 Bp需要先注册一个死亡通知&#xff0c;当Bn端死亡时&#xff0c;回调到Bp端。 1&#xff0c;java代码注册死亡通知 …

hadoop学习---基于hive的航空公司客户价值的LRFCM模型案例

案例需求&#xff1a; RFM模型的复习 在客户分类中&#xff0c;RFM模型是一个经典的分类模型&#xff0c;模型利用通用交易环节中最核心的三个维度——最近消费(Recency)、消费频率(Frequency)、消费金额(Monetary)细分客户群体&#xff0c;从而分析不同群体的客户价值。在某些…

C++list的模拟实现

文章目录 一、观察源码二、模拟实现1. 节点结构体2. list类3. 迭代器的定义与实现&#xff08;1&#xff09; 前置--后置--模拟实现&#xff08;2&#xff09; *和->重载模拟实现&#xff08;3&#xff09; 和!重载实现 4. list成员函数模拟实现。&#xff08;1&#xff09;…

Unity Audio Filter 入门

概述&#xff1a; 如果你在你项目中需要一些特殊的声音效果&#xff0c;那这部分声音过滤器的部分一定不要错过喔&#xff0c;让我们来学习这部分的内容吧&#xff01; 这部分理论性比较强&#xff0c;认真看我的注解哈&#xff0c;我尽量解释的易懂一点。 Audio Chorus Filter…

翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习六

合集 ChatGPT 通过图形化的方式来理解 Transformer 架构 翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习一翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习二翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深…

基于Springboot+Vue的Java项目-火车票订票系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

html--剑雨

<!doctype html> <html> <head> <meta charset"utf-8"> <title>css3剑雨-jq22.com</title> <script src"http://www.jq22.com/jquery/jquery-1.10.2.js"></script> <style> .sword:before, .sword:…

Docker基础学习(5.Docker镜像命令)

⭐ 作者简介&#xff1a;码上言 ⭐ 代表教程&#xff1a;Spring Boot vue-element 开发个人博客项目实战教程 ⭐专栏内容&#xff1a;个人博客系统 ⭐我的文档网站&#xff1a;http://xyhwh-nav.cn/ ⭐微信公众号&#xff1a;码上言 文章目录 Docker run流程镜像是什么&a…

云计算技术概述_1.云计算相关概念

1.关于IBM“蓝云&#xff08;Blue Cloud&#xff09;”计划 IBM 推出的“蓝云&#xff08;Blue Cloud&#xff09;”计划为客户带来即可使用的云计算(Cloud Computing)。它包括一系列的云计算产品&#xff0c;使计算不仅仅局限在本地机器或远程Server Farms&#…

树莓派点亮LED灯

简介 使用GPIO Zero library 的 Python库实现点亮LED灯。接线 树莓派引脚参考图如下&#xff1a; LED正极 接GPIO17 LED负极 接GND 权限 将你的用户加到gpio组中&#xff0c; 否则无法控制GPIO sudo usermod -a -G gpio 代码 from gpiozero import LED from time impor…

MouseBoost PRO for Mac激活版:强大的 鼠标增强软件

在追求高效工作的今天&#xff0c;MouseBoost PRO for Mac成为了许多Mac用户的得力助手。这款功能强大的鼠标增强软件&#xff0c;以其独特的智能化功能和丰富的实用工具&#xff0c;让您的电脑操作更加便捷、高效。 MouseBoost PRO for Macv3.4.0中文激活版下载 MouseBoost PR…

【Mac】Photoshop 2024 for mac最新安装教程

软件介绍 Photoshop 2024是Adobe公司推出的一款图像处理软件&#xff0c;它支持Windows和Mac OS系统。Adobe Photoshop是业界领先的图像编辑和处理软件之一&#xff0c;广泛用于设计、摄影、数字绘画等领域。 Photoshop 2024的功能包括&#xff1a; 1.图像编辑&#xff1a;提…

图片壁纸社区app前后端开源小程序源码

图片壁纸社区APP前后端开源小程序源码&#xff0c;修改了开源版的前端样式&#xff0c;变成图片社区&#xff0c;也可以用来作为壁纸。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89122506 更多资源下载&#xff1a;关注我。

【Unity】修改模型透明度

在 Unity 中修改模型透明度主要有两种方法&#xff1a;通过材质和通过着色器。以下是两种方法的步骤和解释&#xff1a; 方法 1&#xff1a;通过材质 在 Unity 编辑器中&#xff0c;选择你想要修改透明度的模型。在 Inspector 窗口中&#xff0c;找到模型的 Renderer 组件&am…

简约大气的全屏背景壁纸导航网源码(免费)

简约大气的全屏背景壁纸导航网模板 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <html lang"zh-CN"> <!--版权归孤独 --> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible…

【b站前端-小鑫】Vue Router(路由)快速掌握(入门到精通5节课)

课程地址&#xff1a;【Vue Router(路由)快速掌握&#xff08;入门到精通5节课&#xff09;】 https://www.bilibili.com/video/BV1aP4y1W7Uz/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 1 Vue Router 1.1 Vue Router的安装 1.2 创建路由…