From f0e7add76834807bb5af6c8dfa6e2655452b8a55 Mon Sep 17 00:00:00 2001 From: anotheruserofgithub <96748782+anotheruserofgithub@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:07:00 +0200 Subject: [PATCH] Fix time-related plots and diagram visualization issues (#11069) * Clean up time manager & browser time slot functions * Update diagram visualization once it is shown * Update diagram visualization even if plot shown * Update all plots and not only current plot window * Separate update of plots and diagram visualization * Init time slider and time label using time manager * Avoid duplicate computations when time changed * Fix visualization time within start/end range * Check time value within start/end bounds * Set final value to time slider * Set final value to time label * Set final value to speed box * Extract common time update * Fix browser update by timer * Standardize action tips --- OMEdit/OMEditLIB/Plotting/DiagramWindow.cpp | 1 + OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp | 175 +++++++++++------- OMEdit/OMEditLIB/Plotting/VariablesWidget.h | 8 +- OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp | 27 +-- OMPlot/OMPlot/OMPlotGUI/PlotWindow.h | 2 +- 5 files changed, 129 insertions(+), 84 deletions(-) diff --git a/OMEdit/OMEditLIB/Plotting/DiagramWindow.cpp b/OMEdit/OMEditLIB/Plotting/DiagramWindow.cpp index 2ba9c7c186c..931ede0b2e0 100644 --- a/OMEdit/OMEditLIB/Plotting/DiagramWindow.cpp +++ b/OMEdit/OMEditLIB/Plotting/DiagramWindow.cpp @@ -68,6 +68,7 @@ void DiagramWindow::showVisualizationDiagram(ModelWidget *pModelWidget) mpModelWidget = pModelWidget; mpModelWidget->getDiagramGraphicsView()->setIsVisualizationView(true); connect(MainWindow::instance()->getVariablesWidget(), SIGNAL(updateDynamicSelect(double)), mpModelWidget->getDiagramGraphicsView(), SIGNAL(updateDynamicSelect(double))); + MainWindow::instance()->getVariablesWidget()->updateVisualization(); mpModelWidget->getDiagramGraphicsView()->show(); mpMainLayout->addWidget(mpModelWidget->getDiagramGraphicsView()); } else { diff --git a/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp b/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp index b9d386edecb..7f9eb84c3f6 100644 --- a/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp +++ b/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp @@ -1442,7 +1442,7 @@ VariablesWidget::VariablesWidget(QWidget *pParent) mpToolBar->setIconSize(QSize(toolbarIconSize, toolbarIconSize)); // rewind action mpRewindAction = new QAction(QIcon(":/Resources/icons/initialize.svg"), tr("Rewind"), this); - mpRewindAction->setStatusTip(tr("Rewinds the visualization to the start")); + mpRewindAction->setStatusTip(tr("Rewind the visualization to the start")); connect(mpRewindAction, SIGNAL(triggered()), SLOT(rewindVisualization())); // play action mpPlayAction = new QAction(QIcon(":/Resources/icons/play_animation.svg"), Helper::animationPlay, this); @@ -1460,7 +1460,7 @@ VariablesWidget::VariablesWidget(QWidget *pParent) mpTimeTextBox = new QLineEdit("0.0"); mpTimeTextBox->setMaximumHeight(toolbarIconSize); mpTimeTextBox->setValidator(pDoubleValidator); - connect(mpTimeTextBox, SIGNAL(returnPressed()), SLOT(visulizationTimeChanged())); + connect(mpTimeTextBox, SIGNAL(returnPressed()), SLOT(visualizationTimeChanged())); // speed mpSpeedLabel = new Label; mpSpeedLabel->setText(Helper::speed); @@ -1864,8 +1864,8 @@ void VariablesWidget::initializeVisualization() mpTimeManager->setVisTime(mpTimeManager->getStartTime()); mpTimeManager->setPause(true); // reset the visualization controls - mpTimeTextBox->setText("0.0"); - mpSimulationTimeSlider->setValue(mpSimulationTimeSlider->minimum()); + mpTimeTextBox->setText(QString::number(mpTimeManager->getVisTime())); + mpSimulationTimeSlider->setValue(mpTimeManager->getTimeFraction()); enableVisualizationControls(true); } @@ -2373,43 +2373,86 @@ void VariablesWidget::unitChanged(const QModelIndex &index) /*! * \brief VariablesWidget::simulationTimeChanged * SLOT activated when mpSimulationTimeSlider valueChanged SIGNAL is raised. - * \param time + * \param value + */ +void VariablesWidget::simulationTimeChanged(int value) +{ + if (value >= 0) { + double start = mpTimeManager->getStartTime(); + double end = mpTimeManager->getEndTime(); + double time = (end - start) * (value / (double)mSliderRange) + start; + updateBrowserTime(time); + } else { + bool state = mpSimulationTimeSlider->blockSignals(true); + mpSimulationTimeSlider->setValue(mpTimeManager->getTimeFraction()); + mpSimulationTimeSlider->blockSignals(state); + } +} + +/*! + * \brief VariablesWidget::updateBrowserTime + * Updates the browser to the provided point of time + * \param time The new point of time */ -void VariablesWidget::simulationTimeChanged(int timePercent) +void VariablesWidget::updateBrowserTime(double time) { - double time = (mpTimeManager->getEndTime() - mpTimeManager->getStartTime()) * ((double)timePercent / (double)mSliderRange); + double start = mpTimeManager->getStartTime(); + double end = mpTimeManager->getEndTime(); + if (time < start) { + time = start; + } else if (time > end) { + time = end; + } mpTimeManager->setVisTime(time); mpTimeTextBox->setText(QString::number(mpTimeManager->getVisTime())); + bool state = mpSimulationTimeSlider->blockSignals(true); + mpSimulationTimeSlider->setValue(mpTimeManager->getTimeFraction()); + mpSimulationTimeSlider->blockSignals(state); + updateVisualization(); + updatePlotWindows(); +} - PlotWindow *pPlotWindow = MainWindow::instance()->getPlotWindowContainer()->getCurrentWindow(); - if (pPlotWindow) { +/*! + * \brief VariablesWidget::updatePlotWindows + * Updates the plot windows. + */ +void VariablesWidget::updatePlotWindows() +{ + double time = mpTimeManager->getVisTime(); + foreach (QMdiSubWindow *pSubWindow, MainWindow::instance()->getPlotWindowContainer()->subWindowList(QMdiArea::StackingOrder)) { try { - PlotWindow::PlotType plotType = pPlotWindow->getPlotType(); - if (plotType == PlotWindow::PLOTARRAY) { - QList curves = pPlotWindow->getPlot()->getPlotCurvesList(); - foreach (PlotCurve* curve, curves) { - QString varName = curve->getYVariable(); - pPlotWindow->setVariablesList(QStringList(varName)); - pPlotWindow->plotArray(time, curve); - } - } else if (plotType == PlotWindow::PLOTARRAYPARAMETRIC) { - QList curves = pPlotWindow->getPlot()->getPlotCurvesList(); - foreach (PlotCurve* curve, curves) { - QString xVarName = curve->getXVariable(); - QString yVarName = curve->getYVariable(); - pPlotWindow->setVariablesList({xVarName,yVarName}); - pPlotWindow->plotArrayParametric(time, curve); + if (MainWindow::instance()->getPlotWindowContainer()->isPlotWindow(pSubWindow->widget())) { + PlotWindow *pPlotWindow = qobject_cast(pSubWindow->widget()); + PlotWindow::PlotType plotType = pPlotWindow->getPlotType(); + if (plotType == PlotWindow::PLOTARRAY || plotType == PlotWindow::PLOTARRAYPARAMETRIC) { + QList curves = pPlotWindow->getPlot()->getPlotCurvesList(); + if (curves.isEmpty()) { + if (!pPlotWindow->getFooter().isEmpty()) { + pPlotWindow->setTime(time); + pPlotWindow->updateTimeText(); + } + } else if (plotType == PlotWindow::PLOTARRAY) { + foreach (PlotCurve* curve, curves) { + QString varName = curve->getYVariable(); + pPlotWindow->setVariablesList(QStringList(varName)); + pPlotWindow->plotArray(time, curve); + } + } else { + foreach (PlotCurve* curve, curves) { + QString xVarName = curve->getXVariable(); + QString yVarName = curve->getYVariable(); + pPlotWindow->setVariablesList({xVarName, yVarName}); + pPlotWindow->plotArrayParametric(time, curve); + } + } } - } else { - return; } } catch (PlotException &e) { MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, e.what(), Helper::scriptingKind, Helper::errorLevel)); } - } else { // if no plot window then try to update the DiagramWindow - updateVisualization(); } } + /*! * \brief VariablesWidget::valueEntered * Handles the case when a new value is entered in VariablesTreeView.\n @@ -2651,7 +2694,7 @@ void VariablesWidget::timeUnitChanged(QString unit) if (pPlotWindow->getPlotType() == PlotWindow::PLOTARRAY || pPlotWindow->getPlotType() == PlotWindow::PLOTARRAYPARAMETRIC) { pPlotWindow->setTimeUnit(unit); - pPlotWindow->updateTimeText(unit); + pPlotWindow->updateTimeText(); } else if (pPlotWindow->getPlotType() == PlotWindow::PLOT || pPlotWindow->getPlotType() == PlotWindow::PLOTINTERACTIVE) { OMCInterface::convertUnits_res convertUnit = MainWindow::instance()->getOMCProxy()->convertUnits(pPlotWindow->getTimeUnit(), unit); @@ -2806,10 +2849,14 @@ void VariablesWidget::showReSimulateSetup() */ void VariablesWidget::rewindVisualization() { - mpTimeManager->setVisTime(mpTimeManager->getStartTime()); - mpTimeManager->setRealTimeFactor(0.0); mpTimeManager->setPause(true); - mpSimulationTimeSlider->setValue(mpSimulationTimeSlider->minimum()); + mpTimeManager->setRealTimeFactor(0.0); + mpTimeManager->setVisTime(mpTimeManager->getStartTime()); + updateVisualization(); + updatePlotWindows(); + bool state = mpSimulationTimeSlider->blockSignals(true); + mpSimulationTimeSlider->setValue(mpTimeManager->getTimeFraction()); + mpSimulationTimeSlider->blockSignals(state); mpTimeTextBox->setText(QString::number(mpTimeManager->getVisTime())); } @@ -2832,39 +2879,33 @@ void VariablesWidget::pauseVisualization() } /*! - * \brief VariablesWidget::visulizationTimeChanged + * \brief VariablesWidget::visualizationTimeChanged * Slot activated when mpTimeTextBox returnPressed SIGNAL is raised. */ -void VariablesWidget::visulizationTimeChanged() +void VariablesWidget::visualizationTimeChanged() { - QString time = mpTimeTextBox->text(); - bool isDouble = true; - double start = mpTimeManager->getStartTime(); - double end = mpTimeManager->getEndTime(); - double value = time.toDouble(&isDouble); - if (isDouble && value >= 0.0) { - if (value < start) { - value = start; - } else if (value > end) { - value = end; - } - mpTimeManager->setVisTime(value); - mpSimulationTimeSlider->setValue(mpTimeManager->getTimeFraction()); - + bool isDouble = false; + double time = mpTimeTextBox->text().toDouble(&isDouble); + if (isDouble && time >= 0.0) { + updateBrowserTime(time); + } else { + mpTimeTextBox->setText(QString::number(mpTimeManager->getVisTime())); } } /*! * \brief VariablesWidget::visualizationSpeedChanged - * Slot activated when mpSpeedComboBox currentIndexChanged SIGNAL is raised. + * Slot activated when mpSpeedComboBox currentIndexChanged SIGNAL is raised, + * as well as when mpSpeedComboBox->lineEdit() textChanged SIGNAL is raised. */ void VariablesWidget::visualizationSpeedChanged() { - QString speed = mpSpeedComboBox->lineEdit()->text(); - bool isDouble = true; - double value = speed.toDouble(&isDouble); - if (isDouble && value > 0.0) { - mpTimeManager->setSpeedUp(value); + bool isDouble = false; + double speed = mpSpeedComboBox->lineEdit()->text().toDouble(&isDouble); + if (isDouble && speed > 0.0) { + mpTimeManager->setSpeedUp(speed); + } else { + mpSpeedComboBox->lineEdit()->setText(QString::number(mpTimeManager->getSpeedUp())); } } @@ -2874,24 +2915,32 @@ void VariablesWidget::visualizationSpeedChanged() */ void VariablesWidget::incrementVisualization() { - //measure realtime + // measure real time mpTimeManager->updateTick(); - //update scene and set next time step + // set next time step if (!mpTimeManager->isPaused()) { - mpTimeTextBox->setText(QString::number(mpTimeManager->getVisTime())); - // set time slider - int time = mpTimeManager->getTimeFraction(); - mpSimulationTimeSlider->setValue(time); - //finish animation with pause when endtime is reached + // finish animation with pause when end time is reached if (mpTimeManager->getVisTime() >= mpTimeManager->getEndTime()) { pauseVisualization(); - } else { // get the new visualization time - double newTime = mpTimeManager->getVisTime() + (mpTimeManager->getHVisual()*mpTimeManager->getSpeedUp()); + } else { + // set new visualization time + double newTime = mpTimeManager->getVisTime() + (mpTimeManager->getHVisual() * mpTimeManager->getSpeedUp()); if (newTime <= mpTimeManager->getEndTime()) { mpTimeManager->setVisTime(newTime); } else { mpTimeManager->setVisTime(mpTimeManager->getEndTime()); } } + // update browser + updateVisualization(); + updatePlotWindows(); + if (!mpTimeManager->isPaused()) { + // set time label + mpTimeTextBox->setText(QString::number(mpTimeManager->getVisTime())); + // set time slider + bool state = mpSimulationTimeSlider->blockSignals(true); + mpSimulationTimeSlider->setValue(mpTimeManager->getTimeFraction()); + mpSimulationTimeSlider->blockSignals(state); + } } } diff --git a/OMEdit/OMEditLIB/Plotting/VariablesWidget.h b/OMEdit/OMEditLIB/Plotting/VariablesWidget.h index 83a827a571c..c3bbef8276e 100644 --- a/OMEdit/OMEditLIB/Plotting/VariablesWidget.h +++ b/OMEdit/OMEditLIB/Plotting/VariablesWidget.h @@ -235,6 +235,9 @@ class VariablesWidget : public QWidget void interactiveReSimulation(QString modelName); void updateInitXmlFile(SimulationOptions simulationOptions); void initializeVisualization(); + void updateVisualization(); + void updatePlotWindows(); + void updateBrowserTime(double time); double readVariableValue(QString variable, double time); void closeResultFile(); private: @@ -263,14 +266,13 @@ class VariablesWidget : public QWidget QFile mPlotFileReader; void selectInteractivePlotWindow(VariablesTreeItem *pVariablesTreeItem); void openResultFile(double &startTime, double &stopTime); - void updateVisualization(); void checkVariable(const QModelIndex &index, bool checkState); void unCheckVariableAndErrorMessage(const QModelIndex &index, const QString &errorMessage); void unCheckCurveVariable(const QString &variable); public slots: void plotVariables(const QModelIndex &index, qreal curveThickness, int curveStyle, bool shiftKey, OMPlot::PlotCurve *pPlotCurve = 0, OMPlot::PlotWindow *pPlotWindow = 0); void unitChanged(const QModelIndex &index); - void simulationTimeChanged(int timePercent); + void simulationTimeChanged(int value); void valueEntered(const QModelIndex &index); void timeUnitChanged(QString unit); void updateVariablesTree(QMdiSubWindow *pSubWindow); @@ -282,7 +284,7 @@ public slots: private slots: void playVisualization(); void pauseVisualization(); - void visulizationTimeChanged(); + void visualizationTimeChanged(); void visualizationSpeedChanged(); void incrementVisualization(); signals: diff --git a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp index efdd4af99f6..798d24ab67a 100644 --- a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp +++ b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp @@ -902,7 +902,8 @@ void readPLTArray(QTextStream *mpTextStream, QString variable, double alpha, int return; } -double getTimeUnitFactor(QString timeUnit){ +double getTimeUnitFactor(QString timeUnit) +{ if (timeUnit == "ms") return 1000.0; else if (timeUnit == "s") return 1.0; else if (timeUnit == "min") return 1.0/6.0; @@ -911,8 +912,9 @@ double getTimeUnitFactor(QString timeUnit){ else throw PlotException(QObject::tr("Unknown unit in plotArray(Parametric).")); } -void PlotWindow::updateTimeText(QString unit) +void PlotWindow::updateTimeText() { + QString unit = getTimeUnit(); double timeUnitFactor = getTimeUnitFactor(unit); mpPlot->setFooter(QString("t = %1 " + unit).arg(getTime()*timeUnitFactor,0,'g',3)); mpPlot->replot(); @@ -923,7 +925,6 @@ void PlotWindow::plotArray(double time, PlotCurve *pPlotCurve) double *res; QString currentLine; setTime(time); - double timeUnitFactor = getTimeUnitFactor(getTimeUnit()); if (mVariablesList.isEmpty() && getPlotType() == PlotWindow::PLOTARRAY) throw NoVariableException(QString("No variables specified!").toStdString().c_str()); bool editCase = pPlotCurve ? true : false; @@ -984,8 +985,7 @@ void PlotWindow::plotArray(double time, PlotCurve *pPlotCurve) } pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize()); pPlotCurve->attach(mpPlot); - mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3)); - mpPlot->replot(); + updateTimeText(); } mFile.close(); } @@ -1044,9 +1044,7 @@ void PlotWindow::plotArray(double time, PlotCurve *pPlotCurve) } pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize()); pPlotCurve->attach(mpPlot); - mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3)); - mpPlot->replot(); - + updateTimeText(); } omc_free_csv_reader(csvReader); } @@ -1105,8 +1103,7 @@ void PlotWindow::plotArray(double time, PlotCurve *pPlotCurve) } pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize()); pPlotCurve->attach(mpPlot); - mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3)); - mpPlot->replot(); + updateTimeText(); delete[] res; } // if plottype is PLOT then check which requested variables are not found in the file @@ -1122,7 +1119,6 @@ void PlotWindow::plotArrayParametric(double time, PlotCurve *pPlotCurve) QString xVariable, yVariable, xTitle, yTitle; int pair = 0; setTime(time); - double timeUnitFactor = getTimeUnitFactor(getTimeUnit()); if (mVariablesList.isEmpty()) throw NoVariableException(QString("No variables specified!").toStdString().c_str()); else if (mVariablesList.size()%2 != 0) @@ -1202,8 +1198,7 @@ void PlotWindow::plotArrayParametric(double time, PlotCurve *pPlotCurve) } pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize()); pPlotCurve->attach(mpPlot); - mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3)); - mpPlot->replot(); + updateTimeText(); mFile.close(); } // //PLOT CSV @@ -1270,8 +1265,7 @@ void PlotWindow::plotArrayParametric(double time, PlotCurve *pPlotCurve) } pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize()); pPlotCurve->attach(mpPlot); - mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3)); - mpPlot->replot(); + updateTimeText(); omc_free_csv_reader(csvReader); } //PLOT MAT @@ -1343,8 +1337,7 @@ void PlotWindow::plotArrayParametric(double time, PlotCurve *pPlotCurve) } pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize()); pPlotCurve->attach(mpPlot); - mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3)); - mpPlot->replot(); + updateTimeText(); omc_free_matlab4_reader(&reader); } } diff --git a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h index 546add34c82..5470eda25c0 100644 --- a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h +++ b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h @@ -185,7 +185,7 @@ class PlotWindow : public QMainWindow void closeEvent(QCloseEvent *event); void setTime(double time){mTime = time;} double getTime() {return mTime;} - void updateTimeText(QString unit); + void updateTimeText(); void updateCurves(); void updateYAxis(QPair minMaxValues); void updatePlot();