341 lines
11 KiB
C++
341 lines
11 KiB
C++
#include "monitorAttributeGroupDlg.h"
|
||
#include "monitorAttributeDlg.h"
|
||
#include "monitorSideBarDlg.h"
|
||
#include "monitorPanel.h"
|
||
#include "monitorDetailAttributeDlg.h"
|
||
#include <QScrollArea>
|
||
#include <QFormLayout>
|
||
#include <QLabel>
|
||
#include <QUuid>
|
||
#include <QChartView>
|
||
#include <QBarSeries>
|
||
#include <QBarCategoryAxis>
|
||
#include <QValueAxis>
|
||
#include <QLineSeries>
|
||
#include <QDateTimeAxis>
|
||
#include "global.h"
|
||
|
||
MonitorAttributeGroupDlg::MonitorAttributeGroupDlg(QWidget* parent)
|
||
: QScrollArea(parent)
|
||
,_layout(nullptr)
|
||
,_pParent(nullptr)
|
||
,_pDetailParent(nullptr)
|
||
,_curMode(0)
|
||
{
|
||
initial();
|
||
}
|
||
|
||
MonitorAttributeGroupDlg::~MonitorAttributeGroupDlg()
|
||
{
|
||
|
||
}
|
||
|
||
void MonitorAttributeGroupDlg::initial()
|
||
{
|
||
_layout = new QVBoxLayout(this);
|
||
}
|
||
|
||
void MonitorAttributeGroupDlg::createGroupView(QList<monitorItemAttributeInfo> lst,int nType)
|
||
{
|
||
QWidget* content = new QWidget();
|
||
QGridLayout* gridLayout = new QGridLayout(content);
|
||
gridLayout->setHorizontalSpacing(2);
|
||
gridLayout->setVerticalSpacing(10);
|
||
gridLayout->setContentsMargins(0, 0, 0, 0);
|
||
|
||
// 设置列的最小宽度和拉伸比例
|
||
gridLayout->setColumnMinimumWidth(0, 30); // 标签列最小宽度
|
||
gridLayout->setColumnStretch(0, 1); // 标签列拉伸因子
|
||
gridLayout->setColumnStretch(1, 8); // 控件列拉伸因子
|
||
|
||
int row = 0;
|
||
for(auto& info : lst) {
|
||
QLabel* label = new QLabel(info.sTag, this);
|
||
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||
label->setMaximumWidth(40); // 设置标签最大宽度
|
||
|
||
QWidget* editor = createEditor(info);
|
||
editor->setProperty("category", info.nShowType);
|
||
editor->setProperty("graphType", info.nGraphType);
|
||
editor->setProperty("connectPara", info.sConnectPara);
|
||
|
||
// 添加到网格布局
|
||
gridLayout->addWidget(label, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||
gridLayout->addWidget(editor, row, 1);
|
||
|
||
// 设置行的拉伸因子(可选)
|
||
gridLayout->setRowStretch(row, 0); // 不拉伸,保持内容高度
|
||
|
||
_curWidget.insert(info.sTag, editor);
|
||
row++;
|
||
}
|
||
|
||
// 添加一个拉伸行,使内容在顶部对齐
|
||
gridLayout->setRowStretch(row, 1);
|
||
|
||
setWidget(content);
|
||
setWidgetResizable(true);
|
||
}
|
||
|
||
QWidget* MonitorAttributeGroupDlg::createEditor(monitorItemAttributeInfo info,int nType)
|
||
{
|
||
QWidget* pWidget = nullptr;
|
||
if(info.nShowType == 0){ //正常显示
|
||
QLabel *label = new QLabel(this);
|
||
pWidget = label;
|
||
}
|
||
else{ //图表
|
||
QChartView* chartView = new QChartView(this);
|
||
QSize size;
|
||
if(nType == 0)
|
||
size = QSize(400,300);
|
||
else
|
||
size = QSize(600,400);
|
||
chartView->setMinimumSize(size);
|
||
chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||
chartView->setRenderHint(QPainter::Antialiasing);
|
||
|
||
QChart* chart = new QChart();
|
||
chartView->setChart(chart);
|
||
|
||
if (info.nGraphType == 0) {
|
||
// 创建折线序列
|
||
QLineSeries* series = new QLineSeries();
|
||
|
||
QFont axisFont;
|
||
axisFont.setPointSize(9);
|
||
|
||
// 创建图表
|
||
chart->addSeries(series);
|
||
chart->setTitle(info.sName);
|
||
chart->setAnimationOptions(QChart::SeriesAnimations);
|
||
|
||
// 设置线条样式
|
||
QPen pen(Qt::blue);
|
||
pen.setWidth(3);
|
||
pen.setStyle(Qt::SolidLine);
|
||
series->setPen(pen);
|
||
|
||
// 创建坐标轴
|
||
QValueAxis* axisX = new QValueAxis();
|
||
QValueAxis* axisY = new QValueAxis();
|
||
|
||
// 添加坐标轴到图表
|
||
chart->addAxis(axisX, Qt::AlignBottom);
|
||
chart->addAxis(axisY, Qt::AlignLeft);
|
||
|
||
// 将序列关联到坐标轴
|
||
series->attachAxis(axisX);
|
||
series->attachAxis(axisY);
|
||
|
||
// 设置默认范围或等待数据更新
|
||
axisX->setRange(0, 10); // 临时范围
|
||
axisY->setRange(0, 100);
|
||
|
||
// 设置坐标轴标题
|
||
axisX->setTitleText("时间");
|
||
axisX->setLabelsFont(axisFont);
|
||
axisX->setTitleFont(axisFont);
|
||
axisY->setTitleText("值");
|
||
axisY->setLabelsFont(axisFont);
|
||
axisY->setTitleFont(axisFont);
|
||
|
||
chart->setTheme(QChart::ChartThemeLight);
|
||
chart->legend()->setVisible(true);
|
||
chart->legend()->setAlignment(Qt::AlignBottom);
|
||
|
||
QFont legendFont = chart->legend()->font();
|
||
legendFont.setPointSize(9); // 设置图例字体大小
|
||
chart->legend()->setFont(legendFont);
|
||
}
|
||
else if (info.nGraphType == 1) {
|
||
QBarSeries* series = new QBarSeries();
|
||
chart->addSeries(series);
|
||
chart->setTitle(info.sName);
|
||
chart->setAnimationOptions(QChart::SeriesAnimations);
|
||
|
||
// 创建坐标轴
|
||
QBarCategoryAxis* axisX = new QBarCategoryAxis();
|
||
QValueAxis* axisY = new QValueAxis();
|
||
|
||
chart->addAxis(axisX, Qt::AlignBottom);
|
||
chart->addAxis(axisY, Qt::AlignLeft);
|
||
series->attachAxis(axisX);
|
||
series->attachAxis(axisY);
|
||
}
|
||
|
||
pWidget = chartView;
|
||
}
|
||
return pWidget;
|
||
}
|
||
|
||
void MonitorAttributeGroupDlg::updateLineChartData(QChartView* chartView, const QVector<QPointF>& data)
|
||
{
|
||
if (!chartView || data.isEmpty()) return;
|
||
|
||
QChart* chart = chartView->chart();
|
||
if (!chart) {
|
||
chart = new QChart();
|
||
chart->setAnimationOptions(QChart::NoAnimation);
|
||
chartView->setChart(chart);
|
||
}
|
||
|
||
QLineSeries* series = nullptr;
|
||
if (chart->series().isEmpty()) {
|
||
series = new QLineSeries();
|
||
chart->addSeries(series);
|
||
} else {
|
||
series = qobject_cast<QLineSeries*>(chart->series().first());
|
||
if (!series) return;
|
||
}
|
||
|
||
series->clear();
|
||
|
||
// 计算数据范围
|
||
qint64 minTime = std::numeric_limits<qint64>::max();
|
||
qint64 maxTime = std::numeric_limits<qint64>::lowest();
|
||
double minVal = std::numeric_limits<double>::max();
|
||
double maxVal = std::numeric_limits<double>::lowest();
|
||
for (const QPointF& point : data) {
|
||
qint64 t = static_cast<qint64>(point.x());
|
||
series->append(t, point.y());
|
||
minTime = qMin(minTime, t);
|
||
maxTime = qMax(maxTime, t);
|
||
minVal = qMin(minVal, point.y());
|
||
maxVal = qMax(maxVal, point.y());
|
||
}
|
||
|
||
// ========== 简单直接的方法:确保只有一个坐标轴 ==========
|
||
QDateTimeAxis* xAxis = nullptr;
|
||
QValueAxis* yAxis = nullptr;
|
||
|
||
// 获取当前所有坐标轴
|
||
QList<QAbstractAxis*> allAxes = chart->axes();
|
||
|
||
// 如果坐标轴太多,清理所有
|
||
//if (allAxes.size() > 2) { // 应该只有x轴和y轴
|
||
for (auto axis : allAxes) {
|
||
chart->removeAxis(axis);
|
||
delete axis;
|
||
}
|
||
allAxes.clear();
|
||
//}
|
||
|
||
// 在剩余的坐标轴中查找
|
||
for (auto axis : allAxes) {
|
||
if (!xAxis && qobject_cast<QDateTimeAxis*>(axis)) {
|
||
xAxis = qobject_cast<QDateTimeAxis*>(axis);
|
||
} else if (!yAxis && qobject_cast<QValueAxis*>(axis)) {
|
||
yAxis = qobject_cast<QValueAxis*>(axis);
|
||
}
|
||
}
|
||
|
||
// 创建缺失的坐标轴
|
||
if (!xAxis) {
|
||
xAxis = new QDateTimeAxis();
|
||
xAxis->setTitleText("时间");
|
||
chart->addAxis(xAxis, Qt::AlignBottom);
|
||
}
|
||
|
||
if (!yAxis) {
|
||
yAxis = new QValueAxis();
|
||
yAxis->setTitleText("值");
|
||
chart->addAxis(yAxis, Qt::AlignLeft);
|
||
}
|
||
|
||
// 确保系列附加
|
||
series->attachAxis(xAxis);
|
||
series->attachAxis(yAxis);
|
||
|
||
// 设置范围和其他属性
|
||
qint64 timeMargin = qMax<qint64>((maxTime - minTime) * 0.05, 1000);
|
||
double valMargin = qMax((maxVal - minVal) * 0.1, 0.1);
|
||
|
||
xAxis->setRange(
|
||
QDateTime::fromMSecsSinceEpoch(minTime - timeMargin),
|
||
QDateTime::fromMSecsSinceEpoch(maxTime + timeMargin)
|
||
);
|
||
yAxis->setRange(minVal - valMargin, maxVal + valMargin);
|
||
|
||
qint64 timeSpan = maxTime - minTime;
|
||
xAxis->setFormat((timeSpan > 3600000) ? "HH:mm:ss" : "HH:mm:ss.zzz");
|
||
|
||
xAxis->setTickCount(6);
|
||
yAxis->setTickCount(8);
|
||
yAxis->setLabelFormat("%.2f");
|
||
|
||
QFont font;
|
||
font.setPointSize(9);
|
||
xAxis->setLabelsFont(font);
|
||
yAxis->setLabelsFont(font);
|
||
}
|
||
|
||
void MonitorAttributeGroupDlg::updateData()
|
||
{
|
||
if(_pParent || _pDetailParent){
|
||
auto pModel = getModelController();
|
||
auto pMap = pModel->getMonitorPara();
|
||
QUuid uid = getCurUid();
|
||
|
||
if(!pMap.isEmpty() && pMap.contains(uid)){
|
||
auto info = pMap.value(uid);
|
||
|
||
for(auto &widget:_curWidget){
|
||
int nCate = widget->property("category").toInt();
|
||
int nGraph = widget->property("graphType").toInt();
|
||
QString sPara = widget->property("connectPara").toString();
|
||
|
||
for(auto& data:info){
|
||
if(data.sConnectPara == sPara){
|
||
if(nCate == 0){
|
||
QLabel* pLabel = dynamic_cast<QLabel*>(widget);
|
||
pLabel->setText(QString::number(data.mapValue.last()));
|
||
}
|
||
else{
|
||
if(nGraph == 0){ //折线图
|
||
// 转换为 QVector<QPointF>
|
||
QVector<QPointF> points;
|
||
points.reserve(data.mapValue.size()); // 预分配内存以提高性能
|
||
|
||
// 遍历 QMap
|
||
for (auto it = data.mapValue.constBegin(); it != data.mapValue.constEnd(); ++it) {
|
||
// 将 quint64 时间戳转换为 qreal(QPointF 使用 qreal)
|
||
qint64 timestampMs = it.key() / 1000000; // 纳秒转毫秒
|
||
points.append(QPointF(static_cast<qreal>(timestampMs), it.value()));
|
||
}
|
||
QChartView* pView = dynamic_cast<QChartView*>(widget);
|
||
updateLineChartData(pView,points);
|
||
}
|
||
else if(nGraph == 1){
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
FixedPortsModel* MonitorAttributeGroupDlg::getModelController()
|
||
{
|
||
FixedPortsModel* pModel;
|
||
if(_curMode == 0){
|
||
pModel = _pParent->getParent()->getParent()->getModelController();
|
||
}
|
||
else{
|
||
pModel = _pDetailParent->getParent()->getModelController();
|
||
}
|
||
return pModel;
|
||
}
|
||
|
||
QUuid MonitorAttributeGroupDlg::getCurUid()
|
||
{
|
||
if(_curMode == 0){
|
||
return _pParent->getCurId();
|
||
}
|
||
else{
|
||
return _pDetailParent->getCurId();
|
||
}
|
||
}
|