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

本文主要是介绍《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实用小工具·五十》动态增删数据与平滑缩放移动的折线图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954099

相关文章

SQLite3命令行工具最佳实践指南

《SQLite3命令行工具最佳实践指南》SQLite3是轻量级嵌入式数据库,无需服务器支持,具备ACID事务与跨平台特性,适用于小型项目和学习,sqlite3.exe作为命令行工具,支持SQL执行、数... 目录1. SQLite3简介和特点2. sqlite3.exe使用概述2.1 sqlite3.exe

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

CnPlugin是PL/SQL Developer工具插件使用教程

《CnPlugin是PL/SQLDeveloper工具插件使用教程》:本文主要介绍CnPlugin是PL/SQLDeveloper工具插件使用教程,具有很好的参考价值,希望对大家有所帮助,如有错... 目录PL/SQL Developer工具插件使用安装拷贝文件配置总结PL/SQL Developer工具插

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

详解如何使用Python构建从数据到文档的自动化工作流

《详解如何使用Python构建从数据到文档的自动化工作流》这篇文章将通过真实工作场景拆解,为大家展示如何用Python构建自动化工作流,让工具代替人力完成这些数字苦力活,感兴趣的小伙伴可以跟随小编一起... 目录一、Excel处理:从数据搬运工到智能分析师二、PDF处理:文档工厂的智能生产线三、邮件自动化: