Skip to content

Commit

Permalink
Automatically pick the right prefix value for axes values (#7397)
Browse files Browse the repository at this point in the history
Fixes ticket #5447
The feature is optional and is off by default. Enable it via `Tools->Options->Plotting->General->Prefix Axes`.
  • Loading branch information
adeas31 committed Apr 21, 2021
1 parent 1870412 commit 07fe8a2
Show file tree
Hide file tree
Showing 19 changed files with 352 additions and 208 deletions.
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -2884,7 +2884,7 @@ function plotParametric "Launches a plotParametric window using OMPlot. Returns
input String grid = "detailed" "Sets the grid for the plot i.e simple, detailed, none.";
input Boolean logX = false "Determines whether or not the horizontal axis is logarithmically scaled.";
input Boolean logY = false "Determines whether or not the vertical axis is logarithmically scaled.";
input String xLabel = "time" "This text will be used as the horizontal label in the diagram.";
input String xLabel = "" "This text will be used as the horizontal label in the diagram.";
input String yLabel = "" "This text will be used as the vertical label in the diagram.";
input Real xRange[2] = {0.0,0.0} "Determines the horizontal interval that is visible in the diagram. {0,0} will select a suitable range.";
input Real yRange[2] = {0.0,0.0} "Determines the vertical interval that is visible in the diagram. {0,0} will select a suitable range.";
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFModelicaBuiltin.mo
Expand Up @@ -3107,7 +3107,7 @@ function plotParametric "Launches a plotParametric window using OMPlot. Returns
input String grid = "detailed" "Sets the grid for the plot i.e simple, detailed, none.";
input Boolean logX = false "Determines whether or not the horizontal axis is logarithmically scaled.";
input Boolean logY = false "Determines whether or not the vertical axis is logarithmically scaled.";
input String xLabel = "time" "This text will be used as the horizontal label in the diagram.";
input String xLabel = "" "This text will be used as the horizontal label in the diagram.";
input String yLabel = "" "This text will be used as the vertical label in the diagram.";
input Real xRange[2] = {0.0,0.0} "Determines the horizontal interval that is visible in the diagram. {0,0} will select a suitable range.";
input Real yRange[2] = {0.0,0.0} "Determines the vertical interval that is visible in the diagram. {0,0} will select a suitable range.";
Expand Down
1 change: 0 additions & 1 deletion OMCompiler/Compiler/runtime/unitparser.cpp
Expand Up @@ -1190,7 +1190,6 @@ void UnitParser::initSIUnits() {
addDerived("pressure", "millimeter of mercury", "mmHg", "Pa", Rational(0),
Rational(133322387415, 1000000000), Rational(0), true);

addDerived("time", "millisecond", "ms", "s", Rational(-3), Rational(1), Rational(0), true);
addDerived("time", "minute", "min", "s", Rational(0), Rational(60), Rational(0), true);
addDerived("time", "hour", "h", "s", Rational(0), Rational(60 * 60), Rational(0), true);
addDerived("time", "day", "d", "s", Rational(0), Rational(60 * 60 * 24), Rational(0), true);
Expand Down
10 changes: 10 additions & 0 deletions OMEdit/OMEditLIB/Options/OptionsDialog.cpp
Expand Up @@ -788,6 +788,10 @@ void OptionsDialog::readPlottingSettings()
if (mpSettings->contains("plotting/autoScale")) {
mpPlottingPage->getAutoScaleCheckBox()->setChecked(mpSettings->value("plotting/autoScale").toBool());
}
// read the prefix axes
if (mpSettings->contains("plotting/prefixAxes")) {
mpPlottingPage->getPrefixAxesCheckbox()->setChecked(mpSettings->value("plotting/prefixAxes").toBool());
}
// read the plotting view mode
if (mpSettings->contains("plotting/viewmode")) {
mpPlottingPage->setPlottingViewMode(mpSettings->value("plotting/viewmode").toString());
Expand Down Expand Up @@ -1407,6 +1411,8 @@ void OptionsDialog::savePlottingSettings()
{
// save the auto scale
mpSettings->setValue("plotting/autoScale", mpPlottingPage->getAutoScaleCheckBox()->isChecked());
// save the prefix axes
mpSettings->setValue("plotting/prefixAxes", mpPlottingPage->getPrefixAxesCheckbox()->isChecked());
// save plotting view mode
mpSettings->setValue("plotting/viewmode", mpPlottingPage->getPlottingViewMode());
if (mpPlottingPage->getPlottingViewMode().compare(Helper::subWindow) == 0) {
Expand Down Expand Up @@ -4410,9 +4416,13 @@ PlottingPage::PlottingPage(OptionsDialog *pOptionsDialog)
// auto scale
mpAutoScaleCheckBox = new QCheckBox(tr("Auto Scale"));
mpAutoScaleCheckBox->setToolTip(tr("Auto scale the plot to fit in view when variable is plotted."));
// prefix axes
mpPrefixAxesCheckbox = new QCheckBox(tr("Prefix Axes"));
mpPrefixAxesCheckbox->setToolTip(tr("Automatically pick the right prefix for axes values."));
// set general groupbox layout
QGridLayout *pGeneralGroupBoxLayout = new QGridLayout;
pGeneralGroupBoxLayout->addWidget(mpAutoScaleCheckBox, 0, 0);
pGeneralGroupBoxLayout->addWidget(mpPrefixAxesCheckbox, 1, 0);
mpGeneralGroupBox->setLayout(pGeneralGroupBoxLayout);
// Plotting View Mode
mpPlottingViewModeGroupBox = new QGroupBox(tr("Default Plotting View Mode"));
Expand Down
2 changes: 2 additions & 0 deletions OMEdit/OMEditLIB/Options/OptionsDialog.h
Expand Up @@ -800,6 +800,7 @@ class PlottingPage : public QWidget
void setPlottingViewMode(QString value);
QString getPlottingViewMode();
QCheckBox* getAutoScaleCheckBox() {return mpAutoScaleCheckBox;}
QCheckBox* getPrefixAxesCheckbox() {return mpPrefixAxesCheckbox;}
void setCurvePattern(int pattern);
int getCurvePattern();
void setCurveThickness(qreal thickness);
Expand All @@ -816,6 +817,7 @@ class PlottingPage : public QWidget
OptionsDialog *mpOptionsDialog;
QGroupBox *mpGeneralGroupBox;
QCheckBox *mpAutoScaleCheckBox;
QCheckBox *mpPrefixAxesCheckbox;
QGroupBox *mpPlottingViewModeGroupBox;
QRadioButton *mpPlottingTabbedViewRadioButton;
QRadioButton *mpPlottingSubWindowViewRadioButton;
Expand Down
9 changes: 7 additions & 2 deletions OMEdit/OMEditLIB/Plotting/PlotWindowContainer.cpp
Expand Up @@ -273,8 +273,9 @@ void PlotWindowContainer::addPlotWindow(bool maximized)
pPlotWindow->setTitle("");
pPlotWindow->setLegendPosition("top");
pPlotWindow->setAutoScale(OptionsDialog::instance()->getPlottingPage()->getAutoScaleCheckBox()->isChecked());
pPlotWindow->setPrefixAxes(OptionsDialog::instance()->getPlottingPage()->getPrefixAxesCheckbox()->isChecked());
pPlotWindow->setTimeUnit(MainWindow::instance()->getVariablesWidget()->getSimulationTimeComboBox()->currentText());
pPlotWindow->setXLabel(QString("time (%1)").arg(pPlotWindow->getTimeUnit()));
pPlotWindow->setXLabel(QString("time"));
pPlotWindow->installEventFilter(this);
QMdiSubWindow *pSubWindow = addSubWindow(pPlotWindow);
PlottingPage *pPlottingPage = OptionsDialog::instance()->getPlottingPage();
Expand Down Expand Up @@ -306,6 +307,7 @@ void PlotWindowContainer::addParametricPlotWindow()
pPlotWindow->setTitle("");
pPlotWindow->setLegendPosition("top");
pPlotWindow->setAutoScale(OptionsDialog::instance()->getPlottingPage()->getAutoScaleCheckBox()->isChecked());
pPlotWindow->setPrefixAxes(OptionsDialog::instance()->getPlottingPage()->getPrefixAxesCheckbox()->isChecked());
pPlotWindow->setTimeUnit(MainWindow::instance()->getVariablesWidget()->getSimulationTimeComboBox()->currentText());
pPlotWindow->installEventFilter(this);
QMdiSubWindow *pSubWindow = addSubWindow(pPlotWindow);
Expand Down Expand Up @@ -336,6 +338,7 @@ void PlotWindowContainer::addArrayPlotWindow(bool maximized)
pPlotWindow->setTitle("");
pPlotWindow->setLegendPosition("top");
pPlotWindow->setAutoScale(OptionsDialog::instance()->getPlottingPage()->getAutoScaleCheckBox()->isChecked());
pPlotWindow->setPrefixAxes(OptionsDialog::instance()->getPlottingPage()->getPrefixAxesCheckbox()->isChecked());
QComboBox* unitComboBox = MainWindow::instance()->getVariablesWidget()->getSimulationTimeComboBox();
if (unitComboBox->currentText() == ""){
int currentIndex = unitComboBox->findText("s", Qt::MatchExactly);
Expand Down Expand Up @@ -378,8 +381,9 @@ PlotWindow* PlotWindowContainer::addInteractivePlotWindow(bool maximized, QStrin
pPlotWindow->setTitle("");
pPlotWindow->setLegendPosition("top");
pPlotWindow->setAutoScale(OptionsDialog::instance()->getPlottingPage()->getAutoScaleCheckBox()->isChecked());
pPlotWindow->setPrefixAxes(OptionsDialog::instance()->getPlottingPage()->getPrefixAxesCheckbox()->isChecked());
pPlotWindow->setTimeUnit(MainWindow::instance()->getVariablesWidget()->getSimulationTimeComboBox()->currentText());
pPlotWindow->setXLabel(QString("time (%1)").arg(pPlotWindow->getTimeUnit()));
pPlotWindow->setXLabel(QString("time"));
pPlotWindow->installEventFilter(this);
QMdiSubWindow *pSubWindow = addSubWindow(pPlotWindow);
PlottingPage *pPlottingPage = OptionsDialog::instance()->getPlottingPage();
Expand Down Expand Up @@ -414,6 +418,7 @@ void PlotWindowContainer::addArrayParametricPlotWindow()
pPlotWindow->setTitle("");
pPlotWindow->setLegendPosition("top");
pPlotWindow->setAutoScale(OptionsDialog::instance()->getPlottingPage()->getAutoScaleCheckBox()->isChecked());
pPlotWindow->setPrefixAxes(OptionsDialog::instance()->getPlottingPage()->getPrefixAxesCheckbox()->isChecked());
QComboBox* unitComboBox = MainWindow::instance()->getVariablesWidget()->getSimulationTimeComboBox();
if (unitComboBox->currentText() == ""){
int currentIndex = unitComboBox->findText("s", Qt::MatchExactly);
Expand Down
26 changes: 1 addition & 25 deletions OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp
Expand Up @@ -2112,29 +2112,6 @@ void VariablesWidget::plotVariables(const QModelIndex &index, qreal curveThickne
}
}
}
// Set the plot labels if there is only on parametric plot curve.
if (pPlotWindow->getPlot()->getPlotCurvesList().size() == 1) {
PlotCurve *pLastPlotCurve = pPlotWindow->getPlot()->getPlotCurvesList().last();
// x label
QString xVariable = pLastPlotCurve->getXVariable();
QString xUnit = pLastPlotCurve->getXDisplayUnit();
if (xUnit.isEmpty()) {
pPlotWindow->setXLabel(xVariable);
} else {
pPlotWindow->setXLabel(xVariable + " (" + xUnit + ")");
}
// y label
QString yVariable = pLastPlotCurve->getYVariable();
QString yUnit = pLastPlotCurve->getYDisplayUnit();
if (yUnit.isEmpty()) {
pPlotWindow->setYLabel(yVariable);
} else {
pPlotWindow->setYLabel(yVariable + " (" + yUnit + ")");
}
} else {
pPlotWindow->setXLabel("");
pPlotWindow->setYLabel("");
}
} else { // if plottype is INTERACTIVE then
VariablesTreeItem *pVariablesTreeRootItem = pVariablesTreeItem;
if (!pVariablesTreeItem->isRootItem()) {
Expand Down Expand Up @@ -2481,15 +2458,14 @@ void VariablesWidget::timeUnitChanged(QString unit)
} else if (pPlotWindow->getPlotType() == PlotWindow::PLOT ||
pPlotWindow->getPlotType() == PlotWindow::PLOTINTERACTIVE) {
OMCInterface::convertUnits_res convertUnit = MainWindow::instance()->getOMCProxy()->convertUnits(pPlotWindow->getTimeUnit(), unit);
pPlotWindow->setTimeUnit(unit);
if (convertUnit.unitsCompatible) {
foreach (PlotCurve *pPlotCurve, pPlotWindow->getPlot()->getPlotCurvesList()) {
for (int i = 0 ; i < pPlotCurve->mXAxisVector.size() ; i++) {
pPlotCurve->updateXAxisValue(i, Utilities::convertUnit(pPlotCurve->mXAxisVector.at(i), convertUnit.offset, convertUnit.scaleFactor));
}
pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
}
pPlotWindow->setXLabel(QString("time (%1)").arg(unit));
pPlotWindow->setTimeUnit(unit);
pPlotWindow->getPlot()->replot();
}
}
Expand Down
8 changes: 7 additions & 1 deletion OMPlot/OMPlot/OMPlotGUI/OMPlot.h
Expand Up @@ -40,6 +40,7 @@
#include "PlotZoomer.h"
#include "PlotPanner.h"
#include "PlotPicker.h"
#include "ScaleDraw.h"
#include "PlotCurve.h"

namespace OMPlot
Expand All @@ -50,6 +51,7 @@ class PlotGrid;
class PlotZoomer;
class PlotPanner;
class PlotPicker;
class ScaleDraw;
class PlotCurve;

class Plot : public QwtPlot
Expand All @@ -59,6 +61,8 @@ class Plot : public QwtPlot
PlotWindow *mpParentPlotWindow;
Legend *mpLegend;
PlotGrid *mpPlotGrid;
ScaleDraw *mpXScaleDraw;
ScaleDraw *mpYScaleDraw;
PlotZoomer *mpPlotZoomer;
PlotPanner *mpPlotPanner;
PlotPicker *mpPlotPicker;
Expand All @@ -72,8 +76,10 @@ class Plot : public QwtPlot
PlotWindow* getParentPlotWindow();
void setLegend(Legend *pLegend);
Legend* getLegend();
QwtPlotPicker* getPlotPicker();
PlotPicker *getPlotPicker();
PlotGrid* getPlotGrid();
ScaleDraw *getXScaleDraw() const {return mpXScaleDraw;}
ScaleDraw *getYScaleDraw() const {return mpYScaleDraw;}
PlotZoomer* getPlotZoomer();
PlotPanner* getPlotPanner();
QList<PlotCurve*> getPlotCurvesList();
Expand Down
56 changes: 44 additions & 12 deletions OMPlot/OMPlot/OMPlotGUI/Plot.cpp
Expand Up @@ -32,7 +32,6 @@
*/

#include "PlotWindow.h"
#include "ScaleDraw.h"
#include "qwt_plot_canvas.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_widget.h"
Expand All @@ -53,6 +52,10 @@ Plot::Plot(PlotWindow *pParent)
insertLegend(mpLegend, QwtPlot::TopLegend);
// create an instance of grid
mpPlotGrid = new PlotGrid(this);
mpXScaleDraw = new ScaleDraw(this);
setAxisScaleDraw(QwtPlot::xBottom, mpXScaleDraw);
mpYScaleDraw = new ScaleDraw(this);
setAxisScaleDraw(QwtPlot::yLeft, mpYScaleDraw);
// create an instance of zoomer
mpPlotZoomer = new PlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft, canvas());
// create an instance of panner
Expand All @@ -66,8 +69,6 @@ Plot::Plot(PlotWindow *pParent)
pPlotCanvas->setFrameStyle(QFrame::NoFrame); /* Ticket #2679 point 6. Remove the default frame from the canvas. */
setCanvasBackground(Qt::white);
setContentsMargins(10, 10, 10, 10);
setAxisScaleDraw(QwtPlot::yLeft, new ScaleDraw);
setAxisScaleDraw(QwtPlot::xBottom, new ScaleDraw);
#if QWT_VERSION >= 0x060000
/* Ticket #2679 point 2. */
for (int i = 0; i < QwtPlot::axisCnt; i++) {
Expand All @@ -78,15 +79,16 @@ Plot::Plot(PlotWindow *pParent)
}
plotLayout()->setAlignCanvasToScales(true);
#endif
// Use monospaced font for better readability.
QFont monospaceFont("Monospace");
monospaceFont.setStyleHint(QFont::TypeWriter);
// set the bottom axis title font size small.
QwtText bottomTitle = axisTitle(QwtPlot::xBottom);
QFont font = bottomTitle.font();
bottomTitle.setFont(QFont(font.family(), 11));
bottomTitle.setFont(QFont(monospaceFont.family(), 11));
setAxisTitle(QwtPlot::xBottom, bottomTitle);
// set the left axis title font size small.
QwtText leftTitle = axisTitle(QwtPlot::yLeft);
font = leftTitle.font();
leftTitle.setFont(QFont(font.family(), 11));
leftTitle.setFont(QFont(monospaceFont.family(), 11));
setAxisTitle(QwtPlot::yLeft, leftTitle);
// fill colors list
fillColorsList();
Expand Down Expand Up @@ -129,7 +131,7 @@ Legend* Plot::getLegend()
return mpLegend;
}

QwtPlotPicker* Plot::getPlotPicker()
PlotPicker* Plot::getPlotPicker()
{
return mpPlotPicker;
}
Expand Down Expand Up @@ -223,16 +225,46 @@ void Plot::setFontSizes(double titleFontSize, double verticalAxisTitleFontSize,
// just overloaded this function to get colors for curves.
void Plot::replot()
{
for (int i = 0 ; i < mPlotCurvesList.length() ; i++)
{
for (int i = 0 ; i < mPlotCurvesList.length() ; i++) {
// if user has set the custom color for the curve then dont get automatic color for it
if (!mPlotCurvesList[i]->hasCustomColor())
{
if (!mPlotCurvesList[i]->hasCustomColor()) {
QPen pen = mPlotCurvesList[i]->pen();
pen.setColor(getUniqueColor(i, mPlotCurvesList.length()));
mPlotCurvesList[i]->setPen(pen);
}
}

if (mpParentPlotWindow->getXCustomLabel().isEmpty()) {
QString timeUnit = mpParentPlotWindow->getTimeUnit();
if (mpParentPlotWindow->getPlotType() == PlotWindow::PLOT
|| mpParentPlotWindow->getPlotType() == PlotWindow::PLOTALL
|| mpParentPlotWindow->getPlotType() == PlotWindow::PLOTINTERACTIVE
|| mpParentPlotWindow->getPlotType() == PlotWindow::PLOTARRAY) {
if (mpXScaleDraw->getAxesPrefix().isEmpty()) {
setAxisTitle(QwtPlot::xBottom, QString("%1 (%2)").arg(mpParentPlotWindow->getXLabel(), timeUnit));
} else {
setAxisTitle(QwtPlot::xBottom, QString("%1 (%2%3)").arg(mpParentPlotWindow->getXLabel(), mpXScaleDraw->getAxesPrefix(), timeUnit));
}
} else {
if (mpXScaleDraw->getAxesPrefix().isEmpty()) {
setAxisTitle(QwtPlot::xBottom, "");
} else {
setAxisTitle(QwtPlot::xBottom, QString("(%1)").arg(mpXScaleDraw->getAxesPrefix()));
}
}
} else {
setAxisTitle(QwtPlot::xBottom, mpParentPlotWindow->getXCustomLabel());
}

if (mpParentPlotWindow->getYCustomLabel().isEmpty()) {
if (mpYScaleDraw->getAxesPrefix().isEmpty()) {
setAxisTitle(QwtPlot::yLeft, "");
} else {
setAxisTitle(QwtPlot::yLeft, QString("(%1)").arg(mpYScaleDraw->getAxesPrefix()));
}
} else {
setAxisTitle(QwtPlot::yLeft, mpParentPlotWindow->getYCustomLabel());
}

QwtPlot::replot();
}

0 comments on commit 07fe8a2

Please sign in to comment.