diff --git a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp index 39834f77a8..01ec102940 100644 --- a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp +++ b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp @@ -19,20 +19,20 @@ #include "RiuRelativePermeabilityPlotPanel.h" #include "RiuRelativePermeabilityPlotUpdater.h" #include "RiuSummaryQwtPlot.h" -#include "RiuQwtPlotWheelZoomer.h" -#include "RiuQwtPlotZoomer.h" +#include "RiuLineSegmentQwtPlotCurve.h" #include "RigFlowDiagSolverInterface.h" #include "cvfBase.h" #include "cvfAssert.h" -//#include "cvfTrace.h" +#include "cvfTrace.h" #include "qwt_plot.h" #include "qwt_plot_curve.h" #include "qwt_legend.h" #include "qwt_symbol.h" #include "qwt_plot_marker.h" +#include "qwt_scale_engine.h" #include #include @@ -104,10 +104,12 @@ RiuRelativePermeabilityPlotPanel::RiuRelativePermeabilityPlotPanel(QDockWidget* groupBoxLayout->addWidget(checkButtonList[i]); } + m_logarithmicScaleKrAxisCheckBox = new QCheckBox("Logarithmic Scale\nKr Axis"); m_showUnscaledCheckBox = new QCheckBox("Show Unscaled"); QVBoxLayout* leftLayout = new QVBoxLayout; leftLayout->addWidget(groupBox); + leftLayout->addWidget(m_logarithmicScaleKrAxisCheckBox); leftLayout->addWidget(m_showUnscaledCheckBox); leftLayout->addStretch(1); @@ -119,7 +121,8 @@ RiuRelativePermeabilityPlotPanel::RiuRelativePermeabilityPlotPanel(QDockWidget* setLayout(mainLayout); connect(m_selectedCurvesButtonGroup, SIGNAL(buttonClicked(int)), SLOT(slotButtonInButtonGroupClicked(int))); - connect(m_showUnscaledCheckBox, SIGNAL(stateChanged(int)), SLOT(slotUnscaledCheckBoxStateChanged(int))); + connect(m_logarithmicScaleKrAxisCheckBox, SIGNAL(stateChanged(int)), SLOT(slotSomeCheckBoxStateChanged(int))); + connect(m_showUnscaledCheckBox, SIGNAL(stateChanged(int)), SLOT(slotSomeCheckBoxStateChanged(int))); plotUiSelectedCurves(); } @@ -183,7 +186,7 @@ void RiuRelativePermeabilityPlotPanel::clearPlot() m_sgas = HUGE_VAL; m_cellReferenceText.clear(); - plotCurvesInQwt(m_allCurvesArr, m_swat, m_sgas, m_cellReferenceText, m_qwtPlot, &m_myPlotMarkers); + plotCurvesInQwt(m_allCurvesArr, m_swat, m_sgas, m_cellReferenceText, false, m_qwtPlot, &m_myPlotMarkers); } //-------------------------------------------------------------------------------------------------- @@ -204,6 +207,8 @@ void RiuRelativePermeabilityPlotPanel::plotUiSelectedCurves() // Determine which curves to actually plot based on selection in GUI const RigFlowDiagSolverInterface::RelPermCurve::EpsMode epsModeToShow = m_showUnscaledCheckBox->isChecked() ? RigFlowDiagSolverInterface::RelPermCurve::EPS_OFF : RigFlowDiagSolverInterface::RelPermCurve::EPS_ON; + const bool useLogScale = m_logarithmicScaleKrAxisCheckBox->isChecked() ? true : false; + for (size_t i = 0; i < m_allCurvesArr.size(); i++) { const RigFlowDiagSolverInterface::RelPermCurve::Ident curveIdent = m_allCurvesArr[i].ident; @@ -217,13 +222,13 @@ void RiuRelativePermeabilityPlotPanel::plotUiSelectedCurves() } } - plotCurvesInQwt(selectedCurves, m_swat, m_sgas, m_cellReferenceText, m_qwtPlot, &m_myPlotMarkers); + plotCurvesInQwt(selectedCurves, m_swat, m_sgas, m_cellReferenceText, useLogScale, m_qwtPlot, &m_myPlotMarkers); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector& curveArr, double swat, double sgas, QString cellReferenceText, QwtPlot* plot, std::vector* myPlotMarkers) +void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector& curveArr, double swat, double sgas, QString cellReferenceText, bool logScaleLeftAxis, QwtPlot* plot, std::vector* myPlotMarkers) { plot->detachItems(QwtPlotItem::Rtti_PlotCurve); @@ -238,31 +243,48 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vectorclear(); + //ValueRange leftYAxisValueRange; bool shouldEableRightYAxis = false; for (size_t i = 0; i < curveArr.size(); i++) { const RigFlowDiagSolverInterface::RelPermCurve& curve = curveArr[i]; - QwtPlotCurve* qwtCurve = new QwtPlotCurve(curve.name.c_str()); + + // Which axis should this curve be plotted on + WhichYAxis plotOnWhichYAxis = LEFT_YAXIS; + if (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOW || curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOG) + { + plotOnWhichYAxis = RIGHT_YAXIS; + } + + //if (plotOnWhichYAxis == LEFT_YAXIS) + //{ + // leftYAxisValueRange.add(calcValueRange(curve.yVals, logScaleLeftAxis)); + //} + + + //QwtPlotCurve* qwtCurve = new QwtPlotCurve(curve.name.c_str()); + RiuLineSegmentQwtPlotCurve* qwtCurve = new RiuLineSegmentQwtPlotCurve(curve.name.c_str()); CVF_ASSERT(curve.xVals.size() == curve.yVals.size()); - qwtCurve->setSamples(curve.xVals.data(), curve.yVals.data(), static_cast(curve.xVals.size())); + //qwtCurve->setSamples(curve.xVals.data(), curve.yVals.data(), static_cast(curve.xVals.size())); + const bool includePositiveValuesOnly = (logScaleLeftAxis && plotOnWhichYAxis == LEFT_YAXIS); + qwtCurve->setSamplesFromXValuesAndYValues(curve.xVals, curve.yVals, includePositiveValuesOnly); qwtCurve->setTitle(curve.name.c_str()); qwtCurve->setStyle(QwtPlotCurve::Lines); - bool plotCurveOnRightAxis = false; Qt::PenStyle penStyle = Qt::SolidLine; QColor clr = Qt::magenta; switch (curve.ident) { case RigFlowDiagSolverInterface::RelPermCurve::KRW: clr = QColor(0, 0, 200); break; case RigFlowDiagSolverInterface::RelPermCurve::KROW: clr = QColor(0, 0, 200); break; - case RigFlowDiagSolverInterface::RelPermCurve::PCOW: clr = QColor(0, 130, 175); penStyle = Qt::DashLine; plotCurveOnRightAxis = true; break; + case RigFlowDiagSolverInterface::RelPermCurve::PCOW: clr = QColor(0, 130, 175); penStyle = Qt::DashLine; break; case RigFlowDiagSolverInterface::RelPermCurve::KRG: clr = QColor(200, 0, 0); break; case RigFlowDiagSolverInterface::RelPermCurve::KROG: clr = QColor(200, 0, 0); break; - case RigFlowDiagSolverInterface::RelPermCurve::PCOG: clr = QColor(225, 110, 0); penStyle = Qt::DashLine; plotCurveOnRightAxis = true; break; + case RigFlowDiagSolverInterface::RelPermCurve::PCOG: clr = QColor(225, 110, 0); penStyle = Qt::DashLine; break; } const QPen curvePen(clr, 1, penStyle); @@ -280,7 +302,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vectorsetRenderHint(QwtPlotItem::RenderAntialiased, true); - if (plotCurveOnRightAxis) + if (plotOnWhichYAxis == RIGHT_YAXIS) { qwtCurve->setYAxis(QwtPlot::yRight); shouldEableRightYAxis = true; @@ -290,13 +312,14 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector(plot->axisScaleEngine(QwtPlot::yLeft))) + { + plot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLogScaleEngine); + //plot->setAxisAutoScale(QwtPlot::yLeft, true); + } + + //if (leftYAxisValueRange.min <= leftYAxisValueRange.max) + //{ + // //plot->setAxisScale(QwtPlot::yLeft, leftYAxisValueRange.min, leftYAxisValueRange.max); + //} + } + else + { + if (!dynamic_cast(plot->axisScaleEngine(QwtPlot::yLeft))) + { + plot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); + //plot->setAxisAutoScale(QwtPlot::yLeft, true); + } + } + + QString titleStr = "Relative Permeability"; if (!cellReferenceText.isEmpty()) { @@ -391,7 +437,7 @@ void RiuRelativePermeabilityPlotPanel::addVerticalSaturationMarkerLine(double sa //-------------------------------------------------------------------------------------------------- /// Add a marker at the intersection of the passed curve and the constant saturation value //-------------------------------------------------------------------------------------------------- -void RiuRelativePermeabilityPlotPanel::addCurveConstSaturationIntersectionMarker(const RigFlowDiagSolverInterface::RelPermCurve& curve, double saturationValue, QColor markerColor, bool plotCurveOnRightAxis, QwtPlot* plot, std::vector* myPlotMarkers) +void RiuRelativePermeabilityPlotPanel::addCurveConstSaturationIntersectionMarker(const RigFlowDiagSolverInterface::RelPermCurve& curve, double saturationValue, QColor markerColor, WhichYAxis whichYAxis, QwtPlot* plot, std::vector* myPlotMarkers) { const double yVal = interpolatedCurveYValue(curve.xVals, curve.yVals, saturationValue); if (yVal != HUGE_VAL) @@ -406,7 +452,7 @@ void RiuRelativePermeabilityPlotPanel::addCurveConstSaturationIntersectionMarker pointMarker->setSymbol(symbol); pointMarker->attach(plot); - if (plotCurveOnRightAxis) + if (whichYAxis == RIGHT_YAXIS) { pointMarker->setYAxis(QwtPlot::yRight); } @@ -415,6 +461,37 @@ void RiuRelativePermeabilityPlotPanel::addCurveConstSaturationIntersectionMarker } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuRelativePermeabilityPlotPanel::ValueRange RiuRelativePermeabilityPlotPanel::calcValueRange(const std::vector& valueArr, bool includePositiveValuesOnly) +{ + ValueRange range; + + for (double v : valueArr) + { + if (v == HUGE_VAL) + { + continue; + } + if (includePositiveValuesOnly && v <= 0) + { + continue; + } + + if (v < range.min) + { + range.min = v; + } + if (v > range.max) + { + range.max = v; + } + } + + return range; +} + //-------------------------------------------------------------------------------------------------- /// Assumes that all the x-values are ordered in increasing order //-------------------------------------------------------------------------------------------------- @@ -450,7 +527,7 @@ double RiuRelativePermeabilityPlotPanel::interpolatedCurveYValue(const std::vect CVF_ASSERT(x1 > x0); const double t = (x1 - x0) > 0 ? (x - x0)/(x1 - x0) : 0; - const double y = y0 + t*(y1 - y0); + const double y = y0*(1.0 - t) + y1*t; return y; } @@ -467,8 +544,41 @@ void RiuRelativePermeabilityPlotPanel::slotButtonInButtonGroupClicked(int) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuRelativePermeabilityPlotPanel::slotUnscaledCheckBoxStateChanged(int) +void RiuRelativePermeabilityPlotPanel::slotSomeCheckBoxStateChanged(int) { plotUiSelectedCurves(); } + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuRelativePermeabilityPlotPanel::ValueRange::ValueRange() + : min(HUGE_VAL), + max(-HUGE_VAL) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuRelativePermeabilityPlotPanel::ValueRange::add(const ValueRange& range) +{ + if (range.max >= range.min) + { + if (range.max > max) + { + max = range.max; + } + if (range.min < min) + { + min = range.min; + } + } +} diff --git a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h index 4682aec0b7..13347fbe9c 100644 --- a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h +++ b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h @@ -51,17 +51,35 @@ public: RiuRelativePermeabilityPlotUpdater* plotUpdater(); private: - void plotUiSelectedCurves(); - static void setPlotDefaults(QwtPlot* plot); - static void plotCurvesInQwt(const std::vector& curveArr, double swat, double sgas, QString cellReferenceText, QwtPlot* plot, std::vector* myPlotMarkers); - static QString determineXAxisTitleFromCurveCollection(const std::vector& curveArr); - static void addVerticalSaturationMarkerLine(double saturationValue, QString label, QColor color, QwtPlot* plot, std::vector* myPlotMarkers); - static void addCurveConstSaturationIntersectionMarker(const RigFlowDiagSolverInterface::RelPermCurve& curve, double saturationValue, QColor markerColor, bool plotCurveOnRightAxis, QwtPlot* plot, std::vector* myPlotMarkers); - static double interpolatedCurveYValue(const std::vector& xVals, const std::vector& yVals, double x); + enum WhichYAxis + { + LEFT_YAXIS, + RIGHT_YAXIS + }; + + class ValueRange + { + public: + ValueRange(); + void add(const ValueRange& range); + + public: + double min; + double max; + }; + + void plotUiSelectedCurves(); + static void setPlotDefaults(QwtPlot* plot); + static void plotCurvesInQwt(const std::vector& curveArr, double swat, double sgas, QString cellReferenceText, bool logScaleLeftAxis, QwtPlot* plot, std::vector* myPlotMarkers); + static QString determineXAxisTitleFromCurveCollection(const std::vector& curveArr); + static void addVerticalSaturationMarkerLine(double saturationValue, QString label, QColor color, QwtPlot* plot, std::vector* myPlotMarkers); + static void addCurveConstSaturationIntersectionMarker(const RigFlowDiagSolverInterface::RelPermCurve& curve, double saturationValue, QColor markerColor, WhichYAxis whichYAxis, QwtPlot* plot, std::vector* myPlotMarkers); + static ValueRange calcValueRange(const std::vector& valueArr, bool includePositiveValuesOnly); + static double interpolatedCurveYValue(const std::vector& xVals, const std::vector& yVals, double x); private slots: void slotButtonInButtonGroupClicked(int); - void slotUnscaledCheckBoxStateChanged(int); + void slotSomeCheckBoxStateChanged(int); private: std::vector m_allCurvesArr; @@ -73,6 +91,7 @@ private: QButtonGroup* m_selectedCurvesButtonGroup; QCheckBox* m_showUnscaledCheckBox; + QCheckBox* m_logarithmicScaleKrAxisCheckBox; std::unique_ptr m_plotUpdater; };