QChart的折线图
``
#ifndef FPLINECHART_H
#define FPLINECHART_H
#include <QWidget>
#include <QTimer>
#include <QtCharts/QChartView>//显示图表
#include <QtCharts/QLineSeries>//线系列
#include <QtCharts/QSplineSeries>
#include <QtCharts/QValueAxis>
#include <QDateTime>
#include <QDateTimeAxis>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include<QDebug>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QDateTime>
#include <QTimer>
#include <QtCharts>
QT_BEGIN_NAMESPACE
namespace Ui { class FpLineChart; }
QT_END_NAMESPACE
class FpLineChart : public QWidget
{
Q_OBJECT
public:
FpLineChart(QWidget *parent = nullptr);
~FpLineChart();
void initLineChart();
public:
//这两个接口提供给外部调用
void createASeries(QString name);
void SeriesAppendData(QString name,QDateTime x, double y);
public:
void updateSeriesEarlyAlarmValueThreshold(double value);
void updateSeriesAlarmValueThreshold(double value);
private:
void setSeriesEarlyAlarmValueThreshold(double value);
void setSeriesAlarmValueThreshold(double value);
void deleteAlarmSeries(QString name);
QSplineSeries* m_earlyAlarm_series=nullptr;
QSplineSeries* m_alarm_series=nullptr;
private:
void test_data_init();
private:
void add_one_serie(QString name, QColor color);
void series_append_data(QSplineSeries *m_series,QDateTime x, double y);
void deleteSeries(QString name);
QMap<QString,QSplineSeries *>name_series_union;
private:
void Margins();
//图表
QChart chart;
//x,y轴
QDateTimeAxis AxisX;
QValueAxis AxisY;
//默认y轴的范围
qreal min_y = 0;
qreal max_y = 0;
//默认x轴的范围
QDateTime start;
QDateTime end;
private:
QChartView *chartView;
private:
Ui::FpLineChart *ui;
};
#endif // FPLINECHART_H
#include "fplinechart.h"
#include "ui_fplinechart.h"
#include<QToolTip>
FpLineChart::FpLineChart(QWidget *parent)
: QWidget(parent)
, ui(new Ui::FpLineChart)
{
ui->setupUi(this);
initLineChart();
// test_data_init();
updateSeriesEarlyAlarmValueThreshold( 300);
updateSeriesAlarmValueThreshold( 400);
QColor color = QColor::fromRgb(rand()%256, rand()%256, rand()%256);
add_one_serie("tempetate", color);
QColor colo1r = QColor::fromRgb(rand()%256, rand()%256, rand()%256);
add_one_serie("dianya", colo1r);
deleteSeries("tempetate");
}
FpLineChart::~FpLineChart()
{
delete ui;
}
void FpLineChart::initLineChart()
{
/*********************/
// chart.setBackgroundBrush(QBrush(QColor(36, 48, 64)));
chart.setTheme(QChart::ChartThemeDark);//设置系统主题
// chart.setTitle( QObject::tr("飞参实时波形图") );//设置标题
chart.setTitleFont(QFont("微软雅黑",10));
// chart.legend()->hide();
chart.setAnimationOptions(QChart::SeriesAnimations); // 动画方式
// x轴(时间轴方式)
AxisX.setTitleText(QObject::tr("时间(分:秒)")); // x轴显示标题
// AxisX.setGridLineVisible(false); // 隐藏背景网格X轴框线
// AxisX.setFormat("mm:ss"); // x轴格式
AxisX.setFormat(" MM-dd hh:mm:ss"); // x轴格式
AxisX.setLabelsAngle(0); // x轴显示的文字倾斜角度
AxisX.setTickCount(6); // 轴上点的个数
// 设置轴上每个刻度之间的小刻度数量
AxisX.setMinorGridLineVisible(true);
AxisX.setGridLineVisible(true); // 隐藏背景网格Y轴框线
start = QDateTime::currentDateTime();
end = start.addSecs(110);
AxisX.setRange(start, end); // 范围
// y轴
AxisY.setTitleText(QObject::tr("数值")); // y轴显示标题
AxisY.setGridLineVisible(true); // 隐藏背景网格Y轴框线
AxisY.setTickCount(6); // 轴上点的个数
AxisY.setMinorTickCount(5);
AxisY.setRange(0, 800);
// 图表视图
chart.addAxis(&AxisX, Qt::AlignBottom); // 设置x轴位置
chart.addAxis(&AxisY, Qt::AlignLeft); // 设置y轴位置
chartView = new QChartView(&chart);
chartView->setRenderHint(QPainter::Antialiasing);
ui->widget->layout()->addWidget(chartView);
Margins();
}
void FpLineChart::createASeries(QString name)
{
QColor color = QColor::fromRgb(rand()%256, rand()%256, rand()%256);
add_one_serie(name, color);
}
void FpLineChart::SeriesAppendData(QString name, QDateTime x, double y)
{
if(name_series_union.isEmpty())
{
return;
}
for(const auto &it:name_series_union.keys())
{
if(name==it)
{
auto ptr=name_series_union[name];
if(ptr==nullptr)
{
return;
}
series_append_data(ptr, x, y);
}
}
}
void FpLineChart::deleteAlarmSeries(QString name)
{
if(name=="earlyAlarm")
{
m_earlyAlarm_series->deleteLater();
}
if(name=="Alarm")
{
m_alarm_series->deleteLater();
}
}
void FpLineChart::updateSeriesEarlyAlarmValueThreshold(double value)
{
if(m_earlyAlarm_series)
{
m_earlyAlarm_series->deleteLater();
setSeriesEarlyAlarmValueThreshold(value);
}
else
{
setSeriesEarlyAlarmValueThreshold(value);
}
}
void FpLineChart::updateSeriesAlarmValueThreshold(double value)
{
if(m_alarm_series)
{
m_alarm_series->deleteLater();
setSeriesAlarmValueThreshold(value);
}
else
{
setSeriesAlarmValueThreshold(value);
}
}
void FpLineChart::setSeriesEarlyAlarmValueThreshold(double value)
{
QColor color = QColor::fromRgb(255, 255, 0);
m_earlyAlarm_series = new QSplineSeries();
m_earlyAlarm_series->setName(QObject::tr("预警"));
chart.addSeries(m_earlyAlarm_series);
//chart.legend()->hide();
// 线段
m_earlyAlarm_series->setPen(QPen(color, 2, Qt::DotLine)); // 设置线段pen
m_earlyAlarm_series->attachAxis(&AxisX); // 线段依附的x轴
m_earlyAlarm_series->attachAxis(&AxisY);
m_earlyAlarm_series->append(start.toMSecsSinceEpoch(), value);
m_earlyAlarm_series->append(end.toMSecsSinceEpoch(), value);
}
void FpLineChart::setSeriesAlarmValueThreshold(double value)
{
QColor color = QColor::fromRgb(236, 28, 36);
m_alarm_series = new QSplineSeries();
m_alarm_series->setName(QObject::tr("告警"));
chart.addSeries(m_alarm_series);
// 线段
m_alarm_series->setPen(QPen(color, 2, Qt::DotLine)); // 设置线段pen
m_alarm_series->attachAxis(&AxisX); // 线段依附的x轴
m_alarm_series->attachAxis(&AxisY);
m_alarm_series->append(start.toMSecsSinceEpoch(), value);
m_alarm_series->append(end.toMSecsSinceEpoch(), value);
}
//设置边距
void FpLineChart::Margins()
{
QMargins mgs;
// // 设置边界
// mgs.setLeft(-10);
// mgs.setRight(-10);
// mgs.setTop(-10);
// mgs.setBottom(-10);
// // 设置边界
mgs.setLeft(0);
mgs.setRight(0);
mgs.setTop(0);
mgs.setBottom(0);
// 刷新到图表
chartView->chart()->setMargins(mgs);
}
void FpLineChart::series_append_data(QSplineSeries *m_series,QDateTime x, double y)
{
if(y < min_y)
{
min_y = y;
AxisY.setRange(min_y*0.9, max_y*1.1);
}
else if (y > max_y)
{
max_y = y;
AxisY.setRange(min_y, max_y*1.1);
}
if(x > end)
{
end = end.addSecs(30);
AxisX.setRange(start, end);
}
m_series->append(x.toMSecsSinceEpoch(), y);
QApplication::processEvents();
}
void FpLineChart::deleteSeries(QString name)
{
if(name_series_union.contains(name))
{
auto ptr=name_series_union[name];
if(ptr)
{
ptr->deleteLater();
name_series_union.remove(name);
}
}
}
void FpLineChart::test_data_init()
{
for(int i = 0;i<5;i++)
{
QColor color = QColor::fromRgb(rand()%256, rand()%256, rand()%256);
add_one_serie("这是一根曲线", color);
}
}
//test
void FpLineChart::add_one_serie(QString name, QColor color)
{
QSplineSeries* m_series = new QSplineSeries();
name_series_union.insert(name,m_series);
m_series->setName(name);
m_series->setPointsVisible(true);
//state:鼠标在不在上面
QObject::connect(m_series, &QSplineSeries::hovered, [=](const QPointF &point, bool state)mutable{
qDebug()<<point<<state;
QDateTime newDateTime = QDateTime::fromMSecsSinceEpoch(point.y());
qDebug() << "Converted back to QDateTime:" << newDateTime.toString();
QToolTip::showText(QCursor::pos(), QString("%1,%2").arg(newDateTime.toString()).arg(QString::number(point.y())),nullptr,QRect(),6000);
QRect rect(QCursor::pos(),QSize(80,80));
});
chart.addSeries(m_series);
chart.legend()->setAlignment(Qt::AlignTop); //设置曲线对应标签
// 线段
m_series->setPen(QPen(color, 2, Qt::SolidLine)); // 设置线段pen
m_series->attachAxis(&AxisX); // 线段依附的x轴
m_series->attachAxis(&AxisY);
//这根曲线要的数据
QDateTime x;
int base = 100 + qrand()%600;
for(int i = 0;i< 100;i++)
{
x = start.addSecs(i);
int data = qrand()%50;
if(i > 10)
data = base + qrand()%10;
m_series->append(x.toMSecsSinceEpoch(), data);
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性