diff --git a/ApplicationLibCode/Application/CMakeLists_files.cmake b/ApplicationLibCode/Application/CMakeLists_files.cmake index d32c5e561f..ed89dbc257 100644 --- a/ApplicationLibCode/Application/CMakeLists_files.cmake +++ b/ApplicationLibCode/Application/CMakeLists_files.cmake @@ -34,6 +34,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaSummaryDefines.h ${CMAKE_CURRENT_LIST_DIR}/RiaLasDefines.h ${CMAKE_CURRENT_LIST_DIR}/RiaWellFlowDefines.h + ${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAddress.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -72,6 +73,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaSeismicDefines.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaLasDefines.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaWellFlowDefines.cpp + ${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAddress.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Application/RiaSummaryCurveAddress.cpp b/ApplicationLibCode/Application/RiaSummaryCurveAddress.cpp new file mode 100644 index 0000000000..aedcbf31b8 --- /dev/null +++ b/ApplicationLibCode/Application/RiaSummaryCurveAddress.cpp @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaSummaryCurveAddress.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaSummaryCurveAddress::RiaSummaryCurveAddress( const RifEclipseSummaryAddress& summaryAddressX, const RifEclipseSummaryAddress& summaryAddressY ) + : m_summaryAddressX( summaryAddressX ) + , m_summaryAddressY( summaryAddressY ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaSummaryCurveAddress::RiaSummaryCurveAddress( const RifEclipseSummaryAddress& summaryAddressY ) + : m_summaryAddressX( RifEclipseSummaryAddress::timeAddress() ) + , m_summaryAddressY( summaryAddressY ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RiaSummaryCurveAddress::summaryAddressX() const +{ + return m_summaryAddressX; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RiaSummaryCurveAddress::summaryAddressY() const +{ + return m_summaryAddressY; +} diff --git a/ApplicationLibCode/Application/RiaSummaryCurveAddress.h b/ApplicationLibCode/Application/RiaSummaryCurveAddress.h new file mode 100644 index 0000000000..fd13a97e78 --- /dev/null +++ b/ApplicationLibCode/Application/RiaSummaryCurveAddress.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RifEclipseSummaryAddress.h" + +//================================================================================================== +/// +//================================================================================================== +class RiaSummaryCurveAddress +{ +public: + explicit RiaSummaryCurveAddress( const RifEclipseSummaryAddress& summaryAddressY ); + explicit RiaSummaryCurveAddress( const RifEclipseSummaryAddress& summaryAddressX, const RifEclipseSummaryAddress& summaryAddressY ); + + RifEclipseSummaryAddress summaryAddressX() const; + RifEclipseSummaryAddress summaryAddressY() const; + + auto operator<=>( const RiaSummaryCurveAddress& rhs ) const = default; + +private: + RifEclipseSummaryAddress m_summaryAddressX; + RifEclipseSummaryAddress m_summaryAddressY; +}; diff --git a/ApplicationLibCode/Application/RiaSummaryDefines.cpp b/ApplicationLibCode/Application/RiaSummaryDefines.cpp index 7efa9c8293..ca10038193 100644 --- a/ApplicationLibCode/Application/RiaSummaryDefines.cpp +++ b/ApplicationLibCode/Application/RiaSummaryDefines.cpp @@ -17,6 +17,18 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaSummaryDefines.h" +#include "cafAppEnum.h" + +namespace caf +{ +template <> +void caf::AppEnum::setUp() +{ + addItem( RiaDefines::HorizontalAxisType::TIME, "TIME", "Time" ); + addItem( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR, "SUMMARY_VECTOR", "Summary Vector" ); + setDefault( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ); +} +} // namespace caf //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationLibCode/Application/RiaSummaryDefines.h b/ApplicationLibCode/Application/RiaSummaryDefines.h index 1559fee019..3429c423a3 100644 --- a/ApplicationLibCode/Application/RiaSummaryDefines.h +++ b/ApplicationLibCode/Application/RiaSummaryDefines.h @@ -29,6 +29,12 @@ enum class FileType STIMPLAN_SUMMARY }; +enum class HorizontalAxisType +{ + TIME, + SUMMARY_VECTOR +}; + QString summaryField(); QString summaryAquifer(); QString summaryNetwork(); diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.cpp b/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.cpp index 86f5b2725c..87de016cd8 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.cpp +++ b/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.cpp @@ -32,6 +32,7 @@ using namespace RifEclipseSummaryAddressDefines; /// //-------------------------------------------------------------------------------------------------- RiaSummaryAddressAnalyzer::RiaSummaryAddressAnalyzer() + : m_onlyCrossPlotCurves( false ) { } @@ -57,6 +58,23 @@ void RiaSummaryAddressAnalyzer::appendAddresses( const std::set& addresses ) +{ + // RiaSummaryCurveAddress can be used to represent cross plot curves. Set the flag m_onlyCrossPlotCurves to true, and this will be set + // to false in analyzeSingleAddress if we detect a time curve + + m_onlyCrossPlotCurves = true; + + for ( const auto& adr : addresses ) + { + analyzeSingleAddress( adr.summaryAddressX() ); + analyzeSingleAddress( adr.summaryAddressY() ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -100,6 +118,14 @@ bool RiaSummaryAddressAnalyzer::isSingleQuantityIgnoreHistory() const return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSummaryAddressAnalyzer::onlyCrossPlotCurves() const +{ + return m_onlyCrossPlotCurves; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -110,6 +136,20 @@ std::string RiaSummaryAddressAnalyzer::quantityNameForTitle() const return *quantities().begin(); } + if ( quantities().size() == 2 && m_onlyCrossPlotCurves ) + { + // We have a cross plot with only one curve + + std::string title; + for ( const auto& quantity : quantities() ) + { + if ( !title.empty() ) title += " | "; + title += quantity; + } + + return title; + } + if ( quantities().size() == 2 && quantityNamesWithHistory().size() == 1 ) { return *quantityNamesWithHistory().begin(); @@ -429,6 +469,14 @@ void RiaSummaryAddressAnalyzer::computeQuantityNamesWithHistory() const //-------------------------------------------------------------------------------------------------- void RiaSummaryAddressAnalyzer::analyzeSingleAddress( const RifEclipseSummaryAddress& address ) { + if ( address.category() == SummaryCategory::SUMMARY_TIME ) + { + m_onlyCrossPlotCurves = false; + + // A time address has no other information than SummaryCategory::SUMMARY_TIME + return; + } + const std::string& wellName = address.wellName(); if ( !wellName.empty() ) diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.h b/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.h index b9d116cd39..3b8d088389 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.h +++ b/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.h @@ -18,6 +18,7 @@ #pragma once +#include "RiaSummaryCurveAddress.h" #include "RifEclipseSummaryAddress.h" #include @@ -39,6 +40,7 @@ class RiaSummaryAddressAnalyzer void appendAddresses( const std::set& allAddresses ); void appendAddresses( const std::vector& allAddresses ); + void appendAddresses( const std::vector& addresses ); void clear(); @@ -48,6 +50,8 @@ class RiaSummaryAddressAnalyzer bool isSingleQuantityIgnoreHistory() const; + bool onlyCrossPlotCurves() const; + std::string quantityNameForTitle() const; std::set wellNames() const; @@ -104,4 +108,6 @@ class RiaSummaryAddressAnalyzer std::multimap m_aquifers; std::map> m_categories; + + bool m_onlyCrossPlotCurves; }; diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp index dddd1fb349..61efb76450 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp @@ -354,3 +354,26 @@ QList RiaSummaryTools::optionsForSummaryCases( const std return options; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaSummaryTools::copyCurveDataSources( RimSummaryCurve& curve, const RimSummaryCurve& otherCurve ) +{ + curve.setSummaryAddressX( otherCurve.summaryAddressX() ); + curve.setSummaryCaseX( otherCurve.summaryCaseX() ); + + curve.setSummaryAddressY( otherCurve.summaryAddressY() ); + curve.setSummaryCaseY( otherCurve.summaryCaseY() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaSummaryTools::copyCurveAxisData( RimSummaryCurve& curve, const RimSummaryCurve& otherCurve ) +{ + curve.setAxisTypeX( otherCurve.axisTypeX() ); + curve.setTopOrBottomAxisX( otherCurve.axisX() ); + + curve.setLeftOrRightAxisY( otherCurve.axisY() ); +} diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h index ebb46308a9..02571787cd 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h @@ -36,6 +36,7 @@ class RimSummaryCaseCollection; class RimSummaryTable; class RimSummaryTableCollection; class RimObservedDataCollection; +class RimSummaryCurve; class RifEclipseSummaryAddress; @@ -88,4 +89,7 @@ class RiaSummaryTools static QList optionsForAllSummaryCases(); static QList optionsForSummaryCases( const std::vector& cases ); + + static void copyCurveDataSources( RimSummaryCurve& curve, const RimSummaryCurve& otherCurve ); + static void copyCurveAxisData( RimSummaryCurve& curve, const RimSummaryCurve& otherCurve ); }; diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateDeclineCurvesFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateDeclineCurvesFeature.cpp index 10de3fc79d..3946d2d9fe 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateDeclineCurvesFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateDeclineCurvesFeature.cpp @@ -92,11 +92,7 @@ RimSummaryDeclineCurve* RicCreateDeclineCurvesFeature::createDeclineCurveAndAddT RimSummaryDeclineCurve* newCurve = new RimSummaryDeclineCurve(); CVF_ASSERT( newCurve ); - newCurve->setSummaryCaseX( sourceCurve->summaryCaseX() ); - newCurve->setSummaryAddressX( sourceCurve->summaryAddressX() ); - - newCurve->setSummaryCaseY( sourceCurve->summaryCaseY() ); - newCurve->setSummaryAddressY( sourceCurve->summaryAddressY() ); + RiaSummaryTools::copyCurveDataSources( *newCurve, *sourceCurve ); newCurve->setDeclineCurveType( declineCurveType ); @@ -105,6 +101,8 @@ RimSummaryDeclineCurve* RicCreateDeclineCurvesFeature::createDeclineCurveAndAddT summaryPlot->addCurveAndUpdate( newCurve ); + RiaSummaryTools::copyCurveAxisData( *newCurve, *sourceCurve ); + newCurve->updateDefaultValues(); newCurve->loadDataAndUpdate( true ); newCurve->updateConnectedEditors(); diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateRegressionAnalysisCurveFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateRegressionAnalysisCurveFeature.cpp index 9ad8b0a9d5..f2387228c1 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateRegressionAnalysisCurveFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicCreateRegressionAnalysisCurveFeature.cpp @@ -78,11 +78,7 @@ RimSummaryRegressionAnalysisCurve* RimSummaryRegressionAnalysisCurve* newCurve = new RimSummaryRegressionAnalysisCurve(); CVF_ASSERT( newCurve ); - newCurve->setSummaryCaseX( sourceCurve->summaryCaseX() ); - newCurve->setSummaryAddressX( sourceCurve->summaryAddressX() ); - - newCurve->setSummaryCaseY( sourceCurve->summaryCaseY() ); - newCurve->setSummaryAddressY( sourceCurve->summaryAddressY() ); + RiaSummaryTools::copyCurveDataSources( *newCurve, *sourceCurve ); newCurve->setColor( sourceCurve->color() ); newCurve->setSymbol( RiuPlotCurveSymbol::PointSymbolEnum::SYMBOL_RECT ); @@ -90,6 +86,8 @@ RimSummaryRegressionAnalysisCurve* summaryPlot->addCurveAndUpdate( newCurve ); + RiaSummaryTools::copyCurveAxisData( *newCurve, *sourceCurve ); + newCurve->updateDefaultValues(); newCurve->loadDataAndUpdate( true ); newCurve->updateConnectedEditors(); diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.cpp index 4f27eee0c3..dd16106175 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.cpp @@ -45,7 +45,7 @@ CAF_CMD_SOURCE_INIT( RicNewSummaryCrossPlotCurveFeature, "RicNewSummaryCrossPlot //-------------------------------------------------------------------------------------------------- bool RicNewSummaryCrossPlotCurveFeature::isCommandEnabled() const { - return ( selectedCrossPlot() ); + return ( selectedSummaryPlot() ); } //-------------------------------------------------------------------------------------------------- @@ -55,24 +55,29 @@ void RicNewSummaryCrossPlotCurveFeature::onActionTriggered( bool isChecked ) { RimProject* project = RimProject::current(); - RimSummaryCrossPlot* plot = selectedCrossPlot(); + auto plot = selectedSummaryPlot(); if ( plot ) { RimSummaryCurve* newCurve = new RimSummaryCurve(); cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable( plot->curveCount() ); newCurve->setColor( curveColor ); - plot->addCurveAndUpdate( newCurve ); - RimSummaryCase* defaultCase = nullptr; if ( project->activeOilField()->summaryCaseMainCollection()->summaryCaseCount() > 0 ) { defaultCase = project->activeOilField()->summaryCaseMainCollection()->summaryCase( 0 ); newCurve->setSummaryCaseY( defaultCase ); + newCurve->setSummaryAddressY( RifEclipseSummaryAddress::fieldAddress( "FOPT" ) ); - newCurve->loadDataAndUpdate( true ); + newCurve->setAxisTypeX( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ); + newCurve->setSummaryCaseX( defaultCase ); + newCurve->setSummaryAddressX( RifEclipseSummaryAddress::fieldAddress( "FGOR" ) ); } + plot->addCurveAndUpdate( newCurve ); + + newCurve->loadDataAndUpdate( true ); + plot->updateConnectedEditors(); RiuPlotMainWindowTools::onObjectAppended( newCurve ); @@ -91,15 +96,8 @@ void RicNewSummaryCrossPlotCurveFeature::setupActionLook( QAction* actionToSetup //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimSummaryCrossPlot* RicNewSummaryCrossPlotCurveFeature::selectedCrossPlot() const +RimSummaryPlot* RicNewSummaryCrossPlotCurveFeature::selectedSummaryPlot() const { - RimSummaryCrossPlot* crossPlot = nullptr; - caf::PdmObject* selObj = dynamic_cast( caf::SelectionManager::instance()->selectedItem() ); - if ( selObj ) - { - crossPlot = RiaSummaryTools::parentCrossPlot( selObj ); - } - - return crossPlot; + return RiaSummaryTools::parentSummaryPlot( selObj ); } diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h index c789c6286b..248b610c41 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h @@ -22,7 +22,7 @@ #include -class RimSummaryCrossPlot; +class RimSummaryPlot; //================================================================================================== /// @@ -37,5 +37,5 @@ class RicNewSummaryCrossPlotCurveFeature : public caf::CmdFeature void setupActionLook( QAction* actionToSetup ) override; private: - RimSummaryCrossPlot* selectedCrossPlot() const; + RimSummaryPlot* selectedSummaryPlot() const; }; diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp index 7060cd6cf4..a5ee881a28 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp @@ -371,7 +371,7 @@ void RicSummaryPlotEditorUi::syncPreviewCurvesFromUiSelection() for ( const auto& curve : currentCurvesInPreviewPlot ) { - currentCurveDefs.insert( curve->curveDefinitionY() ); + currentCurveDefs.insert( curve->curveDefinition() ); } { @@ -385,7 +385,7 @@ void RicSummaryPlotEditorUi::syncPreviewCurvesFromUiSelection() for ( const auto& curve : currentCurvesInPreviewPlot ) { - RiaSummaryCurveDefinition curveDef = curve->curveDefinitionY(); + RiaSummaryCurveDefinition curveDef = curve->curveDefinition(); if ( deleteCurveDefs.count( curveDef ) > 0 ) curvesToDelete.insert( curve ); } } @@ -630,7 +630,7 @@ void RicSummaryPlotEditorUi::populateCurveCreator( const RimSummaryPlot& sourceS for ( const auto& curve : sourceSummaryPlot.summaryCurves() ) { - curveDefs.push_back( curve->curveDefinitionY() ); + curveDefs.push_back( curve->curveDefinition() ); // Copy curve object to the preview plot copyCurveAndAddToPlot( curve, m_previewPlot.get(), true ); diff --git a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp index 92aa241fc4..4d1435b8e5 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp @@ -697,7 +697,7 @@ QString RimGridTimeHistoryCurve::geometrySelectionText() const //-------------------------------------------------------------------------------------------------- void RimGridTimeHistoryCurve::updateQwtPlotAxis() { - if ( m_plotCurve ) updateAxisInPlot( yAxis() ); + if ( m_plotCurve ) updateYAxisInPlot( yAxis() ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.cpp index e3999857f8..f66ceac04a 100644 --- a/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.cpp @@ -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(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.h b/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.h index 3dc02afb02..1ec6bccecd 100644 --- a/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.h +++ b/ApplicationLibCode/ProjectDataModel/RimMainPlotCollection.h @@ -112,7 +112,7 @@ class RimMainPlotCollection : public caf::PdmObject caf::PdmChildField m_rftPlotCollection; caf::PdmChildField m_pltPlotCollection; caf::PdmChildField m_summaryMultiPlotCollection; - caf::PdmChildField m_summaryCrossPlotCollection; + caf::PdmChildField m_summaryCrossPlotCollection_OBSOLETE; caf::PdmChildField m_summaryTableCollection; caf::PdmChildField m_analysisPlotCollection; caf::PdmChildField m_correlationPlotCollection; diff --git a/ApplicationLibCode/ProjectDataModel/RimPlotAxisProperties.cpp b/ApplicationLibCode/ProjectDataModel/RimPlotAxisProperties.cpp index 6aeb196346..f58c2ae03f 100644 --- a/ApplicationLibCode/ProjectDataModel/RimPlotAxisProperties.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimPlotAxisProperties.cpp @@ -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 RimPlotAxisProperties::calculateValueOptions( cons { options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() ); } - else if ( fieldNeedingOptions == &m_plotAxis ) - { - std::vector plotAxes = { RiaDefines::PlotAxis::PLOT_AXIS_LEFT, RiaDefines::PlotAxis::PLOT_AXIS_RIGHT }; - - for ( auto plotAxis : plotAxes ) - { - auto plotAxisEnum = caf::AppEnum( plotAxis ); - - QString uiText = plotAxisEnum.uiText(); - options.push_back( caf::PdmOptionItemInfo( uiText, plotAxisEnum.value() ) ); - } - } return options; } diff --git a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp index 74d25a588a..c2123a22ea 100644 --- a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp @@ -575,14 +575,6 @@ void RimPlotCurve::checkAndApplyDefaultFillColor() // } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimPlotCurve::isCrossPlotCurve() const -{ - return firstAncestorOrThisOfType() != nullptr; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -875,11 +867,19 @@ void RimPlotCurve::setSamplesFromXYErrorValues( const std::vector& 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 ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h index 1e43dc311c..1b2ecf1a40 100644 --- a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h +++ b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h @@ -115,7 +115,6 @@ class RimPlotCurve : public caf::PdmObject void setErrorBarsVisible( bool isVisible ); virtual void updateCurveAppearance(); - bool isCrossPlotCurve() const; virtual void updateUiIconFromPlotSymbol(); virtual bool hasParentPlot() const; @@ -186,7 +185,8 @@ class RimPlotCurve : public caf::PdmObject 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; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp index 650c74236a..80b811fdc7 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp @@ -197,7 +197,7 @@ void RimAsciiDataCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi //-------------------------------------------------------------------------------------------------- void RimAsciiDataCurve::updateQwtPlotAxis() { - if ( m_plotCurve ) updateAxisInPlot( yAxis() ); + if ( m_plotCurve ) updateYAxisInPlot( yAxis() ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp index 5d3955ad71..814057567c 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp @@ -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 RimEnsembleCurveSet::curveDefinitions() c std::vector 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(); - 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() ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h index c5a9072d35..75113758d5 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h @@ -24,6 +24,7 @@ #include "RiaDateTimeDefines.h" #include "RiaPlotDefines.h" +#include "RiaSummaryCurveAddress.h" #include "RimEnsembleCurveSetColorManager.h" #include "RimEnsembleCurveSetInterface.h" @@ -112,6 +113,7 @@ class RimEnsembleCurveSet : public caf::PdmObject, public RimEnsembleCurveSetInt void setSummaryAddress( RifEclipseSummaryAddress address ); void setSummaryAddressAndStatisticsFlag( RifEclipseSummaryAddress address ); RifEclipseSummaryAddress summaryAddress() const; + RiaSummaryCurveAddress curveAddress() const; std::vector curves() const; int ensembleId() const; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.cpp index 7286fb86f6..81c11540f6 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.cpp @@ -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 ""; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.h b/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.h index 56d6ed9581..62039afd7c 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimMultipleSummaryPlotNameHelper.h @@ -30,7 +30,7 @@ class RimMultiSummaryPlotNameHelper : public RimSummaryNameHelper QString plotTitle() const override; - bool isPlotDisplayingSingleVectorName() const override; + bool isPlotDisplayingSingleCurve() const override; bool isWellNameInTitle() const override; bool isGroupNameInTitle() const override; bool isNetworkInTitle() const override; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.cpp index 6abeb75401..64af8dfc8d 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.cpp @@ -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 ); -} diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.h index 480aaf0f39..3f1f456538 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCrossPlot.h @@ -30,6 +30,4 @@ class RimSummaryCrossPlot : public RimSummaryPlot public: RimSummaryCrossPlot(); - - RimSummaryPlotSourceStepping* sourceSteppingObjectForKeyEventHandling() const override; }; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 0b18783c82..8be1d14e73 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -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::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 +{ + 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 RiaSummaryCurveDefinition( summaryCaseY(), summaryAddressY(), isEnsembleCurve() ); + 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(); + 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 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& 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(); - m_plotAxisProperties = plot->axisPropertiesForPlotAxis( plotAxis ); + RimSummaryPlot* plot = firstAncestorOrThisOfTypeAsserted(); + 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 RimSummaryCurve::calculateValueOptions( const caf: { appendOptionItemsForSummaryAddresses( &options, m_xValuesSummaryCase() ); } - else if ( fieldNeedingOptions == &m_plotAxisProperties ) + else if ( fieldNeedingOptions == &m_yPlotAxisProperties ) { auto plot = firstAncestorOrThisOfTypeAsserted(); for ( auto axis : plot->plotAxes() ) { + // TODO: Should we allow time axis to be used as Y axis? if ( dynamic_cast( axis ) ) { options.push_back( caf::PdmOptionItemInfo( axis->objectName(), axis ) ); } } } + else if ( fieldNeedingOptions == &m_xPlotAxisProperties ) + { + auto plot = firstAncestorOrThisOfTypeAsserted(); + + 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 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(); - 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( QListtimeAxisProperties(); + } + 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 ) + { + updateYAxisInPlot( axisY() ); + plot->updateAxes(); + dataChanged.send(); + } + else if ( changedField == &m_xPlotAxisProperties ) { - updateAxisInPlot( axisY() ); + updateXAxisInPlot( axisX() ); plot->updateAxes(); dataChanged.send(); } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h index aa307204ca..aaa9ed95b9 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h @@ -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 @@ class RimSummaryCurve : public RimStackablePlotCurve 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 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 @@ class RimSummaryCurve : public RimStackablePlotCurve void setOverrideCurveDataY( const std::vector& xValues, const std::vector& yValues ); // X Axis functions - RiaSummaryCurveDefinition curveDefinitionX() const; - RimSummaryCase* summaryCaseX() const; - RifEclipseSummaryAddress summaryAddressX() const; - std::string unitNameX() const; - virtual std::vector valuesX() const; - - void setSummaryCaseX( RimSummaryCase* sumCase ); - void setSummaryAddressX( const RifEclipseSummaryAddress& address ); + void setAxisTypeX( RiaDefines::HorizontalAxisType axisType ); + RiaDefines::HorizontalAxisType axisTypeX() const; + RimSummaryCase* summaryCaseX() const; + RifEclipseSummaryAddress summaryAddressX() const; + std::string unitNameX() const; + virtual std::vector valuesX() const; + + void setSummaryCaseX( RimSummaryCase* sumCase ); + void setSummaryAddressX( const RifEclipseSummaryAddress& address ); + void setTopOrBottomAxisX( RiuPlotAxis plotAxis ); + RiuPlotAxis axisX() const; // Other bool isEnsembleCurve() const; @@ -133,23 +139,25 @@ class RimSummaryCurve : public RimStackablePlotCurve private: // Y values - caf::PdmPtrField m_yValuesSummaryCase; - caf::PdmChildField m_yValuesSummaryAddress; - caf::PdmField m_yValuesSummaryAddressUiField; - caf::PdmField m_yPushButtonSelectSummaryAddress; - - caf::PdmField m_resampling; + caf::PdmPtrField m_yValuesSummaryCase; + caf::PdmChildField m_yValuesSummaryAddress; + caf::PdmField m_yValuesSummaryAddressUiField; + caf::PdmField m_yPushButtonSelectSummaryAddress; + caf::PdmPtrField m_yPlotAxisProperties; + caf::PdmField m_yValuesResampling; // X values - caf::PdmPtrField m_xValuesSummaryCase; - caf::PdmChildField m_xValuesSummaryAddress; - caf::PdmField m_xValuesSummaryAddressUiField; - caf::PdmField m_xPushButtonSelectSummaryAddress; - + caf::PdmField> m_xAxisType; + caf::PdmPtrField m_xValuesSummaryCase; + caf::PdmChildField m_xValuesSummaryAddress; + caf::PdmField m_xValuesSummaryAddressUiField; + caf::PdmField m_xPushButtonSelectSummaryAddress; + caf::PdmPtrField m_xPlotAxisProperties; + + // Other fields caf::PdmField m_isEnsembleCurve; caf::PdmChildField m_curveNameConfig; caf::PdmField> m_plotAxis_OBSOLETE; - caf::PdmPtrField m_plotAxisProperties; caf::PdmField m_isTopZWithinCategory; }; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp index efce53cf2d..efd0dd1d30 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp @@ -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() ) diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h index baaacc7c31..9f114709dc 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h @@ -23,6 +23,7 @@ class RifEclipseSummaryAddress; class RimSummaryNameHelper; +class RiaSummaryCurveAddress; class RimSummaryCurveAutoName : public caf::PdmObject { @@ -31,18 +32,21 @@ class RimSummaryCurveAutoName : public caf::PdmObject public: RimSummaryCurveAutoName(); + QString curveName( const RiaSummaryCurveAddress& summaryCurveAddress, + const RimSummaryNameHelper* currentNameHelper, + const RimSummaryNameHelper* plotNameHelper ) const; + + void applySettings( const RimSummaryCurveAutoName& other ); + +private: 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 applySettings( const RimSummaryCurveAutoName& other ); - -private: - friend class RimSummaryCurve; - void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp index 987066a04b..28e11db03d 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp @@ -447,6 +447,21 @@ RimSummaryPlotSourceStepping* RimSummaryCurveCollection::sourceSteppingObject( R return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimSummaryCurveCollection::horizontalAxisTypes() const +{ + std::set axisTypes; + + for ( const auto& curve : m_curves ) + { + axisTypes.insert( curve->axisTypeX() ); + } + + return axisTypes; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h index a8956dcd5d..7203a7d7df 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h @@ -18,6 +18,7 @@ #pragma once +#include "RiaSummaryDefines.h" #include "RimSummaryPlotSourceStepping.h" #include "cafPdmChildArrayField.h" @@ -54,8 +55,9 @@ class RimSummaryCurveCollection : public caf::PdmObject RimSummaryPlotSourceStepping* sourceSteppingObject( RimSummaryDataSourceStepping::Axis sourceSteppingType ) const; - std::vector curves() const; - std::vector curvesForSourceStepping( RimSummaryDataSourceStepping::Axis steppingType ) const; + std::set horizontalAxisTypes() const; + std::vector curves() const; + std::vector curvesForSourceStepping( RimSummaryDataSourceStepping::Axis steppingType ) const; void setCurveAsTopZWithinCategory( RimSummaryCurve* curve ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp index 7726cfee0b..76b2ff488e 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp @@ -198,9 +198,9 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vectorsummaryCaseY()->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() }; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp index 9eb5c2ef5b..d3c5ceab67 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp @@ -374,19 +374,19 @@ void RimSummaryMultiPlot::populateNameHelper( RimSummaryPlotNameHelper* nameHelp { nameHelper->clear(); - std::vector addresses; + std::vector addresses; std::vector sumCases; std::vector 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(); - - auto tickMarkCount = ( columnCount() < 3 ) ? RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_DEFAULT - : RimPlotAxisProperties::LegendTickmarkCount::TICKMARK_FEW; + if ( auto timeAxisProp = p->timeAxisProperties() ) + { + 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() ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryNameHelper.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryNameHelper.h index b21d58416f..5759db3e6f 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryNameHelper.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryNameHelper.h @@ -38,15 +38,15 @@ class RimSummaryNameHelper 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 vectorNames() const = 0; virtual QString caseName() const = 0; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index c0bd834403..f7328aa823 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -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 RimSummaryPlot::allCurves( RimSummaryDataSourceSte //-------------------------------------------------------------------------------------------------- std::vector 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( 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 ); - } + plotWidget()->enableAxis( riuPlotAxis, true ); + } + else + { + plotWidget()->enableAxis( riuPlotAxis, false ); + } + + if ( !hasVisibleCurvesForAxis( riuPlotAxis ) ) + { + axisProps->setNameForUnusedAxis(); + } + else + { + std::set timeHistoryQuantities; - if ( !hasVisibleCurvesForAxis( riuPlotAxis ) ) + for ( auto c : visibleTimeHistoryCurvesForAxis( riuPlotAxis ) ) { - axisProps->setNameForUnusedAxis(); + timeHistoryQuantities.insert( c->quantityName() ); } - else - { - std::set timeHistoryQuantities; - for ( auto c : visibleTimeHistoryCurvesForAxis( riuPlotAxis ) ) + std::vector curveDefs; + for ( auto summaryCurve : summaryCurves() ) + { + if ( summaryCurve->axisY() == riuPlotAxis || summaryCurve->axisX() == riuPlotAxis ) { - timeHistoryQuantities.insert( c->quantityName() ); - } - - std::vector curveDefs; - for ( auto summaryCurve : summaryCurves() ) - { - if ( summaryCurve->axisY() != riuPlotAxis ) continue; - - curveDefs.push_back( summaryCurve->curveDefinitionY() ); + curveDefs.push_back( summaryCurve->curveDefinition() ); } + } - for ( auto curveSet : ensembleCurveSetCollection()->curveSets() ) - { - if ( curveSet->axisY() != riuPlotAxis ) continue; + for ( auto curveSet : ensembleCurveSetCollection()->curveSets() ) + { + if ( curveSet->axisY() != riuPlotAxis ) continue; - RiaSummaryCurveDefinition def( curveSet->summaryCaseCollection(), curveSet->summaryAddress() ); - curveDefs.push_back( def ); - } + RiaSummaryCurveDefinition def( curveSet->summaryCaseCollection(), curveSet->summaryAddress() ); + curveDefs.push_back( def ); + } - RimSummaryPlotAxisFormatter calc( axisProps, {}, curveDefs, visibleAsciiDataCurvesForAxis( riuPlotAxis ), timeHistoryQuantities ); + RimSummaryPlotAxisFormatter calc( axisProps, {}, curveDefs, visibleAsciiDataCurvesForAxis( riuPlotAxis ), timeHistoryQuantities ); - calc.applyAxisPropertiesToPlot( plotWidget() ); - } + 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; + + bool anyTimeHistoryCurvePresent = false; + { + if ( !visibleTimeHistoryCurvesForAxis( RimSummaryPlot::plotAxisForTime() ).empty() ) anyTimeHistoryCurvePresent = true; + if ( !visibleAsciiDataCurvesForAxis( RimSummaryPlot::plotAxisForTime() ).empty() ) anyTimeHistoryCurvePresent = true; + if ( !visibleSummaryCurvesForAxis( RimSummaryPlot::plotAxisForTime() ).empty() ) anyTimeHistoryCurvePresent = true; + } - if ( !timeAxisProperties->isActive() ) + if ( !anyTimeHistoryCurvePresent || !timeAxisProperties->isActive() ) { - plotWidget()->enableAxis( RiuPlotAxis::defaultBottom(), false ); + 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( std::ceil( ( maxValue - minValue ) / ticksInterval ) ); if ( numTicks > MAX_NUM_TICKS ) @@ -1198,54 +1187,108 @@ bool RimSummaryPlot::isOnlyWaterCutCurvesVisible( RiuPlotAxis plotAxis ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlot::scheduleReplotIfVisible() +RiuPlotAxis RimSummaryPlot::plotAxisForTime() { - if ( showWindow() && plotWidget() ) plotWidget()->scheduleReplot(); + return RiuPlotAxis::defaultBottom(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimSummaryPlot::visibleSummaryCurvesForAxis( RiuPlotAxis plotAxis ) const +void RimSummaryPlot::ensureRequiredAxisObjectsForCurves() { - std::vector curves; + // 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 ); + } - if ( plotAxis.axis() == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM ) + auto axisTypes = m_summaryCurveCollection->horizontalAxisTypes(); + if ( axisTypes.contains( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ) ) { - if ( m_summaryCurveCollection && m_summaryCurveCollection->isCurvesVisible() ) + 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 ) { - for ( RimSummaryCurve* curve : m_summaryCurveCollection->curves() ) + auto propertyAxis = dynamic_cast( axisProperties ); + if ( propertyAxis ) { - if ( curve->isChecked() ) - { - curves.push_back( curve ); - } + curve->setTopOrBottomAxisX( propertyAxis->plotAxis() ); + + return; } } } - else + + 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 ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::scheduleReplotIfVisible() +{ + if ( showWindow() && plotWidget() ) plotWidget()->scheduleReplot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimSummaryPlot::visibleSummaryCurvesForAxis( RiuPlotAxis plotAxis ) const +{ + std::vector curves; + + 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() && curve->axisY() == plotAxis ) - { - curves.push_back( curve ); - } + curves.push_back( curve ); } } + } - if ( m_ensembleCurveSetCollection && m_ensembleCurveSetCollection->isCurveSetsVisible() ) + if ( m_ensembleCurveSetCollection && m_ensembleCurveSetCollection->isCurveSetsVisible() ) + { + for ( RimEnsembleCurveSet* curveSet : m_ensembleCurveSetCollection->curveSets() ) { - for ( RimEnsembleCurveSet* curveSet : m_ensembleCurveSetCollection->curveSets() ) + for ( RimSummaryCurve* curve : curveSet->curves() ) { - for ( RimSummaryCurve* curve : curveSet->curves() ) + if ( curve->isChecked() && ( curve->axisY() == plotAxis || curve->axisX() == plotAxis ) ) { - if ( curve->isChecked() && curve->axisY() == plotAxis ) - { - curves.push_back( curve ); - } + curves.push_back( curve ); } } } @@ -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 curves; - - std::map> dataVectorMap; + std::map, std::set> 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 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( 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::vectorsetSummaryCaseY( 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 addresses; + std::vector addresses; std::vector sumCases; std::vector ensembleCases; @@ -2791,21 +2846,21 @@ void RimSummaryPlot::updateNameHelperWithCurveData( RimSummaryPlotNameHelper* na { if ( curve->summaryAddressY().isCalculated() ) { - RiaSummaryTools::getSummaryCasesAndAddressesForCalculation( curve->summaryAddressY().id(), sumCases, addresses ); + std::vector 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 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 RimSummaryPlot::plotYAxes() const for ( const auto& ap : m_axisPropertiesArray ) { auto plotAxisProp = dynamic_cast( 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 RimSummaryPlot::plotYAxes() const /// //-------------------------------------------------------------------------------------------------- void RimSummaryPlot::assignPlotAxis( RimSummaryCurve* destinationCurve ) +{ + assignXPlotAxis( destinationCurve ); + assignYPlotAxis( destinationCurve ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +auto countAxes = []( const std::vector& 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 ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h index e20f8a184f..007e127362 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h @@ -86,7 +86,7 @@ class RimSummaryPlot : public RimPlot, public RimSummaryDataSourceStepping caf::Signal autoTitleChanged; public: - RimSummaryPlot( bool isCrossPlot = false ); + RimSummaryPlot(); ~RimSummaryPlot() override; void setDescription( const QString& description ); @@ -175,7 +175,7 @@ class RimSummaryPlot : public RimPlot, public RimSummaryDataSourceStepping 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 @@ class RimSummaryPlot : public RimPlot, public RimSummaryDataSourceStepping std::vector 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 visibleCurvesForLegend() override; @@ -296,9 +296,15 @@ private slots: 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 slots: bool isOnlyWaterCutCurvesVisible( RiuPlotAxis plotAxis ); + static RiuPlotAxis plotAxisForTime(); + private: #ifdef USE_QTCHARTS caf::PdmField m_useQtChartsPlot; @@ -341,8 +349,6 @@ private slots: std::unique_ptr m_summaryPlot; std::unique_ptr m_plotInfoLabel; - bool m_isCrossPlot; - std::unique_ptr m_nameHelperAllCurves; caf::PdmChildField m_sourceStepping; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotAxisFormatter.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotAxisFormatter.cpp index 7a02ec5221..7901cfd200 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotAxisFormatter.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotAxisFormatter.cpp @@ -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 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() ) - { - sumAddress = rimCurve->summaryAddressY(); - } - else + else if ( rimCurve->axisX() == m_axisProperties->plotAxis() ) { - continue; + addVectorNames( rimCurve->summaryAddressX() ); } - - 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; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp index bd32597303..e51d143c72 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp @@ -48,7 +48,7 @@ void RimSummaryPlotNameHelper::clear() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlotNameHelper::appendAddresses( const std::vector& addresses ) +void RimSummaryPlotNameHelper::appendAddresses( const std::vector& 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 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; } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h index a872dc046c..a6fb2a42d7 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h @@ -33,6 +33,7 @@ class RimSummaryCase; class RimSummaryCaseCollection; class RiaSummaryAddressAnalyzer; class RifEclipseSummaryAddress; +class RiaSummaryCurveAddress; //================================================================================================== // @@ -44,13 +45,13 @@ class RimSummaryPlotNameHelper : public RimSummaryNameHelper void clear(); - void appendAddresses( const std::vector& addresses ); + void appendAddresses( const std::vector& addresses ); void setSummaryCases( const std::vector& summaryCases ); void setEnsembleCases( const std::vector& 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; diff --git a/ApplicationLibCode/UserInterface/RiuPlotAxis.cpp b/ApplicationLibCode/UserInterface/RiuPlotAxis.cpp index a95f54c55a..23531e3f2a 100644 --- a/ApplicationLibCode/UserInterface/RiuPlotAxis.cpp +++ b/ApplicationLibCode/UserInterface/RiuPlotAxis.cpp @@ -84,6 +84,15 @@ RiuPlotAxis RiuPlotAxis::defaultBottom() return RiuPlotAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuPlotAxis RiuPlotAxis::defaultBottomForSummaryVectors() +{ + // Time axis is using index 0, so we need to use index 1 for the bottom axis + return RiuPlotAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, 1 ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UserInterface/RiuPlotAxis.h b/ApplicationLibCode/UserInterface/RiuPlotAxis.h index bb2bc54c22..5588847d54 100644 --- a/ApplicationLibCode/UserInterface/RiuPlotAxis.h +++ b/ApplicationLibCode/UserInterface/RiuPlotAxis.h @@ -32,6 +32,7 @@ class RiuPlotAxis static RiuPlotAxis defaultRight(); static RiuPlotAxis defaultTop(); static RiuPlotAxis defaultBottom(); + static RiuPlotAxis defaultBottomForSummaryVectors(); RiaDefines::PlotAxis axis() const; diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp index c0d90f0c91..d80a1e58f9 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp @@ -349,7 +349,8 @@ void RiuQwtPlotWidget::setAxisRange( RiuPlotAxis axis, double min, double max ) //-------------------------------------------------------------------------------------------------- void RiuQwtPlotWidget::setAxisInverted( RiuPlotAxis axis, bool isInverted ) { - m_plot->axisScaleEngine( toQwtPlotAxis( axis ) )->setAttribute( QwtScaleEngine::Inverted, isInverted ); + auto scaleEngine = m_plot->axisScaleEngine( toQwtPlotAxis( axis ) ); + if ( scaleEngine ) scaleEngine->setAttribute( QwtScaleEngine::Inverted, isInverted ); } //--------------------------------------------------------------------------------------------------