DiagramDesigner/diagramCavas/source/monitorAttributeGroupDlg.cpp

341 lines
11 KiB
C++
Raw Normal View History

2025-11-21 19:22:41 +08:00
#include "monitorAttributeGroupDlg.h"
2025-11-25 20:29:32 +08:00
#include "monitorAttributeDlg.h"
#include "monitorSideBarDlg.h"
#include "monitorPanel.h"
#include "monitorDetailAttributeDlg.h"
2025-11-21 19:22:41 +08:00
#include <QScrollArea>
#include <QFormLayout>
#include <QLabel>
2025-11-25 20:29:32 +08:00
#include <QUuid>
#include <QChartView>
#include <QBarSeries>
#include <QBarCategoryAxis>
#include <QValueAxis>
#include <QLineSeries>
2025-12-25 09:03:35 +08:00
#include <QDateTimeAxis>
2025-11-25 20:29:32 +08:00
#include "global.h"
2025-11-21 19:22:41 +08:00
MonitorAttributeGroupDlg::MonitorAttributeGroupDlg(QWidget* parent)
: QScrollArea(parent)
,_layout(nullptr)
2025-11-25 20:29:32 +08:00
,_pParent(nullptr)
,_pDetailParent(nullptr)
,_curMode(0)
2025-11-21 19:22:41 +08:00
{
initial();
}
MonitorAttributeGroupDlg::~MonitorAttributeGroupDlg()
{
}
void MonitorAttributeGroupDlg::initial()
{
_layout = new QVBoxLayout(this);
}
2025-12-25 09:03:35 +08:00
void MonitorAttributeGroupDlg::createGroupView(QList<monitorItemAttributeInfo> lst,int nType)
2025-11-21 19:22:41 +08:00
{
QWidget* content = new QWidget();
2025-11-25 20:29:32 +08:00
QGridLayout* gridLayout = new QGridLayout(content);
2025-12-25 09:03:35 +08:00
gridLayout->setHorizontalSpacing(2);
2025-11-26 20:33:13 +08:00
gridLayout->setVerticalSpacing(10);
gridLayout->setContentsMargins(0, 0, 0, 0);
2025-11-25 20:29:32 +08:00
// 设置列的最小宽度和拉伸比例
gridLayout->setColumnMinimumWidth(0, 30); // 标签列最小宽度
gridLayout->setColumnStretch(0, 1); // 标签列拉伸因子
2025-12-25 09:03:35 +08:00
gridLayout->setColumnStretch(1, 8); // 控件列拉伸因子
2025-11-25 20:29:32 +08:00
int row = 0;
for(auto& info : lst) {
QLabel* label = new QLabel(info.sTag, this);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
label->setMaximumWidth(40); // 设置标签最大宽度
2025-11-21 19:22:41 +08:00
QWidget* editor = createEditor(info);
2025-11-25 20:29:32 +08:00
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);
2025-11-21 19:22:41 +08:00
setWidget(content);
setWidgetResizable(true);
}
2025-12-25 09:03:35 +08:00
QWidget* MonitorAttributeGroupDlg::createEditor(monitorItemAttributeInfo info,int nType)
2025-11-25 20:29:32 +08:00
{
QWidget* pWidget = nullptr;
if(info.nShowType == 0){ //正常显示
QLabel *label = new QLabel(this);
pWidget = label;
}
else{ //图表
QChartView* chartView = new QChartView(this);
2025-12-25 09:03:35 +08:00
QSize size;
if(nType == 0)
size = QSize(400,300);
else
size = QSize(600,400);
chartView->setMinimumSize(size);
2025-11-25 20:29:32 +08:00
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();
2025-11-26 20:33:13 +08:00
QFont axisFont;
axisFont.setPointSize(9);
2025-11-25 20:29:32 +08:00
// 创建图表
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);
2025-11-26 20:33:13 +08:00
// 设置坐标轴标题
axisX->setTitleText("时间");
axisX->setLabelsFont(axisFont);
axisX->setTitleFont(axisFont);
axisY->setTitleText("");
axisY->setLabelsFont(axisFont);
axisY->setTitleFont(axisFont);
2025-11-25 20:29:32 +08:00
chart->setTheme(QChart::ChartThemeLight);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
2025-11-26 20:33:13 +08:00
QFont legendFont = chart->legend()->font();
2025-12-25 09:03:35 +08:00
legendFont.setPointSize(9); // 设置图例字体大小
2025-11-26 20:33:13 +08:00
chart->legend()->setFont(legendFont);
2025-11-25 20:29:32 +08:00
}
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)
{
2025-12-25 09:03:35 +08:00
if (!chartView || data.isEmpty()) return;
2025-11-25 20:29:32 +08:00
QChart* chart = chartView->chart();
2025-12-25 09:03:35 +08:00
if (!chart) {
chart = new QChart();
chart->setAnimationOptions(QChart::NoAnimation);
chartView->setChart(chart);
}
2025-11-25 20:29:32 +08:00
2025-12-25 09:03:35 +08:00
QLineSeries* series = nullptr;
if (chart->series().isEmpty()) {
series = new QLineSeries();
chart->addSeries(series);
} else {
series = qobject_cast<QLineSeries*>(chart->series().first());
if (!series) return;
}
2025-11-25 20:29:32 +08:00
series->clear();
2025-12-25 09:03:35 +08:00
// 计算数据范围
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());
}
2025-11-25 20:29:32 +08:00
2025-12-25 09:03:35 +08:00
// ========== 简单直接的方法:确保只有一个坐标轴 ==========
QDateTimeAxis* xAxis = nullptr;
QValueAxis* yAxis = nullptr;
2025-11-25 20:29:32 +08:00
2025-12-25 09:03:35 +08:00
// 获取当前所有坐标轴
QList<QAbstractAxis*> allAxes = chart->axes();
2025-11-25 20:29:32 +08:00
2025-12-25 09:03:35 +08:00
// 如果坐标轴太多,清理所有
//if (allAxes.size() > 2) { // 应该只有x轴和y轴
for (auto axis : allAxes) {
chart->removeAxis(axis);
delete axis;
2025-11-25 20:29:32 +08:00
}
2025-12-25 09:03:35 +08:00
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);
}
}
2025-11-25 20:29:32 +08:00
2025-12-25 09:03:35 +08:00
// 创建缺失的坐标轴
if (!xAxis) {
xAxis = new QDateTimeAxis();
xAxis->setTitleText("时间");
chart->addAxis(xAxis, Qt::AlignBottom);
}
2025-11-25 20:29:32 +08:00
2025-12-25 09:03:35 +08:00
if (!yAxis) {
yAxis = new QValueAxis();
yAxis->setTitleText("");
chart->addAxis(yAxis, Qt::AlignLeft);
2025-11-25 20:29:32 +08:00
}
2025-12-25 09:03:35 +08:00
// 确保系列附加
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);
2025-11-25 20:29:32 +08:00
}
void MonitorAttributeGroupDlg::updateData()
{
2025-12-25 09:03:35 +08:00
if(_pParent || _pDetailParent){
2025-11-25 20:29:32 +08:00
auto pModel = getModelController();
auto pMap = pModel->getMonitorPara();
QUuid uid = getCurUid();
2025-12-25 09:03:35 +08:00
if(!pMap.isEmpty() && pMap.contains(uid)){
2025-11-25 20:29:32 +08:00
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);
2025-12-25 09:03:35 +08:00
pLabel->setText(QString::number(data.mapValue.last()));
2025-11-25 20:29:32 +08:00
}
else{
2025-12-25 09:03:35 +08:00
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 时间戳转换为 qrealQPointF 使用 qreal
qint64 timestampMs = it.key() / 1000000; // 纳秒转毫秒
points.append(QPointF(static_cast<qreal>(timestampMs), it.value()));
}
2025-11-25 20:29:32 +08:00
QChartView* pView = dynamic_cast<QChartView*>(widget);
2025-12-25 09:03:35 +08:00
updateLineChartData(pView,points);
}
else if(nGraph == 1){
2025-11-25 20:29:32 +08:00
}
}
}
}
}
}
}
}
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();
}
}