Add support for summary cross plot curves in summary plots

This commit is contained in:
Magne Sjaastad
2023-09-20 09:48:03 +02:00
parent b87fa0bc74
commit 146412c600
44 changed files with 970 additions and 440 deletions

View File

@@ -697,7 +697,7 @@ QString RimGridTimeHistoryCurve::geometrySelectionText() const
//--------------------------------------------------------------------------------------------------
void RimGridTimeHistoryCurve::updateQwtPlotAxis()
{
if ( m_plotCurve ) updateAxisInPlot( yAxis() );
if ( m_plotCurve ) updateYAxisInPlot( yAxis() );
}
//--------------------------------------------------------------------------------------------------

View File

@@ -98,8 +98,8 @@ RimMainPlotCollection::RimMainPlotCollection()
CAF_PDM_InitFieldNoDefault( &m_correlationPlotCollection, "CorrelationPlotCollection", "Correlation Plots" );
m_correlationPlotCollection.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_summaryCrossPlotCollection, "SummaryCrossPlotCollection", "Summary Cross Plots" );
m_summaryCrossPlotCollection.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_summaryCrossPlotCollection_OBSOLETE, "SummaryCrossPlotCollection", "Summary Cross Plots" );
m_summaryCrossPlotCollection_OBSOLETE.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_summaryTableCollection, "SummaryTableCollection", "Summary Tables" );
m_summaryTableCollection.uiCapability()->setUiTreeHidden( true );
@@ -129,20 +129,20 @@ RimMainPlotCollection::RimMainPlotCollection()
m_ensembleFractureStatisticsPlotCollection.uiCapability()->setUiTreeHidden( true );
#endif
m_wellLogPlotCollection = new RimWellLogPlotCollection();
m_rftPlotCollection = new RimRftPlotCollection();
m_pltPlotCollection = new RimPltPlotCollection();
m_summaryMultiPlotCollection = new RimSummaryMultiPlotCollection();
m_summaryCrossPlotCollection = new RimSummaryCrossPlotCollection();
m_summaryTableCollection = new RimSummaryTableCollection();
m_flowPlotCollection = new RimFlowPlotCollection();
m_gridCrossPlotCollection = new RimGridCrossPlotCollection;
m_saturationPressurePlotCollection = new RimSaturationPressurePlotCollection;
m_multiPlotCollection = new RimMultiPlotCollection;
m_analysisPlotCollection = new RimAnalysisPlotCollection;
m_correlationPlotCollection = new RimCorrelationPlotCollection;
m_stimPlanModelPlotCollection = new RimStimPlanModelPlotCollection;
m_vfpPlotCollection = new RimVfpPlotCollection();
m_wellLogPlotCollection = new RimWellLogPlotCollection();
m_rftPlotCollection = new RimRftPlotCollection();
m_pltPlotCollection = new RimPltPlotCollection();
m_summaryMultiPlotCollection = new RimSummaryMultiPlotCollection();
m_summaryCrossPlotCollection_OBSOLETE = new RimSummaryCrossPlotCollection();
m_summaryTableCollection = new RimSummaryTableCollection();
m_flowPlotCollection = new RimFlowPlotCollection();
m_gridCrossPlotCollection = new RimGridCrossPlotCollection;
m_saturationPressurePlotCollection = new RimSaturationPressurePlotCollection;
m_multiPlotCollection = new RimMultiPlotCollection;
m_analysisPlotCollection = new RimAnalysisPlotCollection;
m_correlationPlotCollection = new RimCorrelationPlotCollection;
m_stimPlanModelPlotCollection = new RimStimPlanModelPlotCollection;
m_vfpPlotCollection = new RimVfpPlotCollection();
#ifdef USE_QTCHARTS
m_gridStatisticsPlotCollection = new RimGridStatisticsPlotCollection;
m_ensembleFractureStatisticsPlotCollection = new RimEnsembleFractureStatisticsPlotCollection;
@@ -242,7 +242,7 @@ RimSummaryMultiPlotCollection* RimMainPlotCollection::summaryMultiPlotCollection
//--------------------------------------------------------------------------------------------------
RimSummaryCrossPlotCollection* RimMainPlotCollection::summaryCrossPlotCollection() const
{
return m_summaryCrossPlotCollection();
return m_summaryCrossPlotCollection_OBSOLETE();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -112,7 +112,7 @@ private:
caf::PdmChildField<RimRftPlotCollection*> m_rftPlotCollection;
caf::PdmChildField<RimPltPlotCollection*> m_pltPlotCollection;
caf::PdmChildField<RimSummaryMultiPlotCollection*> m_summaryMultiPlotCollection;
caf::PdmChildField<RimSummaryCrossPlotCollection*> m_summaryCrossPlotCollection;
caf::PdmChildField<RimSummaryCrossPlotCollection*> m_summaryCrossPlotCollection_OBSOLETE;
caf::PdmChildField<RimSummaryTableCollection*> m_summaryTableCollection;
caf::PdmChildField<RimAnalysisPlotCollection*> m_analysisPlotCollection;
caf::PdmChildField<RimCorrelationPlotCollection*> m_correlationPlotCollection;

View File

@@ -145,12 +145,7 @@ void RimPlotAxisProperties::enableRangeSettings( bool enable )
//--------------------------------------------------------------------------------------------------
void RimPlotAxisProperties::setNameForUnusedAxis()
{
QString name = "Unused ";
if ( m_plotAxis() == RiaDefines::PlotAxis::PLOT_AXIS_LEFT )
name += "Left";
else if ( m_plotAxis() == RiaDefines::PlotAxis::PLOT_AXIS_RIGHT )
name += "Right";
QString name = "Unused " + m_plotAxis().text();
m_objectName = name;
}
@@ -184,18 +179,6 @@ QList<caf::PdmOptionItemInfo> RimPlotAxisProperties::calculateValueOptions( cons
{
options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() );
}
else if ( fieldNeedingOptions == &m_plotAxis )
{
std::vector<RiaDefines::PlotAxis> plotAxes = { RiaDefines::PlotAxis::PLOT_AXIS_LEFT, RiaDefines::PlotAxis::PLOT_AXIS_RIGHT };
for ( auto plotAxis : plotAxes )
{
auto plotAxisEnum = caf::AppEnum<RiaDefines::PlotAxis>( plotAxis );
QString uiText = plotAxisEnum.uiText();
options.push_back( caf::PdmOptionItemInfo( uiText, plotAxisEnum.value() ) );
}
}
return options;
}

View File

