#5150 Improve wheel zoom with logarithmic axes

* Limit the amount to scroll at one time and set a fixed minimum
This commit is contained in:
Gaute Lindkvist 2019-11-30 12:08:42 +01:00
parent e03582ab4b
commit 631570f6a5
5 changed files with 70 additions and 6 deletions

View File

@ -859,6 +859,8 @@ void RimSummaryPlot::updateZoomForAxis( RiaDefines::PlotAxis plotAxis )
if ( yAxisProps->isAutoZoom() )
{
m_plotWidget->setAxisIsLogarithmic( yAxisProps->qwtPlotAxisType(), yAxisProps->isLogarithmicScaleEnabled );
if ( yAxisProps->isLogarithmicScaleEnabled )
{
std::vector<const QwtPlotCurve*> plotCurves;

View File

@ -17,10 +17,15 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQwtPlotWheelZoomer.h"
#include "cvfMath.h"
#include "qwt_plot.h"
#include "qwt_scale_div.h"
#include <QEvent>
#include <QWheelEvent>
#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;
}

View File

@ -17,9 +17,12 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "qwt_plot.h"
#include <QObject>
class QwtPlot;
#include <map>
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<QwtPlot::Axis, bool> m_axesAreLogarithmic;
};

View File

@ -112,9 +112,9 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot( RimPlotInterface* plotDefinition, QWidget*
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() ) );
@ -240,6 +240,14 @@ void RiuSummaryQwtPlot::setLegendVisible( bool visible )
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic )
{
if ( m_wheelZoomer ) m_wheelZoomer->setAxisIsLogarithmic( axis, logarithmic );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -29,6 +29,7 @@
class RimEnsembleCurveSet;
class RiuCvfOverlayItemWidget;
class RiuQwtPlotZoomer;
class RiuQwtPlotWheelZoomer;
//==================================================================================================
//
@ -58,6 +59,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;
@ -74,6 +77,7 @@ private:
std::map<caf::PdmPointer<RimEnsembleCurveSet>, QPointer<RiuCvfOverlayItemWidget>> m_ensembleLegendWidgets;
QPointer<RiuQwtPlotZoomer> m_zoomerLeft;
QPointer<RiuQwtPlotZoomer> m_zoomerRight;
QPointer<RiuQwtPlotZoomer> m_zoomerLeft;
QPointer<RiuQwtPlotZoomer> m_zoomerRight;
QPointer<RiuQwtPlotWheelZoomer> m_wheelZoomer;
};