From 4870071b8ea0547ad01cf18c928ee3faaeaeb8b7 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Sat, 30 Nov 2019 12:08:42 +0100 Subject: [PATCH] #5150 Improve wheel zoom with logarithmic axes * Limit the amount to scroll at one time and set a fixed minimum --- .../Summary/RimSummaryPlot.cpp | 2 + .../UserInterface/RiuQwtPlotWheelZoomer.cpp | 41 ++++++++++++++++++- .../UserInterface/RiuQwtPlotWheelZoomer.h | 13 +++++- .../UserInterface/RiuSummaryQwtPlot.cpp | 12 +++++- .../UserInterface/RiuSummaryQwtPlot.h | 8 +++- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index fd2144751a..8cc5346824 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -873,6 +873,8 @@ void RimSummaryPlot::updateZoomForAxis( RiaDefines::PlotAxis plotAxis ) if ( yAxisProps->isAutoZoom() ) { + m_plotWidget->setAxisIsLogarithmic( yAxisProps->qwtPlotAxisType(), yAxisProps->isLogarithmicScaleEnabled ); + if ( yAxisProps->isLogarithmicScaleEnabled ) { std::vector plotCurves; diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp index 57db90cdaf..17e9867a80 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp +++ b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp @@ -17,10 +17,15 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiuQwtPlotWheelZoomer.h" + +#include "cvfMath.h" + #include "qwt_plot.h" +#include "qwt_scale_div.h" #include #include +#define RIU_LOGARITHMIC_MINIMUM 1.0e-15 #define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1 #define RIU_SCROLLWHEEL_PANFACTOR 0.1 @@ -37,15 +42,41 @@ RiuQwtPlotWheelZoomer::RiuQwtPlotWheelZoomer( QwtPlot* plot ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void zoomOnAxis( QwtPlot* plot, QwtPlot::Axis axis, double zoomFactor, int eventPos ) +void RiuQwtPlotWheelZoomer::zoomOnAxis( QwtPlot* plot, QwtPlot::Axis axis, double zoomFactor, int eventPos ) { QwtScaleMap scaleMap = plot->canvasMap( axis ); double zoomCenter = scaleMap.invTransform( eventPos ); double newMin = zoomCenter - zoomFactor * ( zoomCenter - scaleMap.s1() ); double newMax = zoomCenter + zoomFactor * ( -zoomCenter + scaleMap.s2() ); + + // the QwtScaleDiv::interval yields the current axis range + // The following thus doesn't limit the zoom to the min/max data but + // Stops the zoom from changing too much in one step + QwtInterval axisRange = plot->axisScaleDiv( axis ).interval(); + if ( axisIsLogarithmic( axis ) ) + { + // Handle inverted axes as well by not assuming maxValue > minValue + double minValue = std::max( RIU_LOGARITHMIC_MINIMUM, + 0.1 * std::min( axisRange.minValue(), axisRange.maxValue() ) ); + double maxValue = std::max( RIU_LOGARITHMIC_MINIMUM, + 10.0 * std::max( axisRange.minValue(), axisRange.maxValue() ) ); + + newMin = cvf::Math::clamp( newMin, minValue, maxValue ); + newMax = cvf::Math::clamp( newMax, minValue, maxValue ); + } + plot->setAxisScale( axis, newMin, newMax ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuQwtPlotWheelZoomer::axisIsLogarithmic( QwtPlot::Axis axis ) const +{ + auto it = m_axesAreLogarithmic.find( axis ); + return it != m_axesAreLogarithmic.end() ? it->second : false; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -71,3 +102,11 @@ bool RiuQwtPlotWheelZoomer::eventFilter( QObject* watched, QEvent* event ) return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotWheelZoomer::setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic ) +{ + m_axesAreLogarithmic[axis] = logarithmic; +} diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h index 2b8af751b1..e589c0aae5 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h +++ b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h @@ -17,9 +17,12 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "qwt_plot.h" + #include -class QwtPlot; +#include + class QEvent; class RiuQwtPlotWheelZoomer : public QObject @@ -30,9 +33,17 @@ public: bool eventFilter( QObject* watched, QEvent* event ) override; + void setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic ); + signals: void zoomUpdated(); +private: + void zoomOnAxis( QwtPlot* plot, QwtPlot::Axis axis, double zoomFactor, int eventPos ); + bool axisIsLogarithmic( QwtPlot::Axis axis ) const; + private: QwtPlot* m_plot; + + std::map m_axesAreLogarithmic; }; diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index 0d0d299a16..6775330766 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -112,9 +112,9 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot( RimPlot* plotDefinition, QWidget* parent / QwtPlotPanner* panner = new QwtPlotPanner( canvas() ); panner->setMouseButton( Qt::MidButton ); - auto wheelZoomer = new RiuQwtPlotWheelZoomer( this ); + m_wheelZoomer = new RiuQwtPlotWheelZoomer( this ); - connect( wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) ); + connect( m_wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) ); connect( m_zoomerLeft, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) ); connect( m_zoomerRight, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) ); connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) ); @@ -245,6 +245,14 @@ void RiuSummaryQwtPlot::setLegendVisible( bool visible ) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuSummaryQwtPlot::setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic ) +{ + if ( m_wheelZoomer ) m_wheelZoomer->setAxisIsLogarithmic( axis, logarithmic ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index 8c8e313aaa..e243bc462e 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -29,6 +29,7 @@ class RimEnsembleCurveSet; class RiuCvfOverlayItemWidget; class RiuQwtPlotZoomer; +class RiuQwtPlotWheelZoomer; //================================================================================================== // @@ -59,6 +60,8 @@ public: void setLegendFontSize( int fontSize ); void setLegendVisible( bool visible ); + void setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic ); + protected: void keyPressEvent( QKeyEvent* ) override; void contextMenuEvent( QContextMenuEvent* ) override; @@ -75,6 +78,7 @@ private: std::map, QPointer> m_ensembleLegendWidgets; - QPointer m_zoomerLeft; - QPointer m_zoomerRight; + QPointer m_zoomerLeft; + QPointer m_zoomerRight; + QPointer m_wheelZoomer; };