#include "monitorAttributeGroupDlg.h" #include "monitorAttributeDlg.h" #include "monitorSideBarDlg.h" #include "monitorPanel.h" #include "monitorDetailAttributeDlg.h" #include #include #include #include #include #include #include #include #include #include #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 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& 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(chart->series().first()); if (!series) return; } series->clear(); // 计算数据范围 qint64 minTime = std::numeric_limits::max(); qint64 maxTime = std::numeric_limits::lowest(); double minVal = std::numeric_limits::max(); double maxVal = std::numeric_limits::lowest(); for (const QPointF& point : data) { qint64 t = static_cast(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 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(axis)) { xAxis = qobject_cast(axis); } else if (!yAxis && qobject_cast(axis)) { yAxis = qobject_cast(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((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(widget); pLabel->setText(QString::number(data.mapValue.last())); } else{ if(nGraph == 0){ //折线图 // 转换为 QVector QVector 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(timestampMs), it.value())); } QChartView* pView = dynamic_cast(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(); } }