Adjust auto plot settings

* Adjust the max value for summary curves to get more space on top of plot
* Compute axis range before computing auto plot settings
* Use axis object name as key when computing aggregated min/max
* Guard infinite recursion for enableAutoValue()
This commit is contained in:
Magne Sjaastad
2022-09-13 17:45:41 +02:00
committed by GitHub
parent 58852781c3
commit 22cd06b4c7
5 changed files with 121 additions and 83 deletions
@@ -455,6 +455,8 @@ void RimSummaryMultiPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
{ {
setAutoValueStates(); setAutoValueStates();
syncAxisRanges(); syncAxisRanges();
analyzePlotsAndAdjustAppearanceSettings();
zoomAll();
} }
else if ( changedField == &m_hidePlotsWithValuesBelow ) else if ( changedField == &m_hidePlotsWithValuesBelow )
{ {
@@ -493,7 +495,7 @@ void RimSummaryMultiPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
else if ( changedField == &m_autoAdjustAppearance ) else if ( changedField == &m_autoAdjustAppearance )
{ {
setAutoValueStates(); setAutoValueStates();
checkAndApplyAutoAppearance(); analyzePlotsAndAdjustAppearanceSettings();
} }
else else
{ {
@@ -723,7 +725,7 @@ void RimSummaryMultiPlot::onLoadDataAndUpdate()
RimMultiPlot::onLoadDataAndUpdate(); RimMultiPlot::onLoadDataAndUpdate();
updatePlotWindowTitle(); updatePlotWindowTitle();
checkAndApplyAutoAppearance(); analyzePlotsAndAdjustAppearanceSettings();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -811,18 +813,6 @@ void RimSummaryMultiPlot::setDefaultRangeAggregationSteppingDimension()
setAutoValueStates(); setAutoValueStates();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryMultiPlot::checkAndApplyAutoAppearance()
{
if ( m_autoAdjustAppearance )
{
analyzePlotsAndAdjustAppearanceSettings();
syncAxisRanges();
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -862,16 +852,15 @@ void RimSummaryMultiPlot::syncAxisRanges()
double maxVal = axis->visibleRangeMax(); double maxVal = axis->visibleRangeMax();
if ( axis->isAxisInverted() ) std::swap( minVal, maxVal ); if ( axis->isAxisInverted() ) std::swap( minVal, maxVal );
auto axisTitleText = axis->axisTitleText(); auto key = axis->objectName();
if ( axisRanges.count( axisTitleText ) == 0 ) if ( axisRanges.count( key ) == 0 )
{ {
axisRanges[axisTitleText] = std::make_pair( minVal, maxVal ); axisRanges[key] = std::make_pair( minVal, maxVal );
} }
else else
{ {
auto& [currentMin, currentMax] = axisRanges[axisTitleText]; auto& [currentMin, currentMax] = axisRanges[key];
axisRanges[axisTitleText] = axisRanges[key] = std::make_pair( std::min( currentMin, minVal ), std::max( currentMax, maxVal ) );
std::make_pair( std::min( currentMin, minVal ), std::max( currentMax, maxVal ) );
} }
} }
} }
@@ -881,9 +870,10 @@ void RimSummaryMultiPlot::syncAxisRanges()
{ {
for ( auto axis : plot->plotYAxes() ) for ( auto axis : plot->plotYAxes() )
{ {
auto [minVal, maxVal] = axisRanges[axis->axisTitleText()]; auto [minVal, maxVal] = axisRanges[axis->objectName()];
if ( axis->isAxisInverted() ) std::swap( minVal, maxVal ); if ( axis->isAxisInverted() ) std::swap( minVal, maxVal );
axis->setAutoZoom( false ); axis->setAutoZoom( false );
axis->setAutoValueVisibleRangeMin( minVal ); axis->setAutoValueVisibleRangeMin( minVal );
axis->setAutoValueVisibleRangeMax( maxVal ); axis->setAutoValueVisibleRangeMax( maxVal );
} }
@@ -1122,16 +1112,10 @@ void RimSummaryMultiPlot::computeAggregatedAxisRange()
if ( axis->isAxisInverted() ) std::swap( minVal, maxVal ); if ( axis->isAxisInverted() ) std::swap( minVal, maxVal );
if ( !axis->isLogarithmicScaleEnabled() ) auto [adjustedMinVal, adjustedMaxVal] = adjustedMinMax( axis, minVal, maxVal );
{
int maxMajorTickIntervalCount = 8;
double stepSize = 0.0;
QwtLinearScaleEngine scaleEngine;
scaleEngine.autoScale( maxMajorTickIntervalCount, minVal, maxVal, stepSize );
}
axis->setAutoValueVisibleRangeMin( minVal ); axis->setAutoValueVisibleRangeMin( adjustedMinVal );
axis->setAutoValueVisibleRangeMax( maxVal ); axis->setAutoValueVisibleRangeMax( adjustedMaxVal );
} }
} }
@@ -1228,57 +1212,75 @@ void RimSummaryMultiPlot::duplicate()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimSummaryMultiPlot::analyzePlotsAndAdjustAppearanceSettings() void RimSummaryMultiPlot::analyzePlotsAndAdjustAppearanceSettings()
{ {
RiaSummaryAddressAnalyzer analyzer; if ( m_autoAdjustAppearance )
for ( auto p : summaryPlots() )
{ {
auto addresses = RimSummaryAddressModifier::createEclipseSummaryAddress( p ); // Required to sync axis ranges before computing the auto scale
analyzer.appendAddresses( addresses ); syncAxisRanges();
}
bool hasOnlyOneQuantity = analyzer.isSingleQuantityIgnoreHistory(); RiaSummaryAddressAnalyzer analyzer;
for ( auto p : summaryPlots() ) for ( auto p : summaryPlots() )
{
auto timeAxisProp = p->timeAxisProperties();
if ( columnCount() < 3 )
timeAxisProp->setAutoValueForMajorTickmarkCount( RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_DEFAULT );
else
timeAxisProp->setAutoValueForMajorTickmarkCount( RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_FEW );
for ( RimPlotAxisPropertiesInterface* axisInterface : p->plotYAxes() )
{ {
auto axisProp = dynamic_cast<RimPlotAxisProperties*>( axisInterface ); auto addresses = RimSummaryAddressModifier::createEclipseSummaryAddress( p );
analyzer.appendAddresses( addresses );
}
if ( !axisProp ) continue; bool canShowOneAxisTitlePerRow = analyzer.isSingleQuantityIgnoreHistory() &&
( m_axisRangeAggregation() != AxisRangeAggregation::NONE );
if ( rowsPerPage() == 1 ) for ( auto p : summaryPlots() )
axisProp->setAutoValueForMajorTickmarkCount( {
RimPlotAxisPropertiesInterface::LegendTickmarkCount::TICKMARK_DEFAULT ); auto timeAxisProp = p->timeAxisProperties();
else
axisProp->setAutoValueForMajorTickmarkCount(
RimPlotAxisPropertiesInterface::LegendTickmarkCount::TICKMARK_FEW );
axisProp->computeAndSetAutoValueForScaleFactor(); auto tickMarkCount = ( columnCount() < 3 ) ? RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_DEFAULT
: RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_FEW;
if ( hasOnlyOneQuantity ) timeAxisProp->setAutoValueForMajorTickmarkCount( tickMarkCount );
for ( auto* axisProp : p->plotYAxes() )
{ {
auto [row, col] = gridLayoutInfoForSubPlot( p ); if ( !axisProp ) continue;
if ( col == 0 )
auto tickMarkCount = ( rowsPerPage() == 1 ) ? RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_DEFAULT
: RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_FEW;
axisProp->setAutoValueForMajorTickmarkCount( tickMarkCount );
axisProp->computeAndSetAutoValueForScaleFactor();
if ( canShowOneAxisTitlePerRow )
{
auto [row, col] = gridLayoutInfoForSubPlot( p );
bool isFirstColumn = ( col == 0 );
axisProp->setShowUnitText( isFirstColumn );
axisProp->setShowDescription( isFirstColumn );
}
else
{ {
axisProp->setShowUnitText( true ); axisProp->setShowUnitText( true );
axisProp->setShowDescription( true ); axisProp->setShowDescription( true );
} }
else
{
axisProp->setShowUnitText( false );
axisProp->setShowDescription( false );
}
} }
}
p->updateAxes(); p->updateAxes();
}
}
else
{
for ( auto p : summaryPlots() )
{
for ( auto* axisProp : p->plotYAxes() )
{
if ( !axisProp ) continue;
axisProp->computeAndSetAutoValueForScaleFactor();
axisProp->setShowUnitText( true );
axisProp->setShowDescription( true );
}
p->updateAxes();
}
} }
} }
@@ -1383,6 +1385,31 @@ void RimSummaryMultiPlot::updateReadOnlyState()
m_axisRangeAggregation.uiCapability()->setUiReadOnly( m_linkSubPlotAxes() ); m_axisRangeAggregation.uiCapability()->setUiReadOnly( m_linkSubPlotAxes() );
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RimSummaryMultiPlot::adjustedMinMax( const RimPlotAxisProperties* axis, double min, double max ) const
{
if ( !axis->isLogarithmicScaleEnabled() )
{
int maxMajorTickIntervalCount = axis->tickmarkCountFromEnum( axis->majorTickmarkCount() );
double stepSize = 0.0;
QwtLinearScaleEngine scaleEngine;
// Do not adjust minimum value, as we usually want to keep zero unchanged
double adjustedMin = min;
// Adjust the max value to get some space between the top of the plot and the top of the curve
double adjustedMax = max * 1.05;
scaleEngine.autoScale( maxMajorTickIntervalCount, adjustedMin, adjustedMax, stepSize );
return { adjustedMin, adjustedMax };
}
return { min, max };
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -34,6 +34,7 @@ class RimSummaryPlot;
class RimSummaryPlotSourceStepping; class RimSummaryPlotSourceStepping;
class RimSummaryPlotNameHelper; class RimSummaryPlotNameHelper;
class RimSummaryNameHelper; class RimSummaryNameHelper;
class RimPlotAxisProperties;
//================================================================================================== //==================================================================================================
/// ///
@@ -104,7 +105,7 @@ public:
void zoomAll() override; void zoomAll() override;
void setDefaultRangeAggregationSteppingDimension(); void setDefaultRangeAggregationSteppingDimension();
void checkAndApplyAutoAppearance(); void analyzePlotsAndAdjustAppearanceSettings();
void keepVisiblePageAfterUpdate( bool keepPage ); void keepVisiblePageAfterUpdate( bool keepPage );
@@ -144,14 +145,14 @@ private:
void appendSubPlotByStepping( int direction ); void appendSubPlotByStepping( int direction );
void appendCurveByStepping( int direction ); void appendCurveByStepping( int direction );
void analyzePlotsAndAdjustAppearanceSettings();
void onSubPlotChanged( const caf::SignalEmitter* emitter ); void onSubPlotChanged( const caf::SignalEmitter* emitter );
void onSubPlotZoomed( const caf::SignalEmitter* emitter ); void onSubPlotZoomed( const caf::SignalEmitter* emitter );
void onSubPlotAxisChanged( const caf::SignalEmitter* emitter, RimSummaryPlot* summaryPlot ); void onSubPlotAxisChanged( const caf::SignalEmitter* emitter, RimSummaryPlot* summaryPlot );
void updateReadOnlyState(); void updateReadOnlyState();
std::pair<double, double> adjustedMinMax( const RimPlotAxisProperties* axis, double min, double max ) const;
private: private:
caf::PdmField<bool> m_autoPlotTitle; caf::PdmField<bool> m_autoPlotTitle;
caf::PdmField<bool> m_autoSubPlotTitle; caf::PdmField<bool> m_autoSubPlotTitle;
@@ -508,7 +508,7 @@ void RiuMultiPlotBook::performUpdate( RiaDefines::MultiPlotPageUpdateType whatTo
updateGeometry(); updateGeometry();
RimSummaryMultiPlot* multiPlot = dynamic_cast<RimSummaryMultiPlot*>( m_plotDefinition.p() ); RimSummaryMultiPlot* multiPlot = dynamic_cast<RimSummaryMultiPlot*>( m_plotDefinition.p() );
if ( multiPlot ) multiPlot->checkAndApplyAutoAppearance(); if ( multiPlot ) multiPlot->analyzePlotsAndAdjustAppearanceSettings();
// use a timer to trigger a viewer page change, if needed // use a timer to trigger a viewer page change, if needed
if ( m_goToPageAfterUpdate ) if ( m_goToPageAfterUpdate )
@@ -140,11 +140,7 @@ void PdmUiFieldHandle::setAutoValue( const QVariant& autoValue, bool notifyField
{ {
m_autoValue = autoValue; m_autoValue = autoValue;
if ( m_useAutoValue && m_autoValue.isValid() ) applyAutoValueAndUpdateEditors( notifyFieldChanged );
{
setValueFromUiEditor( m_autoValue, notifyFieldChanged );
updateConnectedEditors();
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -158,15 +154,11 @@ QVariant PdmUiFieldHandle::autoValue() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void PdmUiFieldHandle::enableAutoValue( bool enable ) void PdmUiFieldHandle::enableAutoValue( bool enable, bool notifyFieldChanged )
{ {
m_useAutoValue = enable; m_useAutoValue = enable;
if ( m_useAutoValue && m_autoValue.isValid() ) applyAutoValueAndUpdateEditors( notifyFieldChanged );
{
setValueFromUiEditor( m_autoValue, true );
updateConnectedEditors();
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -228,7 +220,11 @@ void PdmUiFieldHandle::setAttributes( const std::vector<std::pair<QString, QStri
{ {
if ( valueString == "TRUE" ) if ( valueString == "TRUE" )
{ {
enableAutoValue( true ); // If notifyFieldChanged equals true, recursion will happen. Triggered by
// RimSummaryPlot::copyMatchingAxisPropertiesFromOther(), where data from one object is copied and set
// in another object using readObjectFromXmlString()
bool notifyFieldChanged = false;
enableAutoValue( true, notifyFieldChanged );
} }
} }
else if ( key == "autoValueSupported" ) else if ( key == "autoValueSupported" )
@@ -257,6 +253,18 @@ bool PdmUiFieldHandle::isQVariantDataEqual( const QVariant& oldUiBasedQVariant,
return false; return false;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiFieldHandle::applyAutoValueAndUpdateEditors( bool notifyFieldChanged )
{
if ( m_useAutoValue && m_autoValue.isValid() )
{
setValueFromUiEditor( m_autoValue, notifyFieldChanged );
updateConnectedEditors();
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Implementation of uiCapability() defined in cafPdmFieldHandle.h /// Implementation of uiCapability() defined in cafPdmFieldHandle.h
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -30,7 +30,7 @@ public:
void enableAndSetAutoValue( const QVariant& autoValue ); void enableAndSetAutoValue( const QVariant& autoValue );
void setAutoValue( const QVariant& autoValue, bool notifyFieldChanged = true ); void setAutoValue( const QVariant& autoValue, bool notifyFieldChanged = true );
QVariant autoValue() const; QVariant autoValue() const;
void enableAutoValue( bool enable ); void enableAutoValue( bool enable, bool notifyFieldChanged = true );
bool isAutoValueEnabled() const; bool isAutoValueEnabled() const;
void enableAutoValueSupport( bool enable ); void enableAutoValueSupport( bool enable );
bool isAutoValueSupported() const; bool isAutoValueSupported() const;
@@ -46,6 +46,8 @@ private:
// custom types. // custom types.
virtual bool isQVariantDataEqual( const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant ) const; virtual bool isQVariantDataEqual( const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant ) const;
void applyAutoValueAndUpdateEditors( bool notifyFieldChanged );
private: private:
PdmFieldHandle* m_owner; PdmFieldHandle* m_owner;
bool m_isAutoAddingOptionFromValue; bool m_isAutoAddingOptionFromValue;