From 7de04d4c34739de05a9f064540d8e96d9ac87cb2 Mon Sep 17 00:00:00 2001 From: pimin <362371171@qq.com> Date: Mon, 27 Oct 2025 15:26:32 +0800 Subject: [PATCH] modified curvepanel --- src/ui/Panel/CurvePanel.cpp | 334 +++++++++++++++++++++++++++- src/ui/Panel/CurvePanel.h | 7 + src/ui/Panel/DataPanelManager.cpp | 10 +- src/workspace/FileEntry.cpp | 40 +++- src/workspace/FileEntry.h | 10 + src/workspace/WorkSpaceXMLParse.cpp | 35 ++- 6 files changed, 405 insertions(+), 31 deletions(-) diff --git a/src/ui/Panel/CurvePanel.cpp b/src/ui/Panel/CurvePanel.cpp index 1632e8f9..848d380a 100644 --- a/src/ui/Panel/CurvePanel.cpp +++ b/src/ui/Panel/CurvePanel.cpp @@ -1,5 +1,6 @@ #include "ui/Panel/CurvePanel.h" #include "ui/DockWidget.h" +#include "ui/DockTitleBar.h" #include "common/SpdLogger.h" #include @@ -325,15 +326,42 @@ void CurvePanel::initQChartView() { curveChartView->setRenderHint(QPainter::Antialiasing); QHBoxLayout* pLayout = new QHBoxLayout(this); + pLayout->setContentsMargins(0, 0, 0, 0); pLayout->addWidget(curveChartView); } void CurvePanel::OnDataPanelUpdated(FileEntryCurve* fileEntry) { - FileEntryCurve::ChartProperties prop = fileEntry->GetChartProperties(); + FileEntryCurve::ChartProperties propChart = fileEntry->GetChartProperties(); - updateTitleAxis(prop.xTitle, prop.yTitle); - updateMinMaxX(prop.xMin, prop.xMax, prop.xCount); - updateMinMaxY(prop.yMin, prop.yMax, prop.yCount); + QString strName = fileEntry->GetName(); + updateTitle(strName); + + updateTitleAxis(propChart.xTitle, propChart.yTitle); + updateMinMaxX(propChart.xMin, propChart.xMax, propChart.xCount); + updateMinMaxY(propChart.yMin, propChart.yMax, propChart.yCount); + + FileEntryCurve::CurveProperties propCurves = fileEntry->GetCurveProperties(); + if (propCurves.size() > 0) + { + QString strFile = fileEntry->GetPath(); + + if (propCurves.at(0).start == 0 && propCurves.at(0).stop == 0) + { + updateParseReportFile(strFile, propChart.timeParam, propCurves); + } + else + { + updateParseWaveFile(strFile, propChart.timeParam, propCurves); + } + } +} + +void CurvePanel::updateTitle(const QString & title) +{ + if (nullptr != dockWidget_) + { + dockWidget_->setWindowTitle(title); + } } void CurvePanel::updateTitleAxis(const QString & xTitle, const QString & yTitle) @@ -392,4 +420,300 @@ void CurvePanel::updateMinMaxY(float min, float max, int count) curAxisY->setLabelFormat("%d"); } } -} \ No newline at end of file +} + +void CurvePanel::updateParseWaveFile(const QString& strFile, int nT, FileEntryCurve::CurveProperties listCurve) +{ + if (strFile.isEmpty()) + { + QMessageBox::information(nullptr, QStringLiteral("Error"), QStringLiteral("Please check Wave file path")); + return; + } + + QFile file(strFile); + if (file.open(QIODevice::ReadOnly)) + { + for (int nI = 0; nI < listCurve.size(); nI++) + { + FileEntryCurve::CurveProperty propCurve = listCurve.at(nI); + + QSplineSeries *pSeries = new QSplineSeries(this); + pSeries->setName(propCurve.name); + pSeries->setColor(propCurve.color); + pSeries->setUseOpenGL(true); + //pSeries->attachAxis(m_pAxisY); + //pSeries->attachAxis(m_pAxisX); + curveChart->addSeries(pSeries); + m_seriesIDMap.insert(nI, pSeries); + + QPen pen(propCurve.color); + pen.setWidth(2); + pSeries->setPen(pen); + + QList axesX; + axesX = curveChart->axes(Qt::Horizontal); + QValueAxis* curAxisX = (QValueAxis*)axesX[0]; + pSeries->attachAxis(curAxisX); + + QList axesY; + axesY = curveChart->axes(Qt::Vertical); + QValueAxis* curAxisY = (QValueAxis*)axesY[0]; + pSeries->attachAxis(curAxisY); + } + + bool bResetAxisX = false; + if (m_iXMax == m_iXMin) + { + bResetAxisX = true; + } + bool bResetAxisY = false; + if (m_iYMax == m_iYMin) + { + bResetAxisY = true; + } + + float maxY = -10000000.0; + float minY = 10000000.0; + + while (!file.atEnd()) + { + QString strLine = file.readLine().simplified(); + if (!strLine.isEmpty()) + { + QStringList listLine = strLine.split(" "); + double t = listLine.at(nT).toDouble(); + + QMap mapData; + for (int nI = 0; nI < listCurve.size(); nI++) + { + FileEntryCurve::CurveProperty propCurve = listCurve.at(nI); + + if (bResetAxisX) + { + int nMax = propCurve.stop - propCurve.start; + if (m_iXMax < nMax) + { + m_iXMax = nMax; + } + } + + QVariantList listData; + for (int nJ = propCurve.start; nJ < propCurve.stop; nJ++) + { + double value = listLine.at(nJ).toDouble(); + listData.push_back(value); + + if (bResetAxisY) + { + if (value < minY) + { + minY = value; + } + if (value > maxY) + { + maxY = value; + } + } + } + mapData.insert(nI, listData); + } + m_dataWava.insert(t, mapData); + } + } + + if (bResetAxisX) + { + updateMinMaxX(0, m_iXMax * 1.1, 0); + } + if (bResetAxisY) + { + updateMinMaxY(minY * 0.9, maxY * 1.1, 0); + } + + file.close(); + } +} + +void CurvePanel::updateParseReportFile(const QString & strFile, int nT, FileEntryCurve::CurveProperties listCurve) +{ + if (strFile.isEmpty()) + { + QMessageBox::information(nullptr, QStringLiteral("Error"), QStringLiteral("Please check data file path")); + return; + } + + QFile file(strFile); + if (file.open(QIODevice::ReadOnly)) + { + for (int nI = 0; nI < listCurve.size(); nI++) + { + FileEntryCurve::CurveProperty propCurve = listCurve.at(nI); + + QSplineSeries *pSeries = new QSplineSeries(this); + pSeries->setName(propCurve.name); + pSeries->setColor(propCurve.color); + pSeries->setUseOpenGL(true); + //pSeries->attachAxis(m_pAxisY); + //pSeries->attachAxis(m_pAxisX); + curveChart->addSeries(pSeries); + m_seriesIDMap.insert(nI, pSeries); + + QPen pen(propCurve.color); + pen.setWidth(2); + pSeries->setPen(pen); + + QList axesX; + axesX = curveChart->axes(Qt::Horizontal); + QValueAxis* curAxisX = (QValueAxis*)axesX[0]; + pSeries->attachAxis(curAxisX); + + QList axesY; + axesY = curveChart->axes(Qt::Vertical); + QValueAxis* curAxisY = (QValueAxis*)axesY[0]; + pSeries->attachAxis(curAxisY); + } + + bool bResetAxisX = false; + if (m_iXMax == m_iXMin) + { + bResetAxisX = true; + } + bool bResetAxisY = false; + if (m_iYMax == m_iYMin) + { + bResetAxisY = true; + } + + float maxX = -10000000.0; + float minX = 10000000.0; + float maxY = -10000000.0; + float minY = 10000000.0; + + while (!file.atEnd()) + { + QString strLine = file.readLine().simplified(); + if (!strLine.isEmpty()) + { + QStringList listLine = strLine.split(" "); + double t = listLine.at(nT).toDouble(); + + QMap mapData; + for (int nI = 0; nI < listCurve.size(); nI++) + { + FileEntryCurve::CurveProperty propCurve = listCurve.at(nI); + + double x = listLine.at(propCurve.x).toDouble(); + double y = listLine.at(propCurve.y).toDouble(); + + QPointF ptData = QPointF(x, y); + mapData.insert(nI, ptData); + + if (bResetAxisX) + { + if (x < minX) + { + minX = x; + } + if (x > maxX) + { + maxX = x; + } + } + if (bResetAxisY) + { + if (y < minY) + { + minY = y; + } + if (y > maxY) + { + maxY = y; + } + } + } + m_dataReport.insert(t, mapData); + } + } + + if (bResetAxisX) + { + updateMinMaxX(minX * 0.9, maxX * 1.1, 0); + } + if (bResetAxisY) + { + updateMinMaxY(minY * 0.9, maxY * 1.1, 0); + } + + file.close(); + } +} + +void CurvePanel::updateWaveData(double t) +{ + if (m_dataWava.size() > 0) + { + QMap< double, QMap >::const_iterator ite = m_dataWava.lowerBound(t); + if (ite == m_dataWava.end()) + { + ite--; + } + + QMap mapData = ite.value(); + for (QMap::Iterator it = mapData.begin(); it != mapData.end(); it++) + { + int nIndex = it.key(); + QVariantList dataList = it.value(); + + QSplineSeries* pSeries = m_seriesIDMap.value(nIndex); + if (pSeries) + { + pSeries->clear(); + for (int nI = 0; nI < dataList.size(); nI++) + { + float fY = dataList.at(nI).toFloat(); + pSeries->append(QPointF(nI, fY)); + } + } + } + } +} + +void CurvePanel::updateReportData(double t) +{ + if (m_dataReport.size() > 0) + { + for (QMap::Iterator itSeries = m_seriesIDMap.begin(); itSeries != m_seriesIDMap.end(); itSeries++) + { + QSplineSeries* pSeries = itSeries.value(); + if (pSeries) + { + pSeries->clear(); + } + } + + QMap< double, QMap >::const_iterator ite = m_dataReport.lowerBound(t); + if (ite != m_dataReport.end()) + { + ite++; + } + + for (QMap< double, QMap >::Iterator itA = m_dataReport.begin(); itA != ite; itA++) + { + double dTime = itA.key(); + QMap mapData = itA.value(); + for (QMap::Iterator it = mapData.begin(); it != mapData.end(); it++) + { + int nIndex = it.key(); + QPointF data = it.value(); + + QSplineSeries* pSeries = m_seriesIDMap.value(nIndex); + if (pSeries) + { + pSeries->append(data); + } + } + } + + + } +} diff --git a/src/ui/Panel/CurvePanel.h b/src/ui/Panel/CurvePanel.h index efacdc84..3f1b28b6 100644 --- a/src/ui/Panel/CurvePanel.h +++ b/src/ui/Panel/CurvePanel.h @@ -78,10 +78,17 @@ private: */ void UpdateCurveDisplay(); + void updateTitle(const QString& title); void updateTitleAxis(const QString& xTitle, const QString& yTitle); void updateMinMaxX(float min, float max, int count); void updateMinMaxY(float min, float max, int count); + void updateParseWaveFile(const QString& strFile, int nT, FileEntryCurve::CurveProperties listCurve); + void updateParseReportFile(const QString& strFile, int nT, FileEntryCurve::CurveProperties listCurve); + + void updateWaveData(double t); + void updateReportData(double t); + private: Ui::FitCurve* ui; FitCurveChartView* curveChartView; diff --git a/src/ui/Panel/DataPanelManager.cpp b/src/ui/Panel/DataPanelManager.cpp index 6450dc68..3c85b607 100644 --- a/src/ui/Panel/DataPanelManager.cpp +++ b/src/ui/Panel/DataPanelManager.cpp @@ -193,6 +193,11 @@ DataPanel* DataPanelManager::CreateDataPanel(FileEntryType fileType, const QStri return nullptr; } + dockWidget->setWidget(panel); + + // Set panel's dock widget reference + panel->SetDockWidget(dockWidget); + auto fileEntries = currentWorkspace_->GetFileEntries(fileType); if (index < fileEntries.size()) { panel->SetFileEntry(fileEntries[index]); @@ -200,11 +205,6 @@ DataPanel* DataPanelManager::CreateDataPanel(FileEntryType fileType, const QStri panel->RefreshPanel(); } - dockWidget->setWidget(panel); - - // Set panel's dock widget reference - panel->SetDockWidget(dockWidget); - // Connect panel signals connect(panel, &DataPanel::PanelClosed, this, &DataPanelManager::OnPanelClosed); diff --git a/src/workspace/FileEntry.cpp b/src/workspace/FileEntry.cpp index 27a2ca1d..47706214 100644 --- a/src/workspace/FileEntry.cpp +++ b/src/workspace/FileEntry.cpp @@ -276,26 +276,26 @@ bool FileEntryCurve::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocumen curveElement->SetAttribute("name", curve.name.toUtf8().constData()); curveElement->SetAttribute("color", QColorToString(curve.color).toUtf8().constData()); - curveElement->SetAttribute("startPoint", curve.start); - curveElement->SetAttribute("endPoint", curve.stop); + curveElement->SetAttribute("start", curve.start); + curveElement->SetAttribute("stop", curve.stop); } return true; } // FileEntryCurve ParseFiles implementation -bool FileEntryCurve::ParseFiles(const tinyxml2::XMLElement* element) { - if (!element) { +bool FileEntryCurve::ParseFiles(const tinyxml2::XMLElement* chartElement) { + if (!chartElement) { LOG_ERROR("Invalid XML element"); return false; } // 查找元素 - const tinyxml2::XMLElement* chartElement = element->FirstChildElement("chart"); - if (!chartElement) { - LOG_ERROR("No chart element found"); - return false; - } + //const tinyxml2::XMLElement* chartElement = element->FirstChildElement("chart"); + //if (!chartElement) { + // LOG_ERROR("No chart element found"); + // return false; + //} // 解析chart属性 const char* nameAttr = chartElement->Attribute("name"); @@ -335,8 +335,26 @@ bool FileEntryCurve::ParseFiles(const tinyxml2::XMLElement* element) { if (curveNameAttr) curve.name = QString::fromUtf8(curveNameAttr); if (colorAttr) curve.color = StringToQColor(QString::fromUtf8(colorAttr)); - curve.start = curveElement->IntAttribute("startPoint", 0); - curve.stop = curveElement->IntAttribute("endPoint", 0); + const char* startAttr = curveElement->Attribute("start"); + if (startAttr) + { + curve.start = curveElement->IntAttribute("start", 0); + } + const char* stopAttr = curveElement->Attribute("stop"); + if (stopAttr) + { + curve.stop = curveElement->IntAttribute("stop", 0); + } + const char* xAttr = curveElement->Attribute("x"); + if (xAttr) + { + curve.x = curveElement->IntAttribute("x", 0); + } + const char* yAttr = curveElement->Attribute("y"); + if (yAttr) + { + curve.y = curveElement->IntAttribute("y", 0); + } curveProperties_.append(curve); } diff --git a/src/workspace/FileEntry.h b/src/workspace/FileEntry.h index 1449257e..5148f29f 100644 --- a/src/workspace/FileEntry.h +++ b/src/workspace/FileEntry.h @@ -100,6 +100,16 @@ public: QColor color; int start; int stop; + int x; + int y; + + CurveProperty() { + name = ""; + start = 0; + stop = 0; + x = 0; + y = 0; + } }; using CurveProperties = QList; diff --git a/src/workspace/WorkSpaceXMLParse.cpp b/src/workspace/WorkSpaceXMLParse.cpp index 43f26d7d..737cb281 100644 --- a/src/workspace/WorkSpaceXMLParse.cpp +++ b/src/workspace/WorkSpaceXMLParse.cpp @@ -119,17 +119,32 @@ bool WorkSpaceXMLParse::ParseFiles(const tinyxml2::XMLElement* element) { // Create FileEntry objects and call their ParseFiles method FileEntryType enumType; if (FileEntryTypeFromString(name, enumType)) { + + const tinyxml2::XMLElement* chartElement = typeElement->FirstChildElement("chart"); + while (nullptr != chartElement) { + auto fileEntry = CreateEmptyFileEntry(enumType); // Create empty FileEntry for XML parsing + if (fileEntry) { + // Call the FileEntry's ParseFiles method to parse detailed data + if (fileEntry->ParseFiles(chartElement)) { + // Add the parsed FileEntry to workspace + workSpace_->SetFileEntry(fileEntry, false); + } + } + + chartElement = chartElement->NextSiblingElement(); + } + // Create FileEntry objects for this type - for (int i = 0; i < count; ++i) { - auto fileEntry = CreateEmptyFileEntry(enumType); // Create empty FileEntry for XML parsing - if (fileEntry) { - // Call the FileEntry's ParseFiles method to parse detailed data - if (fileEntry->ParseFiles(typeElement)) { - // Add the parsed FileEntry to workspace - workSpace_->SetFileEntry(fileEntry, false); - } - } - } + //for (int i = 0; i < count; ++i) { + // auto fileEntry = CreateEmptyFileEntry(enumType); // Create empty FileEntry for XML parsing + // if (fileEntry) { + // // Call the FileEntry's ParseFiles method to parse detailed data + // if (fileEntry->ParseFiles(typeElement)) { + // // Add the parsed FileEntry to workspace + // workSpace_->SetFileEntry(fileEntry, false); + // } + // } + //} // Also set file entry count for backward compatibility workSpace_->SetFileEntryCount(enumType, count);