518 lines
12 KiB
C++
518 lines
12 KiB
C++
#include "fitcurvedialog.h"
|
|
|
|
#include <QLogValueAxis>
|
|
|
|
#include "../DockTitleBar.h"
|
|
#include "../DockWidget.h"
|
|
|
|
#include "common/SpdLogger.h"
|
|
#include "workspace/WorkSpace.h"
|
|
#include "workspace/Timestep.h"
|
|
#include "workspace/WorkSpaceManager.h"
|
|
|
|
FitCurveDialog::FitCurveDialog(QWidget* parent) :
|
|
QDialog(parent),
|
|
ui(new Ui::FitCurveDialog)
|
|
{
|
|
m_iXMin = 0;
|
|
m_iXMax = 0;
|
|
m_iYMax = 0;
|
|
m_iYMin = 0;
|
|
|
|
initQChartView();
|
|
|
|
connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged, this, &FitCurveDialog::OnWorkSpaceChanged);
|
|
}
|
|
|
|
void FitCurveDialog::initQChartView() {
|
|
curveChartView = new FitCurveChartView(this);
|
|
curveChartView->setMaximumWidth(1730);
|
|
curveChartView->setMinimumHeight(480);
|
|
|
|
curveChart = new QChart();
|
|
curveChart->setTheme(QChart::ChartThemeBlueIcy);
|
|
curveChart->setBackgroundRoundness(0);
|
|
curveChartView->setChart(curveChart);
|
|
|
|
m_pAxisX = new QValueAxis;
|
|
m_pAxisX->setRange(0, 10);
|
|
m_pAxisX->setLabelsAngle(-90);
|
|
curveChart->addAxis(m_pAxisX, Qt::AlignBottom);
|
|
|
|
m_pAxisY = new QValueAxis;
|
|
m_pAxisY->setRange(0, 10);
|
|
curveChart->addAxis(m_pAxisY, Qt::AlignLeft);
|
|
|
|
curveChartView->setRenderHint(QPainter::Antialiasing);
|
|
|
|
QHBoxLayout* pLayout = new QHBoxLayout(this);
|
|
pLayout->addWidget(curveChartView);
|
|
}
|
|
|
|
void FitCurveDialog::theSlotMouseEvent(int eventId, QMouseEvent* event) {
|
|
if (eventId == 0) {
|
|
isPressed = true;
|
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
|
pressedPoint = mouseEvent->pos();
|
|
}
|
|
else if (eventId == 1) {
|
|
if (isPressed) {
|
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
|
curveChart->scroll(-(mouseEvent->pos().x() - pressedPoint.x()) / 10,
|
|
(mouseEvent->pos().y() - pressedPoint.y()) / 10);
|
|
}
|
|
}
|
|
else if (eventId == 2) {
|
|
isPressed = false;
|
|
}
|
|
else if (eventId == 3) {
|
|
resetZoomAndScroll();
|
|
}
|
|
}
|
|
|
|
void FitCurveDialog::theSlotWheelEvent(QWheelEvent* event) {
|
|
int delta = event->angleDelta().y();
|
|
if (delta > 0) {
|
|
curveChart->zoom(0.95);
|
|
}
|
|
else {
|
|
curveChart->zoom(1.05);
|
|
}
|
|
}
|
|
|
|
void FitCurveDialog::slotUpdateTime(double dTime)
|
|
{
|
|
updateWaveData(dTime);
|
|
updateReportData(dTime);
|
|
}
|
|
|
|
void FitCurveDialog::resetZoomAndScroll() {
|
|
curveChart->zoomReset();
|
|
QList<QAbstractAxis*> axesX, axesY;
|
|
axesX = curveChart->axes(Qt::Horizontal);
|
|
axesY = curveChart->axes(Qt::Vertical);
|
|
QValueAxis* curAxisX = (QValueAxis*)axesX[0];
|
|
QValueAxis* curAxisY = (QValueAxis*)axesY[0];
|
|
curAxisX->setRange(m_iXMin, m_iXMax);
|
|
curAxisY->setRange(m_iYMin, m_iYMax);
|
|
}
|
|
|
|
QVector<int> FitCurveDialog::getAxisRanges() {
|
|
QList<QAbstractAxis*> axesX, axesY;
|
|
axesX = curveChart->axes(Qt::Horizontal);
|
|
axesY = curveChart->axes(Qt::Vertical);
|
|
QValueAxis* curAxisX = (QValueAxis*)axesX[0];
|
|
QValueAxis* curAxisY = (QValueAxis*)axesY[0];
|
|
QVector<int> ranges = { int(curAxisX->min()), int(curAxisX->max()), int(curAxisY->min()), int(curAxisY->max()) };
|
|
return ranges;
|
|
}
|
|
|
|
void FitCurveDialog::updateTitle(const QString & title)
|
|
{
|
|
if (nullptr != m_pDockTitleBar)
|
|
{
|
|
m_pDockTitleBar->SetTitle(title);
|
|
}
|
|
}
|
|
|
|
void FitCurveDialog::updateTitleAxis(const QString & xTitle, const QString & yTitle)
|
|
{
|
|
if (m_pAxisX)
|
|
{
|
|
if (!xTitle.isEmpty())
|
|
{
|
|
m_pAxisX->setTitleText(xTitle);
|
|
}
|
|
}
|
|
if (m_pAxisY)
|
|
{
|
|
if (!yTitle.isEmpty())
|
|
{
|
|
m_pAxisY->setTitleText(yTitle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FitCurveDialog::updateMinMaxX(float min, float max, int count)
|
|
{
|
|
if (max > min)
|
|
{
|
|
m_iXMin = min;
|
|
m_iXMax = max;
|
|
|
|
QList<QAbstractAxis*> axesX;
|
|
axesX = curveChart->axes(Qt::Horizontal);
|
|
QValueAxis* curAxisX = (QValueAxis*)axesX[0];
|
|
curAxisX->setRange(m_iXMin, m_iXMax);
|
|
|
|
if (count > 0)
|
|
{
|
|
curAxisX->setTickCount(count);
|
|
curAxisX->setLabelFormat("%d");
|
|
}
|
|
}
|
|
}
|
|
|
|
void FitCurveDialog::updateMinMaxY(float min, float max, int count)
|
|
{
|
|
if (max > min)
|
|
{
|
|
m_iYMin = min;
|
|
m_iYMax = max;
|
|
|
|
QList<QAbstractAxis*> axesY;
|
|
axesY = curveChart->axes(Qt::Vertical);
|
|
QValueAxis* curAxisY = (QValueAxis*)axesY[0];
|
|
curAxisY->setRange(m_iYMin, m_iYMax);
|
|
|
|
if (count > 0)
|
|
{
|
|
curAxisY->setTickCount(count);
|
|
curAxisY->setLabelFormat("%d");
|
|
}
|
|
}
|
|
}
|
|
|
|
void FitCurveDialog::updateParseWaveFile(const QString& strFile, int nT, QVariantList 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++)
|
|
{
|
|
QVariantMap mapCurve = listCurve.at(nI).toMap();
|
|
QString strName = mapCurve.value("Name").toString();
|
|
QString strColor = mapCurve.value("Color").toString();
|
|
QColor color = QColor(strColor.section(",", 0, 0).toInt(), strColor.section(",", 1, 1).toInt(), strColor.section(",", 2, 2).toInt());
|
|
|
|
QSplineSeries *pSeries = new QSplineSeries(this);
|
|
pSeries->setName(strName);
|
|
pSeries->setColor(color);
|
|
pSeries->setUseOpenGL(true);
|
|
//pSeries->attachAxis(m_pAxisY);
|
|
//pSeries->attachAxis(m_pAxisX);
|
|
curveChart->addSeries(pSeries);
|
|
m_seriesIDMap.insert(nI, pSeries);
|
|
|
|
QPen pen(color);
|
|
pen.setWidth(2);
|
|
pSeries->setPen(pen);
|
|
|
|
QList<QAbstractAxis*> axesX;
|
|
axesX = curveChart->axes(Qt::Horizontal);
|
|
QValueAxis* curAxisX = (QValueAxis*)axesX[0];
|
|
pSeries->attachAxis(curAxisX);
|
|
|
|
QList<QAbstractAxis*> 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<int, QVariantList> mapData;
|
|
for (int nI = 0; nI < listCurve.size(); nI++)
|
|
{
|
|
QVariantMap mapCurve = listCurve.at(nI).toMap();
|
|
int nStart = mapCurve.value("Start").toInt();
|
|
int nStop = mapCurve.value("Stop").toInt();
|
|
|
|
if (bResetAxisX)
|
|
{
|
|
int nMax = nStop - nStart;
|
|
if (m_iXMax < nMax)
|
|
{
|
|
m_iXMax = nMax;
|
|
}
|
|
}
|
|
|
|
QVariantList listData;
|
|
for (int nJ = nStart; nJ < nStop; 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 FitCurveDialog::updateParseReportFile(const QString & strFile, int nT, QVariantList 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++)
|
|
{
|
|
QVariantMap mapCurve = listCurve.at(nI).toMap();
|
|
QString strName = mapCurve.value("Name").toString();
|
|
QString strColor = mapCurve.value("Color").toString();
|
|
QColor color = QColor(strColor.section(",", 0, 0).toInt(), strColor.section(",", 1, 1).toInt(), strColor.section(",", 2, 2).toInt());
|
|
|
|
QSplineSeries *pSeries = new QSplineSeries(this);
|
|
pSeries->setName(strName);
|
|
pSeries->setColor(color);
|
|
pSeries->setUseOpenGL(true);
|
|
//pSeries->attachAxis(m_pAxisY);
|
|
//pSeries->attachAxis(m_pAxisX);
|
|
curveChart->addSeries(pSeries);
|
|
m_seriesIDMap.insert(nI, pSeries);
|
|
|
|
QPen pen(color);
|
|
pen.setWidth(2);
|
|
pSeries->setPen(pen);
|
|
|
|
QList<QAbstractAxis*> axesX;
|
|
axesX = curveChart->axes(Qt::Horizontal);
|
|
QValueAxis* curAxisX = (QValueAxis*)axesX[0];
|
|
pSeries->attachAxis(curAxisX);
|
|
|
|
QList<QAbstractAxis*> 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<int, QPointF> mapData;
|
|
for (int nI = 0; nI < listCurve.size(); nI++)
|
|
{
|
|
QVariantMap mapCurve = listCurve.at(nI).toMap();
|
|
int xIndex = mapCurve.value("x").toInt();
|
|
int yIndex = mapCurve.value("y").toInt();
|
|
double x = listLine.at(xIndex).toDouble();
|
|
double y = listLine.at(yIndex).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 FitCurveDialog::OnWorkSpaceChanged(WorkSpace* worksapce) {
|
|
if (worksapce == nullptr) {
|
|
LOG_ERROR("worksapce is nullptr");
|
|
return;
|
|
}
|
|
|
|
connect(worksapce, &WorkSpace::TimestepChanged, this, &FitCurveDialog::OnTimestepChanged);
|
|
}
|
|
|
|
void FitCurveDialog::OnTimestepChanged(Timestep* timestep) {
|
|
if (timestep == nullptr) {
|
|
LOG_ERROR("timestep is nullptr");
|
|
return;
|
|
}
|
|
connect(timestep, SIGNAL(TimeChanged(double)), this, SLOT(slotUpdateTime(double)));
|
|
}
|
|
|
|
FitCurveDialog::~FitCurveDialog()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void FitCurveDialog::AttachDock(DockWidget* dockWidget)
|
|
{
|
|
if (nullptr == dockWidget) {
|
|
qDebug() << __FUNCTION__ << "dockwidget is nullptr";
|
|
return;
|
|
}
|
|
|
|
dockWidget->SetDockWidgetTitleBar(nullptr);
|
|
dockWidget->setWidget(this);
|
|
|
|
DockTitleBar* dockTitleBar = new DockTitleBar;
|
|
m_pDockTitleBar = dockTitleBar;
|
|
|
|
dockWidget->SetDockWidgetTitleBar(dockTitleBar);
|
|
}
|
|
|
|
void FitCurveDialog::updateWaveData(double t)
|
|
{
|
|
if (m_dataWava.size() > 0)
|
|
{
|
|
QMap< double, QMap<int, QVariantList> >::const_iterator ite = m_dataWava.lowerBound(t);
|
|
if (ite == m_dataWava.end())
|
|
{
|
|
ite--;
|
|
}
|
|
|
|
QMap<int, QVariantList> mapData = ite.value();
|
|
for (QMap<int, QVariantList>::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 FitCurveDialog::updateReportData(double t)
|
|
{
|
|
if (m_dataReport.size() > 0)
|
|
{
|
|
for (QMap<int, QSplineSeries*>::Iterator itSeries = m_seriesIDMap.begin(); itSeries != m_seriesIDMap.end(); itSeries++)
|
|
{
|
|
QSplineSeries* pSeries = itSeries.value();
|
|
if (pSeries)
|
|
{
|
|
pSeries->clear();
|
|
}
|
|
}
|
|
|
|
QMap< double, QMap<int, QPointF> >::const_iterator ite = m_dataReport.lowerBound(t);
|
|
if (ite != m_dataReport.end())
|
|
{
|
|
ite++;
|
|
}
|
|
|
|
for (QMap< double, QMap<int, QPointF> >::Iterator itA = m_dataReport.begin(); itA != ite; itA++)
|
|
{
|
|
double dTime = itA.key();
|
|
QMap<int, QPointF> mapData = itA.value();
|
|
for (QMap<int, QPointF>::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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|