@@ -575,14 +575,6 @@ void RimPlotCurve::checkAndApplyDefaultFillColor()
// }
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimPlotCurve::isCrossPlotCurve() const
{
return firstAncestorOrThisOfType<RimSummaryCrossPlot>() != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -875,11 +867,19 @@ void RimPlotCurve::setSamplesFromXYErrorValues( const std::vector<double>& xVa
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotCurve::updateAxisInPlot( RiuPlotAxis plotAxis )
void RimPlotCurve::updateYAxisInPlot( RiuPlotAxis plotAxis )
{
if ( m_plotCurve ) m_plotCurve->setYAxis( plotAxis );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotCurve::updateXAxisInPlot( RiuPlotAxis plotAxis )
{
if ( m_plotCurve ) m_plotCurve->setXAxis( plotAxis );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -115,7 +115,6 @@ public:
void setErrorBarsVisible( bool isVisible );
virtual void updateCurveAppearance();
bool isCrossPlotCurve() const;
virtual void updateUiIconFromPlotSymbol();
virtual bool hasParentPlot() const;
@@ -186,7 +185,8 @@ protected:
virtual void clearErrorBars();
void checkAndApplyDefaultFillColor();
virtual void updateAxisInPlot( RiuPlotAxis plotAxis );
void updateYAxisInPlot( RiuPlotAxis plotAxis );
void updateXAxisInPlot( RiuPlotAxis plotAxis );
void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;

View File

@@ -197,7 +197,7 @@ void RimAsciiDataCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::updateQwtPlotAxis()
{
if ( m_plotCurve ) updateAxisInPlot( yAxis() );
if ( m_plotCurve ) updateYAxisInPlot( yAxis() );
}
//--------------------------------------------------------------------------------------------------

View File

@@ -424,6 +424,14 @@ RifEclipseSummaryAddress RimEnsembleCurveSet::summaryAddress() const
return m_yValuesSummaryAddress->address();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveAddress RimEnsembleCurveSet::curveAddress() const
{
return RiaSummaryCurveAddress( summaryAddress(), RifEclipseSummaryAddress::timeAddress() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -1403,7 +1411,7 @@ std::vector<RiaSummaryCurveDefinition> RimEnsembleCurveSet::curveDefinitions() c
std::vector<RiaSummaryCurveDefinition> curveDefs;
for ( auto dataEntry : m_curves() )
{
curveDefs.push_back( dataEntry->curveDefinitionY() );
curveDefs.push_back( dataEntry->curveDefinition() );
}
return curveDefs;
@@ -2147,12 +2155,9 @@ QString RimEnsembleCurveSet::createAutoName() const
{
auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
QString curveSetName =
m_summaryAddressNameTools->curveNameY( m_yValuesSummaryAddress->address(), plot->plotTitleHelper(), plot->plotTitleHelper() );
if ( curveSetName.isEmpty() )
{
curveSetName = m_summaryAddressNameTools->curveNameY( m_yValuesSummaryAddress->address(), nullptr, nullptr );
}
QString curveSetName = m_summaryAddressNameTools->curveName( RiaSummaryCurveAddress( m_yValuesSummaryAddress->address() ),
plot->plotTitleHelper(),
plot->plotTitleHelper() );
if ( curveSetName.isEmpty() )
{

View File

@@ -24,6 +24,7 @@
#include "RiaDateTimeDefines.h"
#include "RiaPlotDefines.h"
#include "RiaSummaryCurveAddress.h"
#include "RimEnsembleCurveSetColorManager.h"
#include "RimEnsembleCurveSetInterface.h"
@@ -112,6 +113,7 @@ public:
void setSummaryAddress( RifEclipseSummaryAddress address );
void setSummaryAddressAndStatisticsFlag( RifEclipseSummaryAddress address );
RifEclipseSummaryAddress summaryAddress() const;
RiaSummaryCurveAddress curveAddress() const;
std::vector<RimSummaryCurve*> curves() const;
int ensembleId() const;

View File

@@ -49,12 +49,12 @@ QString RimMultiSummaryPlotNameHelper::plotTitle() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimMultiSummaryPlotNameHelper::isPlotDisplayingSingleVectorName() const
bool RimMultiSummaryPlotNameHelper::isPlotDisplayingSingleCurve() const
{
int plotCountWithSingleQuantity = 0;
for ( auto nameHelper : m_nameHelpers )
{
if ( nameHelper->isPlotDisplayingSingleVectorName() ) plotCountWithSingleQuantity++;
if ( nameHelper->isPlotDisplayingSingleCurve() ) plotCountWithSingleQuantity++;
}
return plotCountWithSingleQuantity == 1;
@@ -160,7 +160,7 @@ std::string RimMultiSummaryPlotNameHelper::titleVectorName() const
{
for ( auto nameHelper : m_nameHelpers )
{
if ( nameHelper->isPlotDisplayingSingleVectorName() ) return nameHelper->titleVectorName();
if ( nameHelper->isPlotDisplayingSingleCurve() ) return nameHelper->titleVectorName();
}
return "";

View File

@@ -30,7 +30,7 @@ public:
QString plotTitle() const override;
bool isPlotDisplayingSingleVectorName() const override;
bool isPlotDisplayingSingleCurve() const override;
bool isWellNameInTitle() const override;
bool isGroupNameInTitle() const override;
bool isNetworkInTitle() const override;

View File

@@ -27,15 +27,7 @@ CAF_PDM_SOURCE_INIT( RimSummaryCrossPlot, "SummaryCrossPlot" );
///
//--------------------------------------------------------------------------------------------------
RimSummaryCrossPlot::RimSummaryCrossPlot()
: RimSummaryPlot( true )
: RimSummaryPlot()
{
CAF_PDM_InitObject( "Summary Cross Plot", ":/SummaryXPlotLight16x16.png" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryPlotSourceStepping* RimSummaryCrossPlot::sourceSteppingObjectForKeyEventHandling() const
{
return summaryCurveCollection()->sourceSteppingObject( RimSummaryDataSourceStepping::Axis::UNION_X_Y_AXIS );
}

View File

@@ -30,6 +30,4 @@ class RimSummaryCrossPlot : public RimSummaryPlot
public:
RimSummaryCrossPlot();
RimSummaryPlotSourceStepping* sourceSteppingObjectForKeyEventHandling() const override;
};

View File

@@ -27,6 +27,7 @@
#include "RiaQDateTimeTools.h"
#include "RiaResultNames.h"
#include "RiaSummaryCurveDefinition.h"
#include "RiaSummaryDefines.h"
#include "RiaSummaryTools.h"
#include "RimEclipseResultCase.h"
@@ -52,6 +53,7 @@
#include "RiuQwtPlotCurve.h"
#include "RiuSummaryVectorSelectionDialog.h"
#include "cafAssert.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiPushButtonEditor.h"
@@ -86,9 +88,15 @@ RimSummaryCurve::RimSummaryCurve()
m_yValuesSummaryAddress = new RimSummaryAddress;
CAF_PDM_InitFieldNoDefault( &m_resampling, "Resampling", "Resampling" );
CAF_PDM_InitFieldNoDefault( &m_yValuesResampling, "Resampling", "Resampling" );
// X Values
CAF_PDM_InitField( &m_xAxisType,
"HorizontalAxisType",
caf::AppEnum<RiaDefines::HorizontalAxisType>( RiaDefines::HorizontalAxisType::TIME ),
"Axis Type" );
CAF_PDM_InitFieldNoDefault( &m_xValuesSummaryCase, "SummaryCaseX", "Case" );
m_xValuesSummaryCase.uiCapability()->setUiTreeChildrenHidden( true );
m_xValuesSummaryCase.uiCapability()->setAutoAddingOptionFromValue( false );
@@ -116,7 +124,8 @@ RimSummaryCurve::RimSummaryCurve()
CAF_PDM_InitFieldNoDefault( &m_plotAxis_OBSOLETE, "PlotAxis", "Axis" );
m_plotAxis_OBSOLETE.xmlCapability()->setIOWritable( false );
CAF_PDM_InitFieldNoDefault( &m_plotAxisProperties, "Axis", "Axis" );
CAF_PDM_InitFieldNoDefault( &m_yPlotAxisProperties, "Axis", "Axis" );
CAF_PDM_InitFieldNoDefault( &m_xPlotAxisProperties, "XAxis", "Axis" );
CAF_PDM_InitFieldNoDefault( &m_curveNameConfig, "SummaryCurveNameConfig", "SummaryCurveNameConfig" );
m_curveNameConfig.uiCapability()->setUiTreeHidden( true );
@@ -143,9 +152,24 @@ RimSummaryCurve::~RimSummaryCurve()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveDefinition RimSummaryCurve::curveDefinitionY() const
RiaSummaryCurveDefinition RimSummaryCurve::curveDefinition() const
{
return RiaSummaryCurveDefinition( summaryCaseY(), summaryAddressY(), isEnsembleCurve() );
RiaSummaryCurveDefinition curveDefinition( summaryCaseY(), summaryAddressY(), isEnsembleCurve() );
if ( m_xAxisType() == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR )
{
curveDefinition.setSummaryCaseX( summaryCaseX() );
curveDefinition.setSummaryAddressX( summaryAddressX() );
}
return curveDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveAddress RimSummaryCurve::curveAddress() const
{
return RiaSummaryCurveAddress( summaryAddressX(), summaryAddressY() );
}
//--------------------------------------------------------------------------------------------------
@@ -179,6 +203,8 @@ RimSummaryCase* RimSummaryCurve::summaryCaseY() const
//--------------------------------------------------------------------------------------------------
RifEclipseSummaryAddress RimSummaryCurve::summaryAddressX() const
{
if ( m_xAxisType == RiaDefines::HorizontalAxisType::TIME ) return RifEclipseSummaryAddress::timeAddress();
return m_xValuesSummaryAddress->address();
}
@@ -192,6 +218,28 @@ void RimSummaryCurve::setSummaryAddressX( const RifEclipseSummaryAddress& addres
// TODO: Should interpolation be computed similar to RimSummaryCurve::setSummaryAddressY
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::setTopOrBottomAxisX( RiuPlotAxis plotAxis )
{
CAF_ASSERT( plotAxis.isHorizontal() );
RimSummaryPlot* plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
m_xPlotAxisProperties = plot->axisPropertiesForPlotAxis( plotAxis );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotAxis RimSummaryCurve::axisX() const
{
if ( m_xPlotAxisProperties )
return m_xPlotAxisProperties->plotAxis();
else
return RiuPlotAxis::defaultBottom();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -279,16 +327,6 @@ std::vector<double> RimSummaryCurve::valuesY() const
return values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::applyCurveDefinitionY( const RiaSummaryCurveDefinition& curveDefinition )
{
setSummaryCaseY( curveDefinition.summaryCaseY() );
setSummaryAddressY( curveDefinition.summaryAddressY() );
setIsEnsembleCurve( curveDefinition.isEnsembleCurve() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -398,9 +436,17 @@ void RimSummaryCurve::setOverrideCurveDataY( const std::vector<time_t>& dateTime
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveDefinition RimSummaryCurve::curveDefinitionX() const
void RimSummaryCurve::setAxisTypeX( RiaDefines::HorizontalAxisType axisType )
{
return RiaSummaryCurveDefinition( summaryCaseX(), summaryAddressX(), isEnsembleCurve() );
m_xAxisType = axisType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::HorizontalAxisType RimSummaryCurve::axisTypeX() const
{
return m_xAxisType();
}
//--------------------------------------------------------------------------------------------------
@@ -429,10 +475,12 @@ RimSummaryCase* RimSummaryCurve::summaryCaseX() const
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::setLeftOrRightAxisY( RiuPlotAxis plotAxis )
{
CAF_ASSERT( plotAxis.isVertical() );
m_plotAxis_OBSOLETE = plotAxis.axis();
RimSummaryPlot* plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
m_plotAxisProperties = plot->axisPropertiesForPlotAxis( plotAxis );
RimSummaryPlot* plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
m_yPlotAxisProperties = plot->axisPropertiesForPlotAxis( plotAxis );
}
//--------------------------------------------------------------------------------------------------
@@ -440,8 +488,8 @@ void RimSummaryCurve::setLeftOrRightAxisY( RiuPlotAxis plotAxis )
//--------------------------------------------------------------------------------------------------
RiuPlotAxis RimSummaryCurve::axisY() const
{
if ( m_plotAxisProperties )
return m_plotAxisProperties->plotAxis();
if ( m_yPlotAxisProperties )
return m_yPlotAxisProperties->plotAxis();
else
return RiuPlotAxis::defaultLeft();
}
@@ -499,18 +547,28 @@ QList<caf::PdmOptionItemInfo> RimSummaryCurve::calculateValueOptions( const caf:
{
appendOptionItemsForSummaryAddresses( &options, m_xValuesSummaryCase() );
}
else if ( fieldNeedingOptions == &m_plotAxisProperties )
else if ( fieldNeedingOptions == &m_yPlotAxisProperties )
{
auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
for ( auto axis : plot->plotAxes() )
{
// TODO: Should we allow time axis to be used as Y axis?
if ( dynamic_cast<RimPlotAxisProperties*>( axis ) )
{
options.push_back( caf::PdmOptionItemInfo( axis->objectName(), axis ) );
}
}
}
else if ( fieldNeedingOptions == &m_xPlotAxisProperties )
{
auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
for ( auto axis : plot->plotAxes() )
{
options.push_back( caf::PdmOptionItemInfo( axis->objectName(), axis ) );
}
}
return options;
}
@@ -540,26 +598,8 @@ QString RimSummaryCurve::createCurveAutoName()
}
RimMultiSummaryPlotNameHelper multiNameHelper( plotNameHelpers );
QString curveName = m_curveNameConfig->curveNameY( m_yValuesSummaryAddress->address(), currentPlotNameHelper, &multiNameHelper );
if ( curveName.isEmpty() )
{
curveName = m_curveNameConfig->curveNameY( m_yValuesSummaryAddress->address(), nullptr, nullptr );
}
if ( isCrossPlotCurve() )
{
QString curveNameX = m_curveNameConfig->curveNameX( m_xValuesSummaryAddress->address(), currentPlotNameHelper, &multiNameHelper );
if ( curveNameX.isEmpty() )
{
curveNameX = m_curveNameConfig->curveNameX( m_xValuesSummaryAddress->address(), nullptr, nullptr );
}
if ( !curveName.isEmpty() || !curveNameX.isEmpty() )
{
curveName += " | " + curveNameX;
}
}
QString curveName = m_curveNameConfig->curveName( curveAddress(), currentPlotNameHelper, &multiNameHelper );
if ( curveName.isEmpty() )
{
curveName = "Curve Name Placeholder";
@@ -601,7 +641,7 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot )
bool shouldPopulateViewWithEmptyData = false;
if ( isCrossPlotCurve() )
if ( m_xAxisType == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR )
{
auto curveValuesX = valuesX();
auto curveTimeStepsX = timeStepsX();
@@ -634,7 +674,7 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot )
else
{
std::vector<time_t> curveTimeStepsY = timeStepsY();
if ( curveTimeStepsY.size() > 0 && curveTimeStepsY.size() == curveValuesY.size() )
if ( plot->timeAxisProperties() && curveTimeStepsY.size() > 0 && curveTimeStepsY.size() == curveValuesY.size() )
{
if ( plot->timeAxisProperties()->timeMode() == RimSummaryTimeAxisProperties::DATE )
{
@@ -660,13 +700,13 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot )
}
else
{
if ( m_resampling() != RiaDefines::DateTimePeriod::NONE )
if ( m_yValuesResampling() != RiaDefines::DateTimePeriod::NONE )
{
auto [resampledTimeSteps, resampledValues] =
RiaSummaryTools::resampledValuesForPeriod( m_yValuesSummaryAddress->address(),
curveTimeStepsY,
curveValuesY,
m_resampling() );
m_yValuesResampling() );
if ( !resampledValues.empty() && !resampledTimeSteps.empty() )
{
@@ -728,7 +768,7 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot )
updateTimeAnnotations();
}
if ( updateParentPlot ) updateAxisInPlot( axisY() );
if ( updateParentPlot ) updatePlotAxis();
}
//--------------------------------------------------------------------------------------------------
@@ -770,10 +810,10 @@ void RimSummaryCurve::initAfterRead()
{
RimStackablePlotCurve::initAfterRead();
if ( m_plotAxisProperties.value() == nullptr )
if ( m_yPlotAxisProperties.value() == nullptr )
{
auto plot = firstAncestorOrThisOfType<RimSummaryPlot>();
if ( plot ) m_plotAxisProperties = plot->axisPropertiesForPlotAxis( RiuPlotAxis( m_plotAxis_OBSOLETE() ) );
if ( plot ) m_yPlotAxisProperties = plot->axisPropertiesForPlotAxis( RiuPlotAxis( m_plotAxis_OBSOLETE() ) );
}
if ( m_isEnsembleCurve().isPartiallyTrue() )
@@ -842,28 +882,32 @@ void RimSummaryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering
{
RimPlotCurve::updateFieldUiState();
bool isSummaryXHidden = ( m_xAxisType() != RiaDefines::HorizontalAxisType::SUMMARY_VECTOR );
m_xValuesSummaryCase.uiCapability()->setUiHidden( isSummaryXHidden );
m_xValuesSummaryAddress.uiCapability()->setUiHidden( isSummaryXHidden );
m_xValuesSummaryAddressUiField.uiCapability()->setUiHidden( isSummaryXHidden );
m_xPushButtonSelectSummaryAddress.uiCapability()->setUiHidden( isSummaryXHidden );
m_xPlotAxisProperties.uiCapability()->setUiHidden( isSummaryXHidden );
{
QString curveDataGroupName = "Summary Vector";
if ( isCrossPlotCurve() ) curveDataGroupName += " Y";
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroupWithKeyword( curveDataGroupName, "Summary Vector Y" );
QString curveDataGroupName = "Summary Vector";
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroupWithKeyword( curveDataGroupName, "curveDataGroupName" );
curveDataGroup->add( &m_yValuesSummaryCase, { true, 3, 1 } );
curveDataGroup->add( &m_yValuesSummaryAddressUiField, { true, 2, 1 } );
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, { false, 1, 0 } );
curveDataGroup->add( &m_resampling, { true, 3, 1 } );
curveDataGroup->add( &m_plotAxisProperties, { true, 3, 1 } );
if ( isCrossPlotCurve() )
m_showErrorBars = false;
else
curveDataGroup->add( &m_showErrorBars );
curveDataGroup->add( &m_yValuesResampling, { true, 3, 1 } );
curveDataGroup->add( &m_yPlotAxisProperties, { true, 3, 1 } );
curveDataGroup->add( &m_showErrorBars );
}
if ( isCrossPlotCurve() )
{
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector X" );
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector X Axis" );
curveDataGroup->add( &m_xAxisType, { true, 3, 1 } );
curveDataGroup->add( &m_xValuesSummaryCase, { true, 3, 1 } );
curveDataGroup->add( &m_xValuesSummaryAddressUiField, { true, 2, 1 } );
curveDataGroup->add( &m_xPushButtonSelectSummaryAddress, { false, 1, 0 } );
curveDataGroup->add( &m_xPlotAxisProperties, { true, 3, 1 } );
}
caf::PdmUiGroup* stackingGroup = uiOrdering.addNewGroup( "Stacking" );
@@ -882,7 +926,7 @@ void RimSummaryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering
m_curveNameConfig->uiOrdering( uiConfigName, *nameGroup );
}
uiOrdering.skipRemainingFields(); // For now.
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
@@ -917,7 +961,7 @@ void RimSummaryCurve::appendOptionItemsForSummaryAddresses( QList<caf::PdmOption
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::setResampling( RiaDefines::DateTimePeriodEnum resampling )
{
m_resampling = resampling;
m_yValuesResampling = resampling;
}
//--------------------------------------------------------------------------------------------------
@@ -943,7 +987,8 @@ RiaDefines::PhaseType RimSummaryCurve::phaseType() const
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::updatePlotAxis()
{
updateAxisInPlot( axisY() );
updateYAxisInPlot( axisY() );
updateXAxisInPlot( axisX() );
}
//--------------------------------------------------------------------------------------------------
@@ -1067,10 +1112,30 @@ void RimSummaryCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
loadAndUpdate = true;
}
else if ( changedField == &m_resampling )
else if ( changedField == &m_yValuesResampling )
{
loadAndUpdate = true;
}
else if ( &m_xAxisType == changedField )
{
if ( m_xAxisType() == RiaDefines::HorizontalAxisType::TIME )
{
m_xPlotAxisProperties = plot->timeAxisProperties();
}
else if ( m_xAxisType() == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR )
{
if ( !m_xValuesSummaryCase() )
{
m_xValuesSummaryCase = m_yValuesSummaryCase();
m_xValuesSummaryAddress->setAddress( m_yValuesSummaryAddress()->address() );
}
plot->findOrAssignPlotAxisX( this );
}
plot->updateAxes();
plot->updatePlotTitle();
loadAndUpdate = true;
}
else if ( &m_showCurve == changedField )
{
plot->updateAxes();
@@ -1079,9 +1144,15 @@ void RimSummaryCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
RiuPlotMainWindow* mainPlotWindow = RiaGuiApplication::instance()->mainPlotWindow();
mainPlotWindow->updateMultiPlotToolBar();
}
else if ( changedField == &m_plotAxisProperties )
else if ( changedField == &m_yPlotAxisProperties )
{
updateAxisInPlot( axisY() );
updateYAxisInPlot( axisY() );
plot->updateAxes();
dataChanged.send();
}
else if ( changedField == &m_xPlotAxisProperties )
{
updateXAxisInPlot( axisX() );
plot->updateAxes();
dataChanged.send();
}

View File

@@ -26,6 +26,8 @@
#include "RiaDateTimeDefines.h"
#include "RiaDefines.h"
#include "RiaSummaryCurveAddress.h"
#include "RiaSummaryDefines.h"
#include "RifEclipseSummaryAddressQMetaType.h"
#include "RimStackablePlotCurve.h"
@@ -52,14 +54,15 @@ public:
RimSummaryCurve();
~RimSummaryCurve() override;
RiaSummaryCurveDefinition curveDefinition() const;
RiaSummaryCurveAddress curveAddress() const;
// Y Axis functions
RiaSummaryCurveDefinition curveDefinitionY() const;
RimSummaryCase* summaryCaseY() const;
RifEclipseSummaryAddress summaryAddressY() const;
std::string unitNameY() const;
virtual std::vector<double> valuesY() const;
void applyCurveDefinitionY( const RiaSummaryCurveDefinition& curveDefinition );
void setSummaryCaseY( RimSummaryCase* sumCase );
void setSummaryAddressYAndApplyInterpolation( const RifEclipseSummaryAddress& address );
void setSummaryAddressY( const RifEclipseSummaryAddress& address );
@@ -74,14 +77,17 @@ public:
void setOverrideCurveDataY( const std::vector<time_t>& xValues, const std::vector<double>& yValues );
// X Axis functions
RiaSummaryCurveDefinition curveDefinitionX() const;
RimSummaryCase* summaryCaseX() const;
RifEclipseSummaryAddress summaryAddressX() const;
std::string unitNameX() const;
virtual std::vector<double> valuesX() const;
void setAxisTypeX( RiaDefines::HorizontalAxisType axisType );
RiaDefines::HorizontalAxisType axisTypeX() const;
RimSummaryCase* summaryCaseX() const;
RifEclipseSummaryAddress summaryAddressX() const;
std::string unitNameX() const;
virtual std::vector<double> valuesX() const;
void setSummaryCaseX( RimSummaryCase* sumCase );
void setSummaryAddressX( const RifEclipseSummaryAddress& address );
void setSummaryCaseX( RimSummaryCase* sumCase );
void setSummaryAddressX( const RifEclipseSummaryAddress& address );
void setTopOrBottomAxisX( RiuPlotAxis plotAxis );
RiuPlotAxis axisX() const;
// Other
bool isEnsembleCurve() const;
@@ -133,23 +139,25 @@ private:
private:
// Y values
caf::PdmPtrField<RimSummaryCase*> m_yValuesSummaryCase;
caf::PdmChildField<RimSummaryAddress*> m_yValuesSummaryAddress;
caf::PdmField<RifEclipseSummaryAddress> m_yValuesSummaryAddressUiField;
caf::PdmField<bool> m_yPushButtonSelectSummaryAddress;
caf::PdmField<RiaDefines::DateTimePeriodEnum> m_resampling;
caf::PdmPtrField<RimSummaryCase*> m_yValuesSummaryCase;
caf::PdmChildField<RimSummaryAddress*> m_yValuesSummaryAddress;
caf::PdmField<RifEclipseSummaryAddress> m_yValuesSummaryAddressUiField;
caf::PdmField<bool> m_yPushButtonSelectSummaryAddress;
caf::PdmPtrField<RimPlotAxisPropertiesInterface*> m_yPlotAxisProperties;
caf::PdmField<RiaDefines::DateTimePeriodEnum> m_yValuesResampling;
// X values
caf::PdmPtrField<RimSummaryCase*> m_xValuesSummaryCase;
caf::PdmChildField<RimSummaryAddress*> m_xValuesSummaryAddress;
caf::PdmField<RifEclipseSummaryAddress> m_xValuesSummaryAddressUiField;
caf::PdmField<bool> m_xPushButtonSelectSummaryAddress;
caf::PdmField<caf::AppEnum<RiaDefines::HorizontalAxisType>> m_xAxisType;
caf::PdmPtrField<RimSummaryCase*> m_xValuesSummaryCase;
caf::PdmChildField<RimSummaryAddress*> m_xValuesSummaryAddress;
caf::PdmField<RifEclipseSummaryAddress> m_xValuesSummaryAddressUiField;
caf::PdmField<bool> m_xPushButtonSelectSummaryAddress;
caf::PdmPtrField<RimPlotAxisPropertiesInterface*> m_xPlotAxisProperties;
// Other fields
caf::PdmField<caf::Tristate> m_isEnsembleCurve;
caf::PdmChildField<RimSummaryCurveAutoName*> m_curveNameConfig;
caf::PdmField<caf::AppEnum<RiaDefines::PlotAxis>> m_plotAxis_OBSOLETE;
caf::PdmPtrField<RimPlotAxisPropertiesInterface*> m_plotAxisProperties;
caf::PdmField<bool> m_isTopZWithinCategory;
};

View File

@@ -65,6 +65,39 @@ RimSummaryCurveAutoName::RimSummaryCurveAutoName()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCurveAutoName::curveName( const RiaSummaryCurveAddress& summaryCurveAddress,
const RimSummaryNameHelper* currentNameHelper,
const RimSummaryNameHelper* plotNameHelper ) const
{
QString name;
{
auto nameForY = curveNameY( summaryCurveAddress.summaryAddressY(), currentNameHelper, plotNameHelper );
if ( nameForY.isEmpty() )
{
nameForY = curveNameY( summaryCurveAddress.summaryAddressY(), nullptr, nullptr );
}
name += nameForY;
}
if ( summaryCurveAddress.summaryAddressX().category() != SummaryCategory::SUMMARY_TIME )
{
auto nameForX = curveNameX( summaryCurveAddress.summaryAddressX(), currentNameHelper, plotNameHelper );
if ( nameForX.isEmpty() )
{
nameForX = curveNameX( summaryCurveAddress.summaryAddressX(), nullptr, nullptr );
}
if ( nameForX != name ) name += " | " + nameForX;
}
return name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -193,7 +226,7 @@ QString RimSummaryCurveAutoName::buildCurveName( const RifEclipseSummaryAddress&
if ( m_vectorName || m_longVectorName )
{
bool skipSubString = currentNameHelper && currentNameHelper->vectorNames().size() == 1;
bool skipSubString = currentNameHelper && currentNameHelper->isPlotDisplayingSingleCurve();
if ( !skipSubString )
{
if ( m_longVectorName() )

View File

@@ -23,6 +23,7 @@
class RifEclipseSummaryAddress;
class RimSummaryNameHelper;
class RiaSummaryCurveAddress;
class RimSummaryCurveAutoName : public caf::PdmObject
{
@@ -31,17 +32,20 @@ class RimSummaryCurveAutoName : public caf::PdmObject
public:
RimSummaryCurveAutoName();
QString curveNameY( const RifEclipseSummaryAddress& summaryAddress,
const RimSummaryNameHelper* currentNameHelper,
const RimSummaryNameHelper* plotNameHelper ) const;
QString curveNameX( const RifEclipseSummaryAddress& summaryAddress,
const RimSummaryNameHelper* currentNameHelper,
const RimSummaryNameHelper* plotNameHelper ) const;
QString curveName( const RiaSummaryCurveAddress& summaryCurveAddress,
const RimSummaryNameHelper* currentNameHelper,
const RimSummaryNameHelper* plotNameHelper ) const;
void applySettings( const RimSummaryCurveAutoName& other );
private:
friend class RimSummaryCurve;
QString curveNameY( const RifEclipseSummaryAddress& summaryAddress,
const RimSummaryNameHelper* currentNameHelper,
const RimSummaryNameHelper* plotNameHelper ) const;
QString curveNameX( const RifEclipseSummaryAddress& summaryAddress,
const RimSummaryNameHelper* currentNameHelper,
const RimSummaryNameHelper* plotNameHelper ) const;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;

View File

@@ -447,6 +447,21 @@ RimSummaryPlotSourceStepping* RimSummaryCurveCollection::sourceSteppingObject( R
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RiaDefines::HorizontalAxisType> RimSummaryCurveCollection::horizontalAxisTypes() const
{
std::set<RiaDefines::HorizontalAxisType> axisTypes;
for ( const auto& curve : m_curves )
{
axisTypes.insert( curve->axisTypeX() );
}
return axisTypes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -18,6 +18,7 @@
#pragma once
#include "RiaSummaryDefines.h"
#include "RimSummaryPlotSourceStepping.h"
#include "cafPdmChildArrayField.h"
@@ -54,8 +55,9 @@ public:
RimSummaryPlotSourceStepping* sourceSteppingObject( RimSummaryDataSourceStepping::Axis sourceSteppingType ) const;
std::vector<RimSummaryCurve*> curves() const;
std::vector<RimSummaryCurve*> curvesForSourceStepping( RimSummaryDataSourceStepping::Axis steppingType ) const;
std::set<RiaDefines::HorizontalAxisType> horizontalAxisTypes() const;
std::vector<RimSummaryCurve*> curves() const;
std::vector<RimSummaryCurve*> curvesForSourceStepping( RimSummaryDataSourceStepping::Axis steppingType ) const;
void setCurveAsTopZWithinCategory( RimSummaryCurve* curve );

View File

@@ -198,9 +198,9 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vector<RimSummaryCurv
QString curveCaseName = curve->summaryCaseY()->displayCaseName();
QString ensembleName;
if ( curve->curveDefinitionY().ensemble() )
if ( curve->curveDefinition().ensemble() )
{
ensembleName = curve->curveDefinitionY().ensemble()->name();
ensembleName = curve->curveDefinition().ensemble()->name();
}
CurveData curveData = { curve->curveExportDescription( {} ), curve->summaryAddressY(), curve->valuesY() };

View File

@@ -374,19 +374,19 @@ void RimSummaryMultiPlot::populateNameHelper( RimSummaryPlotNameHelper* nameHelp
{
nameHelper->clear();
std::vector<RifEclipseSummaryAddress> addresses;
std::vector<RiaSummaryCurveAddress> addresses;
std::vector<RimSummaryCase*> sumCases;
std::vector<RimSummaryCaseCollection*> ensembleCases;
for ( RimSummaryCurve* curve : allCurves( RimSummaryDataSourceStepping::Axis::Y_AXIS ) )
{
addresses.push_back( curve->summaryAddressY() );
addresses.push_back( curve->curveAddress() );
sumCases.push_back( curve->summaryCaseY() );
}
for ( auto curveSet : curveSets() )
{
addresses.push_back( curveSet->summaryAddress() );
addresses.push_back( curveSet->curveAddress() );
ensembleCases.push_back( curveSet->summaryCaseCollection() );
}
@@ -1273,12 +1273,13 @@ void RimSummaryMultiPlot::analyzePlotsAndAdjustAppearanceSettings()
for ( auto p : summaryPlots() )
{
auto timeAxisProp = p->timeAxisProperties();
if ( auto timeAxisProp = p->timeAxisProperties() )
{
auto tickMarkCount = ( columnCount() < 3 ) ? RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_DEFAULT
: RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_FEW;
auto tickMarkCount = ( columnCount() < 3 ) ? RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_DEFAULT
: RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_FEW;
timeAxisProp->setAutoValueForMajorTickmarkCount( tickMarkCount, notifyFieldChanged );
timeAxisProp->setAutoValueForMajorTickmarkCount( tickMarkCount, notifyFieldChanged );
}
for ( auto* axisProp : p->plotYAxes() )
{

View File

@@ -38,15 +38,15 @@ public:
QString aggregatedPlotTitle( const RimSummaryNameHelper& summaryMultiPlotNameHelper ) const;
virtual bool isPlotDisplayingSingleVectorName() const = 0;
virtual bool isWellNameInTitle() const = 0;
virtual bool isGroupNameInTitle() const = 0;
virtual bool isNetworkInTitle() const = 0;
virtual bool isRegionInTitle() const = 0;
virtual bool isCaseInTitle() const = 0;
virtual bool isBlockInTitle() const = 0;
virtual bool isSegmentInTitle() const = 0;
virtual bool isCompletionInTitle() const = 0;
virtual bool isPlotDisplayingSingleCurve() const = 0;
virtual bool isWellNameInTitle() const = 0;
virtual bool isGroupNameInTitle() const = 0;
virtual bool isNetworkInTitle() const = 0;
virtual bool isRegionInTitle() const = 0;
virtual bool isCaseInTitle() const = 0;
virtual bool isBlockInTitle() const = 0;
virtual bool isSegmentInTitle() const = 0;
virtual bool isCompletionInTitle() const = 0;
virtual std::set<std::string> vectorNames() const = 0;
virtual QString caseName() const = 0;

View File

@@ -30,9 +30,11 @@
#include "RiaStdStringTools.h"
#include "RiaSummaryAddressAnalyzer.h"
#include "RiaSummaryCurveDefinition.h"
#include "RiaSummaryDefines.h"
#include "RiaSummaryTools.h"
#include "RiaTimeHistoryCurveResampler.h"
#include "RifEclipseSummaryAddressDefines.h"
#include "RifReaderEclipseSummary.h"
#include "RicfCommandObject.h"
@@ -118,9 +120,8 @@ struct RimSummaryPlot::CurveInfo
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryPlot::RimSummaryPlot( bool isCrossPlot )
RimSummaryPlot::RimSummaryPlot()
: RimPlot()
, m_isCrossPlot( isCrossPlot )
, curvesChanged( this )
, axisChanged( this )
, plotZoomedByUser( this )
@@ -156,19 +157,6 @@ RimSummaryPlot::RimSummaryPlot( bool isCrossPlot )
CAF_PDM_InitFieldNoDefault( &m_axisPropertiesArray, "AxisProperties", "Axes", ":/Axes16x16.png" );
if ( m_isCrossPlot )
{
addNewAxisProperties( RiuPlotAxis::defaultBottom(), "Bottom" );
}
else
{
auto* timeAxisProperties = new RimSummaryTimeAxisProperties;
timeAxisProperties->settingsChanged.connect( this, &RimSummaryPlot::timeAxisSettingsChanged );
timeAxisProperties->requestLoadDataAndUpdate.connect( this, &RimSummaryPlot::timeAxisSettingsChangedReloadRequired );
m_axisPropertiesArray.push_back( timeAxisProperties );
}
auto leftAxis = addNewAxisProperties( RiuPlotAxis::defaultLeft(), "Left" );
leftAxis->setAlwaysRequired( true );
@@ -179,14 +167,6 @@ RimSummaryPlot::RimSummaryPlot( bool isCrossPlot )
CAF_PDM_InitFieldNoDefault( &m_sourceStepping, "SourceStepping", "" );
m_sourceStepping = new RimSummaryPlotSourceStepping;
if ( m_isCrossPlot )
{
m_sourceStepping->setSourceSteppingType( RimSummaryDataSourceStepping::Axis::UNION_X_Y_AXIS );
}
else
{
m_sourceStepping->setSourceSteppingType( RimSummaryDataSourceStepping::Axis::Y_AXIS );
}
m_sourceStepping->setSourceSteppingObject( this );
m_sourceStepping.uiCapability()->setUiTreeHidden( true );
@@ -220,6 +200,8 @@ RimSummaryPlot::RimSummaryPlot( bool isCrossPlot )
m_timeAxisProperties_OBSOLETE.uiCapability()->setUiTreeHidden( true );
m_timeAxisProperties_OBSOLETE.xmlCapability()->setIOWritable( false );
m_timeAxisProperties_OBSOLETE = new RimSummaryTimeAxisProperties;
ensureRequiredAxisObjectsForCurves();
}
//--------------------------------------------------------------------------------------------------
@@ -258,14 +240,9 @@ void RimSummaryPlot::updateAxes()
m_summaryPlot->updateAnnotationObjects( leftYAxisProperties );
}
if ( m_isCrossPlot )
{
updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM );
}
else
{
updateTimeAxis( timeAxisProperties() );
}
updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM );
updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_TOP );
updateTimeAxis( timeAxisProperties() );
updateZoomInParentPlot();
}
@@ -501,7 +478,12 @@ std::vector<RimSummaryCurve*> RimSummaryPlot::allCurves( RimSummaryDataSourceSte
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryDataSourceStepping::Axis> RimSummaryPlot::availableAxes() const
{
if ( m_isCrossPlot ) return { RimSummaryDataSourceStepping::Axis::X_AXIS, RimSummaryDataSourceStepping::Axis::Y_AXIS };
auto axisTypes = m_summaryCurveCollection->horizontalAxisTypes();
if ( axisTypes.contains( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ) )
{
return { RimSummaryDataSourceStepping::Axis::X_AXIS, RimSummaryDataSourceStepping::Axis::Y_AXIS };
}
return { RimSummaryDataSourceStepping::Axis::X_AXIS };
}
@@ -912,50 +894,50 @@ void RimSummaryPlot::updateNumericalAxis( RiaDefines::PlotAxis plotAxis )
if ( riuPlotAxis.axis() == plotAxis )
{
auto* axisProps = dynamic_cast<RimPlotAxisProperties*>( axisProperties );
if ( axisProps )
if ( !axisProps ) continue;
if ( axisProperties->isActive() && hasVisibleCurvesForAxis( riuPlotAxis ) )
{
if ( axisProperties->isActive() && hasVisibleCurvesForAxis( riuPlotAxis ) )
plotWidget()->enableAxis( riuPlotAxis, true );
}
else
{
plotWidget()->enableAxis( riuPlotAxis, false );
}
if ( !hasVisibleCurvesForAxis( riuPlotAxis ) )
{
axisProps->setNameForUnusedAxis();
}
else
{
std::set<QString> timeHistoryQuantities;
for ( auto c : visibleTimeHistoryCurvesForAxis( riuPlotAxis ) )
{
plotWidget()->enableAxis( riuPlotAxis, true );
}
else
{
plotWidget()->enableAxis( riuPlotAxis, false );
timeHistoryQuantities.insert( c->quantityName() );
}
if ( !hasVisibleCurvesForAxis( riuPlotAxis ) )
std::vector<RiaSummaryCurveDefinition> curveDefs;
for ( auto summaryCurve : summaryCurves() )
{
axisProps->setNameForUnusedAxis();
}
else
{
std::set<QString> timeHistoryQuantities;
for ( auto c : visibleTimeHistoryCurvesForAxis( riuPlotAxis ) )
if ( summaryCurve->axisY() == riuPlotAxis || summaryCurve->axisX() == riuPlotAxis )
{
timeHistoryQuantities.insert( c->quantityName() );
curveDefs.push_back( summaryCurve->curveDefinition() );
}
std::vector<RiaSummaryCurveDefinition> curveDefs;
for ( auto summaryCurve : summaryCurves() )
{
if ( summaryCurve->axisY() != riuPlotAxis ) continue;
curveDefs.push_back( summaryCurve->curveDefinitionY() );
}
for ( auto curveSet : ensembleCurveSetCollection()->curveSets() )
{
if ( curveSet->axisY() != riuPlotAxis ) continue;
RiaSummaryCurveDefinition def( curveSet->summaryCaseCollection(), curveSet->summaryAddress() );
curveDefs.push_back( def );
}
RimSummaryPlotAxisFormatter calc( axisProps, {}, curveDefs, visibleAsciiDataCurvesForAxis( riuPlotAxis ), timeHistoryQuantities );
calc.applyAxisPropertiesToPlot( plotWidget() );
}
for ( auto curveSet : ensembleCurveSetCollection()->curveSets() )
{
if ( curveSet->axisY() != riuPlotAxis ) continue;
RiaSummaryCurveDefinition def( curveSet->summaryCaseCollection(), curveSet->summaryAddress() );
curveDefs.push_back( def );
}
RimSummaryPlotAxisFormatter calc( axisProps, {}, curveDefs, visibleAsciiDataCurvesForAxis( riuPlotAxis ), timeHistoryQuantities );
calc.applyAxisPropertiesToPlot( plotWidget() );
}
plotWidget()->enableAxisNumberLabels( riuPlotAxis, axisProps->showNumbers() );
@@ -972,11 +954,18 @@ void RimSummaryPlot::updateNumericalAxis( RiaDefines::PlotAxis plotAxis )
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::updateTimeAxis( RimSummaryTimeAxisProperties* timeAxisProperties )
{
if ( !plotWidget() ) return;
if ( !plotWidget() || !timeAxisProperties ) return;
if ( !timeAxisProperties->isActive() )
bool anyTimeHistoryCurvePresent = false;
{
plotWidget()->enableAxis( RiuPlotAxis::defaultBottom(), false );
if ( !visibleTimeHistoryCurvesForAxis( RimSummaryPlot::plotAxisForTime() ).empty() ) anyTimeHistoryCurvePresent = true;
if ( !visibleAsciiDataCurvesForAxis( RimSummaryPlot::plotAxisForTime() ).empty() ) anyTimeHistoryCurvePresent = true;
if ( !visibleSummaryCurvesForAxis( RimSummaryPlot::plotAxisForTime() ).empty() ) anyTimeHistoryCurvePresent = true;
}
if ( !anyTimeHistoryCurvePresent || !timeAxisProperties->isActive() )
{
plotWidget()->enableAxis( RimSummaryPlot::plotAxisForTime(), false );
return;
}
@@ -996,7 +985,7 @@ void RimSummaryPlot::updateTimeAxis( RimSummaryTimeAxisProperties* timeAxisPrope
m_summaryPlot->useTimeBasedTimeAxis();
}
plotWidget()->enableAxis( RiuPlotAxis::defaultBottom(), true );
plotWidget()->enableAxis( RimSummaryPlot::plotAxisForTime(), true );
{
Qt::AlignmentFlag alignment = Qt::AlignCenter;
@@ -1005,20 +994,20 @@ void RimSummaryPlot::updateTimeAxis( RimSummaryTimeAxisProperties* timeAxisPrope
alignment = Qt::AlignRight;
}
plotWidget()->setAxisFontsAndAlignment( RiuPlotAxis::defaultBottom(),
plotWidget()->setAxisFontsAndAlignment( RimSummaryPlot::plotAxisForTime(),
timeAxisProperties->titleFontSize(),
timeAxisProperties->valuesFontSize(),
true,
alignment );
plotWidget()->setAxisTitleText( RiuPlotAxis::defaultBottom(), timeAxisProperties->title() );
plotWidget()->setAxisTitleEnabled( RiuPlotAxis::defaultBottom(), timeAxisProperties->showTitle );
plotWidget()->setAxisTitleText( RimSummaryPlot::plotAxisForTime(), timeAxisProperties->title() );
plotWidget()->setAxisTitleEnabled( RimSummaryPlot::plotAxisForTime(), timeAxisProperties->showTitle );
if ( timeAxisProperties->tickmarkType() == RimSummaryTimeAxisProperties::TickmarkType::TICKMARK_COUNT )
{
RimSummaryTimeAxisProperties::LegendTickmarkCount tickmarkCountEnum = timeAxisProperties->majorTickmarkCount();
int maxTickmarkCount = RimPlotAxisPropertiesInterface::tickmarkCountFromEnum( tickmarkCountEnum );
plotWidget()->setAxisMaxMajor( RiuPlotAxis::defaultBottom(), maxTickmarkCount );
plotWidget()->setAxisMaxMajor( RimSummaryPlot::plotAxisForTime(), maxTickmarkCount );
}
else if ( timeAxisProperties->tickmarkType() == RimSummaryTimeAxisProperties::TickmarkType::TICKMARK_CUSTOM )
{
@@ -1135,10 +1124,10 @@ void RimSummaryPlot::createAndSetCustomTimeAxisTickmarks( RimSummaryTimeAxisProp
{
if ( !timeAxisProperties || !plotWidget() ) return;
const auto [minValue, maxValue] = plotWidget()->axisRange( RiuPlotAxis::defaultBottom() );
const auto [minValue, maxValue] = plotWidget()->axisRange( RimSummaryPlot::plotAxisForTime() );
const auto tickmarkList = timeAxisProperties->createTickmarkList( QwtDate::toDateTime( minValue ), QwtDate::toDateTime( maxValue ) );
plotWidget()->setMajorTicksList( RiuPlotAxis::defaultBottom(), tickmarkList, minValue, maxValue );
plotWidget()->setMajorTicksList( RimSummaryPlot::plotAxisForTime(), tickmarkList, minValue, maxValue );
}
//--------------------------------------------------------------------------------------------------
@@ -1155,7 +1144,7 @@ void RimSummaryPlot::overrideTimeAxisSettingsIfTooManyCustomTickmarks( RimSummar
// Prevent too large number of ticks by overriding time axis interval and step to
// prevent large number of tickmarks by accident.
const auto [minValue, maxValue] = plotWidget()->axisRange( RiuPlotAxis::defaultBottom() );
const auto [minValue, maxValue] = plotWidget()->axisRange( RimSummaryPlot::plotAxisForTime() );
const double ticksInterval = timeAxisProperties->getTickmarkIntervalDouble();
const uint numTicks = static_cast<uint>( std::ceil( ( maxValue - minValue ) / ticksInterval ) );
if ( numTicks > MAX_NUM_TICKS )
@@ -1195,6 +1184,76 @@ bool RimSummaryPlot::isOnlyWaterCutCurvesVisible( RiuPlotAxis plotAxis )
return ( waterCutCurveCount == curves.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotAxis RimSummaryPlot::plotAxisForTime()
{
return RiuPlotAxis::defaultBottom();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::ensureRequiredAxisObjectsForCurves()
{
// Always make sure time axis properties are present
if ( !timeAxisProperties() )
{
auto* axisProperties = new RimSummaryTimeAxisProperties;
axisProperties->settingsChanged.connect( this, &RimSummaryPlot::timeAxisSettingsChanged );
axisProperties->requestLoadDataAndUpdate.connect( this, &RimSummaryPlot::timeAxisSettingsChangedReloadRequired );
m_axisPropertiesArray.push_back( axisProperties );
}
auto axisTypes = m_summaryCurveCollection->horizontalAxisTypes();
if ( axisTypes.contains( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ) )
{
m_sourceStepping->setSourceSteppingType( RimSummaryDataSourceStepping::Axis::UNION_X_Y_AXIS );
}
else
{
m_sourceStepping->setSourceSteppingType( RimSummaryDataSourceStepping::Axis::Y_AXIS );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::findOrAssignPlotAxisX( RimSummaryCurve* curve )
{
for ( RimPlotAxisPropertiesInterface* axisProperties : m_axisPropertiesArray )
{
if ( axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM )
{
auto propertyAxis = dynamic_cast<RimPlotAxisProperties*>( axisProperties );
if ( propertyAxis )
{
curve->setTopOrBottomAxisX( propertyAxis->plotAxis() );
return;
}
}
}
if ( curve->summaryCaseX() != nullptr && plotWidget() && plotWidget()->isMultiAxisSupported() )
{
QString axisObjectName = "New Axis";
if ( !curve->summaryAddressX().uiText().empty() ) axisObjectName = QString::fromStdString( curve->summaryAddressX().uiText() );
RiuPlotAxis newPlotAxis = plotWidget()->createNextPlotAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM );
addNewAxisProperties( newPlotAxis, axisObjectName );
if ( plotWidget() )
{
plotWidget()->ensureAxisIsCreated( newPlotAxis );
}
updateAxes();
curve->setTopOrBottomAxisX( newPlotAxis );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -1210,45 +1269,29 @@ std::vector<RimSummaryCurve*> RimSummaryPlot::visibleSummaryCurvesForAxis( RiuPl
{
std::vector<RimSummaryCurve*> curves;
if ( plotAxis.axis() == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM )
if ( m_summaryCurveCollection && m_summaryCurveCollection->isCurvesVisible() )
{
if ( m_summaryCurveCollection && m_summaryCurveCollection->isCurvesVisible() )
for ( RimSummaryCurve* curve : m_summaryCurveCollection->curves() )
{
for ( RimSummaryCurve* curve : m_summaryCurveCollection->curves() )
if ( curve->isChecked() && ( curve->axisY() == plotAxis || curve->axisX() == plotAxis ) )
{
if ( curve->isChecked() )
{
curves.push_back( curve );
}
curves.push_back( curve );
}
}
}
else
if ( m_ensembleCurveSetCollection && m_ensembleCurveSetCollection->isCurveSetsVisible() )
{
if ( m_summaryCurveCollection && m_summaryCurveCollection->isCurvesVisible() )
for ( RimEnsembleCurveSet* curveSet : m_ensembleCurveSetCollection->curveSets() )
{
for ( RimSummaryCurve* curve : m_summaryCurveCollection->curves() )
for ( RimSummaryCurve* curve : curveSet->curves() )
{
if ( curve->isChecked() && curve->axisY() == plotAxis )
if ( curve->isChecked() && ( curve->axisY() == plotAxis || curve->axisX() == plotAxis ) )
{
curves.push_back( curve );
}
}
}
if ( m_ensembleCurveSetCollection && m_ensembleCurveSetCollection->isCurveSetsVisible() )
{
for ( RimEnsembleCurveSet* curveSet : m_ensembleCurveSetCollection->curveSets() )
{
for ( RimSummaryCurve* curve : curveSet->curves() )
{
if ( curve->isChecked() && curve->axisY() == plotAxis )
{
curves.push_back( curve );
}
}
}
}
}
return curves;
@@ -1349,6 +1392,7 @@ void RimSummaryPlot::updateCaseNameHasChanged()
RimTimeAxisAnnotation* RimSummaryPlot::addTimeAnnotation( time_t time )
{
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
CAF_ASSERT( axisProps );
auto* annotation = new RimTimeAxisAnnotation;
annotation->setTime( time );
@@ -1364,6 +1408,7 @@ RimTimeAxisAnnotation* RimSummaryPlot::addTimeAnnotation( time_t time )
RimTimeAxisAnnotation* RimSummaryPlot::addTimeRangeAnnotation( time_t startTime, time_t endTime )
{
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
CAF_ASSERT( axisProps );
auto* annotation = new RimTimeAxisAnnotation;
annotation->setTimeRange( startTime, endTime );
@@ -1379,7 +1424,7 @@ RimTimeAxisAnnotation* RimSummaryPlot::addTimeRangeAnnotation( time_t startTime,
void RimSummaryPlot::removeAllTimeAnnotations()
{
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
axisProps->removeAllAnnotations();
if ( axisProps ) axisProps->removeAllAnnotations();
}
//--------------------------------------------------------------------------------------------------
@@ -1388,6 +1433,8 @@ void RimSummaryPlot::removeAllTimeAnnotations()
void RimSummaryPlot::removeTimeAnnotation( RimTimeAxisAnnotation* annotation )
{
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
CAF_ASSERT( axisProps );
axisProps->removeAnnotation( annotation );
}
@@ -1816,12 +1863,9 @@ void RimSummaryPlot::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin
uiTreeOrdering.add( curve );
}
if ( !m_isCrossPlot )
for ( auto& curveSet : m_ensembleCurveSetCollection->curveSets() )
{
for ( auto& curveSet : m_ensembleCurveSetCollection->curveSets() )
{
uiTreeOrdering.add( curveSet );
}
uiTreeOrdering.add( curveSet );
}
if ( !isPlotEditor )
@@ -2049,7 +2093,7 @@ void RimSummaryPlot::timeAxisSettingsChanged( const caf::SignalEmitter* emitter
if ( !timeAxisProps->isAutoZoom() && plotWidget() )
{
// If not auto zoom - the new date and time ranges must be set and axes updated
plotWidget()->setAxisScale( RiuPlotAxis::defaultBottom(), timeAxisProps->visibleRangeMin(), timeAxisProps->visibleRangeMax() );
plotWidget()->setAxisScale( RimSummaryPlot::plotAxisForTime(), timeAxisProps->visibleRangeMin(), timeAxisProps->visibleRangeMax() );
plotWidget()->updateAxes();
}
@@ -2220,26 +2264,30 @@ bool RimSummaryPlot::autoPlotTitle() const
//--------------------------------------------------------------------------------------------------
RimSummaryPlot::CurveInfo RimSummaryPlot::handleSummaryCaseDrop( RimSummaryCase* summaryCase )
{
int newCurves = 0;
std::vector<RimSummaryCurve*> curves;
std::map<RifEclipseSummaryAddress, std::set<RimSummaryCase*>> dataVectorMap;
std::map<std::pair<RifEclipseSummaryAddress, RifEclipseSummaryAddress>, std::set<RimSummaryCase*>> dataVectorMap;
for ( auto& curve : summaryCurves() )
{
const auto addr = curve->summaryAddressY();
dataVectorMap[addr].insert( curve->summaryCaseY() );
const auto addr = curve->summaryAddressY();
const auto addrX = curve->summaryAddressX();
// NB! This concept is used to make it possible to avoid adding curves for a case that is already present
// To be complete, the summaryCaseX() should also be checked, but this is not done for now
dataVectorMap[std::make_pair( addr, addrX )].insert( curve->summaryCaseY() );
}
for ( const auto& [addr, cases] : dataVectorMap )
std::vector<RimSummaryCurve*> curves;
for ( const auto& [addressPair, cases] : dataVectorMap )
{
if ( cases.count( summaryCase ) > 0 ) continue;
curves.push_back( addNewCurveY( addr, summaryCase ) );
newCurves++;
const auto& [addrY, addrX] = addressPair;
curves.push_back( addNewCurve( addrY, summaryCase, addrX, summaryCase ) );
}
return { newCurves, curves, {} };
return { .curveCount = static_cast<int>( curves.size() ), .curves = curves, .curveSets = {} };
}
//--------------------------------------------------------------------------------------------------
@@ -2291,68 +2339,55 @@ RimSummaryPlot::CurveInfo RimSummaryPlot::handleAddressCollectionDrop( RimSummar
{
for ( auto& curve : summaryCurves() )
{
sourceCurveDefs.push_back( curve->curveDefinitionY() );
sourceCurveDefs.push_back( curve->curveDefinition() );
}
}
if ( ensembleCase )
{
auto curveSets = m_ensembleCurveSetCollection->curveSets();
for ( auto curveSet : curveSets )
if ( ensembleCase )
{
sourceCurveDefs.push_back( RiaSummaryCurveDefinition( ensembleCase, curveSet->summaryAddress() ) );
auto curveSets = m_ensembleCurveSetCollection->curveSets();
for ( auto curveSet : curveSets )
{
sourceCurveDefs.push_back( RiaSummaryCurveDefinition( ensembleCase, curveSet->summaryAddress() ) );
}
}
}
for ( auto& curveDef : sourceCurveDefs )
{
auto newCurveDef = curveDef;
auto curveAdr = newCurveDef.summaryAddressY();
auto newCurveDef = curveDef;
const auto curveAdr = newCurveDef.summaryAddressY();
std::string objectIdentifierString;
if ( ( curveAdr.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL ) &&
( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::WELL ) )
{
objectIdentifierString = curveAdr.wellName();
curveAdr.setWellName( droppedName );
newCurveDef.setSummaryAddressY( curveAdr );
}
else if ( ( curveAdr.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_GROUP ) &&
( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::GROUP ) )
{
objectIdentifierString = curveAdr.groupName();
curveAdr.setGroupName( droppedName );
newCurveDef.setSummaryAddressY( curveAdr );
}
else if ( ( curveAdr.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_NETWORK ) &&
( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::NETWORK ) )
{
objectIdentifierString = curveAdr.networkName();
curveAdr.setNetworkName( droppedName );
newCurveDef.setSummaryAddressY( curveAdr );
}
else if ( ( curveAdr.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_REGION ) &&
( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::REGION ) )
{
objectIdentifierString = std::to_string( curveAdr.regionNumber() );
int droppedRegion = std::stoi( droppedName );
curveAdr.setRegion( droppedRegion );
newCurveDef.setSummaryAddressY( curveAdr );
}
else if ( ( curveAdr.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL_SEGMENT ) &&
( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::WELL_SEGMENT ) )
{
objectIdentifierString = std::to_string( curveAdr.wellSegmentNumber() );
int droppedWellSegmentNumber = std::stoi( droppedName );
curveAdr.setWellSegmentNumber( droppedWellSegmentNumber );
newCurveDef.setSummaryAddressY( curveAdr );
}
if ( !objectIdentifierString.empty() )
{
newCurveDef.setIdentifierText( curveAdr.category(), droppedName );
newCurveDefsWithObjectNames[newCurveDef].insert( objectIdentifierString );
const auto& addr = curveDef.summaryAddressY();
if ( !addr.isHistoryVector() && RiaPreferencesSummary::current()->appendHistoryVectors() )
@@ -2385,7 +2420,16 @@ RimSummaryPlot::CurveInfo RimSummaryPlot::handleAddressCollectionDrop( RimSummar
{
if ( curveDef.summaryCaseY()->summaryReader() && curveDef.summaryCaseY()->summaryReader()->hasAddress( curveDef.summaryAddressY() ) )
{
curves.push_back( addNewCurveY( curveDef.summaryAddressY(), curveDef.summaryCaseY() ) );
auto curve =
addNewCurve( curveDef.summaryAddressY(), curveDef.summaryCaseY(), curveDef.summaryAddressX(), curveDef.summaryCaseX() );
curves.push_back( curve );
if ( curveDef.summaryCaseX() )
{
curve->setAxisTypeX( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR );
curve->setSummaryCaseX( curveDef.summaryCaseX() );
curve->setSummaryAddressX( curveDef.summaryAddressX() );
findOrAssignPlotAxisX( curve );
}
newCurves++;
}
}
@@ -2470,7 +2514,7 @@ RimSummaryPlot::CurveInfo RimSummaryPlot::handleSummaryAddressDrop( RimSummaryAd
if ( !skipAddress )
{
curves.push_back( addNewCurveY( droppedAddress, summaryCase ) );
curves.push_back( addNewCurve( droppedAddress, summaryCase, RifEclipseSummaryAddress::timeAddress(), nullptr ) );
newCurves++;
}
}
@@ -2523,6 +2567,7 @@ void RimSummaryPlot::handleDroppedObjects( const std::vector<caf::PdmObjectHandl
applyDefaultCurveAppearances( curveInfo.curveSets );
loadDataAndUpdate();
zoomAll();
curvesChanged.send();
}
@@ -2533,11 +2578,24 @@ void RimSummaryPlot::handleDroppedObjects( const std::vector<caf::PdmObjectHandl
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCurve* RimSummaryPlot::addNewCurveY( const RifEclipseSummaryAddress& address, RimSummaryCase* summaryCase )
RimSummaryCurve* RimSummaryPlot::addNewCurve( const RifEclipseSummaryAddress& address,
RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& addressX,
RimSummaryCase* summaryCaseX )
{
auto* newCurve = new RimSummaryCurve();
newCurve->setSummaryCaseY( summaryCase );
newCurve->setSummaryAddressYAndApplyInterpolation( address );
// This address is RifEclipseSummaryAddress::time() if the curve is a time plot. Otherwise it is the address of the summary vector used
// for the x-axis
if ( addressX.category() != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_TIME )
{
newCurve->setAxisTypeX( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR );
newCurve->setSummaryAddressX( addressX );
newCurve->setSummaryCaseX( summaryCaseX );
}
addCurveNoUpdate( newCurve );
return newCurve;
@@ -2743,11 +2801,8 @@ void RimSummaryPlot::initAfterRead()
copyAxis( RiuPlotAxis::defaultLeft(), m_leftYAxisProperties_OBSOLETE.v() );
copyAxis( RiuPlotAxis::defaultRight(), m_rightYAxisProperties_OBSOLETE.v() );
if ( m_isCrossPlot )
copyAxis( RiuPlotAxis::defaultBottom(), m_bottomAxisProperties_OBSOLETE.v() );
else
copyAxis( RiuPlotAxis::defaultBottom(), m_timeAxisProperties_OBSOLETE.v() );
copyAxis( RiuPlotAxis::defaultBottomForSummaryVectors(), m_bottomAxisProperties_OBSOLETE.v() );
copyAxis( RiuPlotAxis::defaultBottom(), m_timeAxisProperties_OBSOLETE.v() );
}
for ( const auto& axisProperties : m_axisPropertiesArray )
@@ -2781,7 +2836,7 @@ void RimSummaryPlot::updateNameHelperWithCurveData( RimSummaryPlotNameHelper* na
if ( !nameHelper ) return;
nameHelper->clear();
std::vector<RifEclipseSummaryAddress> addresses;
std::vector<RiaSummaryCurveAddress> addresses;
std::vector<RimSummaryCase*> sumCases;
std::vector<RimSummaryCaseCollection*> ensembleCases;
@@ -2791,21 +2846,21 @@ void RimSummaryPlot::updateNameHelperWithCurveData( RimSummaryPlotNameHelper* na
{
if ( curve->summaryAddressY().isCalculated() )
{
RiaSummaryTools::getSummaryCasesAndAddressesForCalculation( curve->summaryAddressY().id(), sumCases, addresses );
std::vector<RifEclipseSummaryAddress> calcAddresses;
RiaSummaryTools::getSummaryCasesAndAddressesForCalculation( curve->summaryAddressY().id(), sumCases, calcAddresses );
for ( const auto& adr : calcAddresses )
{
addresses.push_back( RiaSummaryCurveAddress( adr ) );
}
}
else
{
addresses.push_back( curve->summaryAddressY() );
addresses.push_back( curve->curveAddress() );
sumCases.push_back( curve->summaryCaseY() );
if ( curve->summaryCaseX() )
{
sumCases.push_back( curve->summaryCaseX() );
if ( curve->summaryAddressX().category() != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID )
{
addresses.push_back( curve->summaryAddressX() );
}
}
}
}
@@ -2813,7 +2868,7 @@ void RimSummaryPlot::updateNameHelperWithCurveData( RimSummaryPlotNameHelper* na
for ( auto curveSet : m_ensembleCurveSetCollection->curveSets() )
{
addresses.push_back( curveSet->summaryAddress() );
addresses.push_back( curveSet->curveAddress() );
ensembleCases.push_back( curveSet->summaryCaseCollection() );
}
@@ -2970,6 +3025,13 @@ void RimSummaryPlot::onPlotItemSelected( std::shared_ptr<RiuPlotItem> plotItem,
//--------------------------------------------------------------------------------------------------
RimSummaryPlotSourceStepping* RimSummaryPlot::sourceSteppingObjectForKeyEventHandling() const
{
auto axisTypes = m_summaryCurveCollection->horizontalAxisTypes();
if ( axisTypes.contains( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ) )
{
return summaryCurveCollection()->sourceSteppingObject( RimSummaryDataSourceStepping::Axis::UNION_X_Y_AXIS );
}
return m_sourceStepping;
}
@@ -3041,7 +3103,10 @@ std::vector<RimPlotAxisProperties*> RimSummaryPlot::plotYAxes() const
for ( const auto& ap : m_axisPropertiesArray )
{
auto plotAxisProp = dynamic_cast<RimPlotAxisProperties*>( ap.p() );
if ( plotAxisProp ) axisProps.push_back( plotAxisProp );
if ( plotAxisProp && plotAxisProp->plotAxis().isVertical() )
{
axisProps.push_back( plotAxisProp );
}
}
return axisProps;
@@ -3051,6 +3116,21 @@ std::vector<RimPlotAxisProperties*> RimSummaryPlot::plotYAxes() const
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
{
assignXPlotAxis( destinationCurve );
assignYPlotAxis( destinationCurve );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
auto countAxes = []( const std::vector<RimPlotAxisPropertiesInterface*>& axes, RiaDefines::PlotAxis axis )
{ return std::count_if( axes.begin(), axes.end(), [axis]( const auto& ap ) { return ap->plotAxis().axis() == axis; } ); };
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::assignYPlotAxis( RimSummaryCurve* curve )
{
enum class AxisAssignmentStrategy
{
@@ -3063,14 +3143,14 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
auto strategy = AxisAssignmentStrategy::USE_MATCHING_UNIT;
auto destinationUnit = RiaStdStringTools::toUpper( destinationCurve->unitNameY() );
auto destinationUnit = RiaStdStringTools::toUpper( curve->unitNameY() );
if ( destinationUnit.empty() ) strategy = AxisAssignmentStrategy::USE_MATCHING_VECTOR;
auto anyCurveWithUnitText = [this, destinationCurve]
auto anyCurveWithUnitText = [this, curve]
{
for ( auto c : summaryCurves() )
{
if ( c == destinationCurve ) continue;
if ( c == curve ) continue;
if ( !c->unitNameY().empty() ) return true;
}
@@ -3086,11 +3166,11 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
for ( auto c : summaryCurves() )
{
if ( c == destinationCurve ) continue;
if ( c == curve ) continue;
if ( c->summaryAddressY().vectorName() == destinationCurve->summaryAddressY().vectorName() )
if ( c->summaryAddressY().vectorName() == curve->summaryAddressY().vectorName() )
{
destinationCurve->setLeftOrRightAxisY( c->axisY() );
curve->setLeftOrRightAxisY( c->axisY() );
return;
}
}
@@ -3102,7 +3182,7 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
for ( auto c : summaryCurves() )
{
if ( c == destinationCurve ) continue;
if ( c == curve ) continue;
if ( c->axisY() == RiuPlotAxis::defaultLeft() ) isLeftUsed = true;
if ( c->axisY() == RiuPlotAxis::defaultRight() ) isRightUsed = true;
@@ -3116,7 +3196,7 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
if ( axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_LEFT ||
axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_RIGHT )
{
destinationCurve->setLeftOrRightAxisY( c->axisY() );
curve->setLeftOrRightAxisY( c->axisY() );
return;
}
@@ -3126,13 +3206,13 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
if ( !isLeftUsed )
{
destinationCurve->setLeftOrRightAxisY( RiuPlotAxis::defaultLeft() );
curve->setLeftOrRightAxisY( RiuPlotAxis::defaultLeft() );
return;
}
if ( !isRightUsed )
{
destinationCurve->setLeftOrRightAxisY( RiuPlotAxis::defaultRight() );
curve->setLeftOrRightAxisY( RiuPlotAxis::defaultRight() );
return;
}
@@ -3143,15 +3223,8 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
if ( strategy == AxisAssignmentStrategy::ALTERNATING )
{
size_t axisCountLeft = 0;
size_t axisCountRight = 0;
for ( const auto& ap : m_axisPropertiesArray )
{
if ( ap->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_LEFT )
axisCountLeft++;
else if ( ap->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_RIGHT )
axisCountRight++;
}
size_t axisCountLeft = countAxes( m_axisPropertiesArray.childrenByType(), RiaDefines::PlotAxis::PLOT_AXIS_LEFT );
size_t axisCountRight = countAxes( m_axisPropertiesArray.childrenByType(), RiaDefines::PlotAxis::PLOT_AXIS_RIGHT );
if ( axisCountLeft > axisCountRight ) plotAxisType = RiaDefines::PlotAxis::PLOT_AXIS_RIGHT;
}
@@ -3168,14 +3241,141 @@ void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve )
if ( plotWidget() && plotWidget()->isMultiAxisSupported() )
{
QString axisObjectName = "New Axis";
if ( !destinationCurve->summaryAddressY().uiText().empty() )
axisObjectName = QString::fromStdString( destinationCurve->summaryAddressY().uiText() );
if ( !curve->summaryAddressY().uiText().empty() ) axisObjectName = QString::fromStdString( curve->summaryAddressY().uiText() );
newPlotAxis = plotWidget()->createNextPlotAxis( plotAxisType );
addNewAxisProperties( newPlotAxis, axisObjectName );
}
destinationCurve->setLeftOrRightAxisY( newPlotAxis );
curve->setLeftOrRightAxisY( newPlotAxis );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::assignXPlotAxis( RimSummaryCurve* curve )
{
RiuPlotAxis newPlotAxis = RimSummaryPlot::plotAxisForTime();
if ( curve->axisTypeX() == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR )
{
enum class AxisAssignmentStrategy
{
ALL_TOP,
ALL_BOTTOM,
ALTERNATING,
USE_MATCHING_UNIT,
USE_MATCHING_VECTOR
};
auto strategy = AxisAssignmentStrategy::USE_MATCHING_UNIT;
auto destinationUnit = RiaStdStringTools::toUpper( curve->unitNameX() );
if ( destinationUnit.empty() ) strategy = AxisAssignmentStrategy::USE_MATCHING_VECTOR;
auto anyCurveWithUnitText = [this, curve]
{
for ( auto c : summaryCurves() )
{
if ( c == curve ) continue;
if ( !c->unitNameX().empty() ) return true;
}
return false;
};
if ( !anyCurveWithUnitText() ) strategy = AxisAssignmentStrategy::USE_MATCHING_VECTOR;
if ( strategy == AxisAssignmentStrategy::USE_MATCHING_VECTOR )
{
// Special handling if curve unit is matching. Try to match on summary vector name to avoid creation of new axis
for ( auto c : summaryCurves() )
{
if ( c == curve ) continue;
if ( c->summaryAddressX().vectorName() == curve->summaryAddressX().vectorName() )
{
curve->setTopOrBottomAxisX( c->axisX() );
return;
}
}
}
else if ( strategy == AxisAssignmentStrategy::USE_MATCHING_UNIT )
{
bool isTopUsed = false;
bool isBottomUsed = false;
for ( auto c : summaryCurves() )
{
if ( c == curve ) continue;
if ( c->axisX() == RiuPlotAxis::defaultTop() ) isTopUsed = true;
if ( c->axisX() == RiuPlotAxis::defaultBottomForSummaryVectors() ) isBottomUsed = true;
auto currentUnit = RiaStdStringTools::toUpper( c->unitNameX() );
if ( currentUnit == destinationUnit )
{
for ( RimPlotAxisPropertiesInterface* axisProperties : m_axisPropertiesArray )
{
if ( axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_TOP ||
axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM )
{
curve->setTopOrBottomAxisX( c->axisX() );
return;
}
}
}
}
if ( !isTopUsed )
{
curve->setTopOrBottomAxisX( RiuPlotAxis::defaultTop() );
return;
}
if ( !isBottomUsed )
{
curve->setTopOrBottomAxisX( RiuPlotAxis::defaultBottomForSummaryVectors() );
return;
}
strategy = AxisAssignmentStrategy::ALTERNATING;
}
RiaDefines::PlotAxis plotAxisType = RiaDefines::PlotAxis::PLOT_AXIS_TOP;
if ( strategy == AxisAssignmentStrategy::ALTERNATING )
{
size_t axisCountTop = countAxes( m_axisPropertiesArray.childrenByType(), RiaDefines::PlotAxis::PLOT_AXIS_TOP );
size_t axisCountBot = countAxes( m_axisPropertiesArray.childrenByType(), RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM );
if ( axisCountTop > axisCountBot ) plotAxisType = RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM;
}
else if ( strategy == AxisAssignmentStrategy::ALL_TOP )
{
plotAxisType = RiaDefines::PlotAxis::PLOT_AXIS_TOP;
}
else if ( strategy == AxisAssignmentStrategy::ALL_BOTTOM )
{
plotAxisType = RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM;
}
RiuPlotAxis newPlotAxis = RiuPlotAxis::defaultBottomForSummaryVectors();
if ( plotWidget() && plotWidget()->isMultiAxisSupported() )
{
QString axisObjectName = "New Axis";
if ( !curve->summaryAddressX().uiText().empty() ) axisObjectName = QString::fromStdString( curve->summaryAddressX().uiText() );
newPlotAxis = plotWidget()->createNextPlotAxis( plotAxisType );
addNewAxisProperties( newPlotAxis, axisObjectName );
}
}
curve->setTopOrBottomAxisX( newPlotAxis );
}
//--------------------------------------------------------------------------------------------------

View File

@@ -86,7 +86,7 @@ public:
caf::Signal<bool> autoTitleChanged;
public:
RimSummaryPlot( bool isCrossPlot = false );
RimSummaryPlot();
~RimSummaryPlot() override;
void setDescription( const QString& description );
@@ -175,7 +175,7 @@ public:
void setNormalizationEnabled( bool enable );
bool isNormalizationEnabled();
virtual RimSummaryPlotSourceStepping* sourceSteppingObjectForKeyEventHandling() const;
RimSummaryPlotSourceStepping* sourceSteppingObjectForKeyEventHandling() const;
void setAutoScaleXEnabled( bool enabled ) override;
void setAutoScaleYEnabled( bool enabled ) override;
@@ -205,8 +205,8 @@ public:
std::vector<RimPlotAxisProperties*> plotYAxes() const;
RimPlotAxisPropertiesInterface* axisPropertiesForPlotAxis( RiuPlotAxis plotAxis ) const;
RimPlotAxisProperties* addNewAxisProperties( RiaDefines::PlotAxis, const QString& name );
RimPlotAxisProperties* addNewAxisProperties( RiaDefines::PlotAxis, const QString& name );
void findOrAssignPlotAxisX( RimSummaryCurve* curve );
std::vector<RimPlotCurve*> visibleCurvesForLegend() override;
@@ -296,9 +296,15 @@ private:
void timeAxisSettingsChanged( const caf::SignalEmitter* emitter );
void timeAxisSettingsChangedReloadRequired( const caf::SignalEmitter* emitter );
void ensureRequiredAxisObjectsForCurves();
void assignPlotAxis( RimSummaryCurve* curve );
void assignYPlotAxis( RimSummaryCurve* curve );
void assignXPlotAxis( RimSummaryCurve* curve );
RimSummaryCurve* addNewCurveY( const RifEclipseSummaryAddress& address, RimSummaryCase* summaryCase );
RimSummaryCurve* addNewCurve( const RifEclipseSummaryAddress& address,
RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& addressX,
RimSummaryCase* summaryCaseX );
RimEnsembleCurveSet* addNewEnsembleCurveY( const RifEclipseSummaryAddress& address, RimSummaryCaseCollection* ensemble );
void updateStackedCurveData();
@@ -314,6 +320,8 @@ private:
bool isOnlyWaterCutCurvesVisible( RiuPlotAxis plotAxis );
static RiuPlotAxis plotAxisForTime();
private:
#ifdef USE_QTCHARTS
caf::PdmField<bool> m_useQtChartsPlot;
@@ -341,8 +349,6 @@ private:
std::unique_ptr<RiuSummaryPlot> m_summaryPlot;
std::unique_ptr<QwtPlotTextLabel> m_plotInfoLabel;
bool m_isCrossPlot;
std::unique_ptr<RimSummaryPlotNameHelper> m_nameHelperAllCurves;
caf::PdmChildField<RimSummaryPlotSourceStepping*> m_sourceStepping;

View File

@@ -131,7 +131,7 @@ void RimSummaryPlotAxisFormatter::applyAxisPropertiesToPlot( RiuPlotWidget* plot
}
QString objectName = createAxisObjectName();
m_axisProperties->setNameAndAxis( objectName, axisTitle, axis.axis(), axis.index() );
m_axisProperties->setNameAndAxis( objectName + axisTitle, axisTitle, axis.axis(), axis.index() );
plotWidget->setAxisTitleText( axis, axisTitle );
bool titleBold = false;
@@ -254,7 +254,7 @@ QString RimSummaryPlotAxisFormatter::autoAxisTitle() const
RifEclipseSummaryAddress sumAddress;
std::string unitText;
if ( m_axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM )
if ( m_axisProperties->plotAxis().isHorizontal() )
{
sumAddress = rimCurve->summaryAddressX();
unitText = rimCurve->unitNameX();
@@ -264,23 +264,15 @@ QString RimSummaryPlotAxisFormatter::autoAxisTitle() const
sumAddress = rimCurve->summaryAddressY();
unitText = rimCurve->unitNameY();
}
else
{
continue;
}
addToUnitToQuantityMap( unitText, sumAddress );
}
for ( const RiaSummaryCurveDefinition& curveDef : m_curveDefinitions )
{
const RifEclipseSummaryAddress& sumAddress = curveDef.summaryAddressY();
std::string unitText;
if ( curveDef.summaryCaseY() && curveDef.summaryCaseY()->summaryReader() )
{
unitText = curveDef.summaryCaseY()->summaryReader()->unitName( sumAddress );
}
else if ( curveDef.ensemble() )
std::string unitText;
RifEclipseSummaryAddress sumAddress = curveDef.summaryAddressY();
if ( curveDef.ensemble() )
{
std::vector<RimSummaryCase*> sumCases = curveDef.ensemble()->allSummaryCases();
if ( !sumCases.empty() && sumCases[0] && sumCases[0]->summaryReader() )
@@ -288,6 +280,20 @@ QString RimSummaryPlotAxisFormatter::autoAxisTitle() const
unitText = sumCases[0]->summaryReader()->unitName( sumAddress );
}
}
else
{
RimSummaryCase* sumCase = curveDef.summaryCaseY();
if ( m_axisProperties->plotAxis().isHorizontal() )
{
sumCase = curveDef.summaryCaseX();
sumAddress = curveDef.summaryAddressX();
}
if ( sumCase && sumCase->summaryReader() )
{
unitText = sumCase->summaryReader()->unitName( sumAddress );
}
}
addToUnitToQuantityMap( unitText, sumAddress );
}
@@ -368,29 +374,26 @@ QString RimSummaryPlotAxisFormatter::createAxisObjectName() const
for ( RimSummaryCurve* rimCurve : m_summaryCurves )
{
RifEclipseSummaryAddress sumAddress;
if ( m_axisProperties->plotAxis().axis() == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM )
if ( rimCurve->axisY() == m_axisProperties->plotAxis() )
{
sumAddress = rimCurve->summaryAddressX();
addVectorNames( rimCurve->summaryAddressY() );
}
else if ( rimCurve->axisY() == m_axisProperties->plotAxis() )
else if ( rimCurve->axisX() == m_axisProperties->plotAxis() )
{
sumAddress = rimCurve->summaryAddressY();
addVectorNames( rimCurve->summaryAddressX() );
}
else
{
continue;
}
addVectorNames( sumAddress );
}
for ( const RiaSummaryCurveDefinition& curveDef : m_curveDefinitions )
{
const RifEclipseSummaryAddress& sumAddress = curveDef.summaryAddressY();
addVectorNames( sumAddress );
if ( m_axisProperties->plotAxis().isVertical() )
{
addVectorNames( curveDef.summaryAddressY() );
}
else
{
addVectorNames( curveDef.summaryAddressX() );
}
}
QString assembledAxisObjectName;

View File

@@ -48,7 +48,7 @@ void RimSummaryPlotNameHelper::clear()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotNameHelper::appendAddresses( const std::vector<RifEclipseSummaryAddress>& addresses )
void RimSummaryPlotNameHelper::appendAddresses( const std::vector<RiaSummaryCurveAddress>& addresses )
{
m_analyzer->appendAddresses( addresses );
@@ -102,10 +102,16 @@ QString RimSummaryPlotNameHelper::plotTitle() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryPlotNameHelper::isPlotDisplayingSingleVectorName() const
bool RimSummaryPlotNameHelper::isPlotDisplayingSingleCurve() const
{
if ( m_analyzer->quantities().size() == 2 )
{
if ( m_analyzer->onlyCrossPlotCurves() )
{
// We have cross plot curves, and two quantities. This means that we have one curve.
return true;
}
std::vector<std::string> strings;
for ( const auto& q : m_analyzer->quantities() )
strings.push_back( q );
@@ -113,6 +119,7 @@ bool RimSummaryPlotNameHelper::isPlotDisplayingSingleVectorName() const
auto first = RimObjectiveFunctionTools::nativeQuantityName( strings[0] );
auto second = RimObjectiveFunctionTools::nativeQuantityName( strings[1] );
// We have two quantities, one summary vector and one corresponding history vector.
if ( first == second ) return true;
}

View File

@@ -33,6 +33,7 @@ class RimSummaryCase;
class RimSummaryCaseCollection;
class RiaSummaryAddressAnalyzer;
class RifEclipseSummaryAddress;
class RiaSummaryCurveAddress;
//==================================================================================================
//
@@ -44,13 +45,13 @@ public:
void clear();
void appendAddresses( const std::vector<RifEclipseSummaryAddress>& addresses );
void appendAddresses( const std::vector<RiaSummaryCurveAddress>& addresses );
void setSummaryCases( const std::vector<RimSummaryCase*>& summaryCases );
void setEnsembleCases( const std::vector<RimSummaryCaseCollection*>& ensembleCases );
QString plotTitle() const override;
bool isPlotDisplayingSingleVectorName() const override;
bool isPlotDisplayingSingleCurve() const override;
bool isWellNameInTitle() const override;
bool isGroupNameInTitle() const override;
bool isNetworkInTitle() const override;