From 83b4aa35a234bfa038c341116f61b8297fa4483e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 19 Oct 2026 09:40:46 +0200 Subject: [PATCH] #1136: Apply global curve appearance to summary plots and ensemble curve sets --- .../RicNewSummaryEnsembleCurveSetFeature.cpp | 3 + .../Summary/RimEnsembleCurveSet.cpp | 24 ++ .../Summary/RimEnsembleCurveSet.h | 12 +- .../Summary/RimSummaryCurve.cpp | 8 + .../RimSummaryCurveAppearanceCalculator.cpp | 125 ++--------- .../RimSummaryCurveAppearanceCalculator.h | 15 +- .../Summary/RimSummaryPlot.cpp | 205 ++++++++++++++++++ .../ProjectDataModel/Summary/RimSummaryPlot.h | 4 + .../Summary/RimSummaryPlotSourceStepping.cpp | 18 ++ 9 files changed, 283 insertions(+), 131 deletions(-) diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp index 133b77a62a..7daa56433a 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp @@ -112,6 +112,9 @@ RimEnsembleCurveSet* RicNewSummaryEnsembleCurveSetFeature::addCurveSet( RimSumma filter->setActive( false ); plot->ensembleCurveSetCollection()->addCurveSet( curveSet ); + + if ( plot->useGlobalCurveAppearance() ) plot->applyDefaultCurveAppearances( { curveSet } ); + return curveSet; } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp index 8b13986841..5754140c7d 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp @@ -32,6 +32,7 @@ #include "SummaryPlotCommands/RicSummaryPlotEditorUi.h" +#include "RimCurveStyleRules.h" #include "RimCustomObjectiveFunction.h" #include "RimCustomObjectiveFunctionCollection.h" #include "RimDeltaSummaryEnsemble.h" @@ -333,6 +334,23 @@ void RimEnsembleCurveSet::setColor( cvf::Color3f color ) computeRealizationColor(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::setColorAndUpdateCurves( cvf::Color3f color ) +{ + setColor( color ); + updateCurveColors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimEnsembleCurveSet::color() const +{ + return m_mainEnsembleColor(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1415,7 +1433,13 @@ void RimEnsembleCurveSet::appendColorGroup( caf::PdmUiOrdering& uiOrdering ) if ( m_colorMode() == RimEnsembleCurveSetColorManager::ColorMode::SINGLE_COLOR ) { + auto plot = firstAncestorOrThisOfType(); + const bool isColorGlobal = plot && plot->useGlobalCurveAppearance(); + m_mainEnsembleColor.uiCapability()->setUiReadOnly( isColorGlobal ); colorsGroup->add( &m_mainEnsembleColor ); + if ( isColorGlobal ) + RimCurveStyleRules::addGlobalAppearanceLink( *colorsGroup, + "The color is controlled by the global curve appearance." ); } else if ( m_colorMode == ColorMode::BY_ENSEMBLE_PARAM ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h index 1c1a53fafd..eec24c1c9e 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h @@ -99,11 +99,13 @@ public: QString name() const; - bool isCurvesVisible() const; - void setColor( cvf::Color3f color ); - void setStatisticsColor( const cvf::Color3f& color ); - void enableStatisticsLables( bool enable ); - QColor mainEnsembleColor() const; + bool isCurvesVisible() const; + void setColor( cvf::Color3f color ); + void setColorAndUpdateCurves( cvf::Color3f color ); + cvf::Color3f color() const; + void setStatisticsColor( const cvf::Color3f& color ); + void enableStatisticsLables( bool enable ); + QColor mainEnsembleColor() const; void loadDataAndUpdate( bool updateParentPlot ); void setParentPlotNoReplot( RiuPlotWidget* plot ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index cdd09962d8..f8d0c988c7 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -31,6 +31,7 @@ #include "Summary/RiaSummaryDefines.h" #include "Summary/RiaSummaryTools.h" +#include "RimCurveStyleRules.h" #include "RimEclipseResultCase.h" #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" @@ -893,7 +894,14 @@ void RimSummaryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering caf::PdmUiGroup* stackingGroup = uiOrdering.addNewGroup( "Stacking" ); RimStackablePlotCurve::stackingUiOrdering( *stackingGroup ); + const auto plot = firstAncestorOrThisOfType(); + const bool isAppearanceGlobal = plot && plot->useGlobalCurveAppearance() && firstAncestorOrThisOfType(); + m_curveAppearance->setUiLocked( isAppearanceGlobal ); + caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup( "Appearance" ); + if ( isAppearanceGlobal ) + RimCurveStyleRules::addGlobalAppearanceLink( *appearanceGroup, + "The appearance is controlled by the global curve appearance." ); RimPlotCurve::appearanceUiOrdering( *appearanceGroup ); caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "Curve Name" ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp index fc63704538..1d7072330a 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp @@ -22,37 +22,22 @@ #include "RiaColorTools.h" #include "RiaPreferencesSummary.h" #include "Summary/RiaSummaryCurveDefinition.h" +#include "Summary/RiaSummaryTools.h" #include "RiuQwtPlotCurve.h" +#include "RifSummaryReaderInterface.h" +#include "RimCurveStyleRules.h" #include "RimProject.h" #include "RimSummaryCase.h" #include "RimSummaryCurve.h" -#include "RifSummaryReaderInterface.h" - #include "cvfVector3.h" #include "cafAssert.h" #include -namespace caf -{ -template <> -void caf::AppEnum::setUp() -{ - addItem( RimSummaryCurveAppearanceCalculator::NONE, "NONE", "None" ); - addItem( RimSummaryCurveAppearanceCalculator::COLOR, "COLOR", "Color" ); - addItem( RimSummaryCurveAppearanceCalculator::SYMBOL, "SYMBOL", "Symbols" ); - addItem( RimSummaryCurveAppearanceCalculator::LINE_STYLE, "LINE_STYLE", "Line Style" ); - addItem( RimSummaryCurveAppearanceCalculator::GRADIENT, "GRADIENT", "Gradient" ); - addItem( RimSummaryCurveAppearanceCalculator::LINE_THICKNESS, "LINE_THICKNESS", "Line Thickness" ); - - setDefault( RimSummaryCurveAppearanceCalculator::NONE ); -} -} // namespace caf - namespace internal { //-------------------------------------------------------------------------------------------------- @@ -99,32 +84,6 @@ RimSummaryCurveAppearanceCalculator::RimSummaryCurveAppearanceCalculator( const init( curveDefVector ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimSummaryCurveAppearanceCalculator::assignDimensions( CurveAppearanceType caseAppearance, - CurveAppearanceType variAppearance, - CurveAppearanceType wellAppearance, - CurveAppearanceType gropAppearance, - CurveAppearanceType regiAppearance ) -{ - m_caseAppearanceType = caseAppearance; - m_varAppearanceType = variAppearance; - m_wellAppearanceType = wellAppearance; - m_groupAppearanceType = gropAppearance; - m_regionAppearanceType = regiAppearance; - - // Update the dimensionCount - m_dimensionCount = 0; - if ( m_caseAppearanceType != NONE ) ++m_dimensionCount; - if ( m_varAppearanceType != NONE ) ++m_dimensionCount; - if ( m_wellAppearanceType != NONE ) ++m_dimensionCount; - if ( m_groupAppearanceType != NONE ) ++m_dimensionCount; - if ( m_regionAppearanceType != NONE ) ++m_dimensionCount; - - updateApperanceIndices(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -259,22 +218,6 @@ std::map RimSummaryCurveAppearanceCalculator::mapNameToAppe return nameToIndex; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimSummaryCurveAppearanceCalculator::getDimensions( CurveAppearanceType* caseAppearance, - CurveAppearanceType* variAppearance, - CurveAppearanceType* wellAppearance, - CurveAppearanceType* gropAppearance, - CurveAppearanceType* regiAppearance ) const -{ - *caseAppearance = m_caseAppearanceType; - *variAppearance = m_varAppearanceType; - *wellAppearance = m_wellAppearanceType; - *gropAppearance = m_groupAppearanceType; - *regiAppearance = m_regionAppearanceType; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -425,8 +368,8 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::computeTintedCurveColorForAddr //-------------------------------------------------------------------------------------------------- void RimSummaryCurveAppearanceCalculator::init( const std::vector& curveDefinitions ) { - m_allSummaryCaseNames = getAllSummaryCaseNames(); - m_allSummaryWellNames = getAllSummaryWellNames(); + m_allSummaryCaseNames = RiaSummaryTools::allSummaryCaseNames(); + m_allSummaryWellNames = RiaSummaryTools::allSummaryWellNames(); for ( const RiaSummaryCurveDefinition& curveDef : curveDefinitions ) { @@ -549,6 +492,14 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledPaletteColor( int colorI { if ( colorIndex < 0 ) return cvf::Color3f::BLACK; + if ( auto project = RimProject::current() ) + { + if ( auto overrides = project->curveStyleRules() ) + { + if ( auto legendColor = overrides->autoLegendColor( colorIndex ) ) return *legendColor; + } + } + return RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f( colorIndex ); } @@ -661,53 +612,3 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::gradeColor( const cvf::Color3f return cvf::Color3f( newColor[0], newColor[1], newColor[2] ); } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::set RimSummaryCurveAppearanceCalculator::getAllSummaryCaseNames() -{ - std::set summaryCaseHashes; - RimProject* proj = RimProject::current(); - - std::vector cases = proj->allSummaryCases(); - for ( RimSummaryCase* rimCase : cases ) - { - summaryCaseHashes.insert( rimCase->summaryHeaderFilename().toUtf8().constData() ); - } - - return summaryCaseHashes; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::set RimSummaryCurveAppearanceCalculator::getAllSummaryWellNames() -{ - std::set summaryWellNames; - RimProject* proj = RimProject::current(); - - std::vector cases = proj->allSummaryCases(); - for ( RimSummaryCase* rimCase : cases ) - { - RifSummaryReaderInterface* reader = nullptr; - if ( rimCase ) - { - reader = rimCase->summaryReader(); - } - - if ( reader ) - { - const std::set allAddresses = reader->allResultAddresses(); - - for ( auto& address : allAddresses ) - { - if ( address.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL ) - { - summaryWellNames.insert( address.wellName() ); - } - } - } - } - return summaryWellNames; -} diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h index 4b98a2f795..5af2f0a214 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h @@ -36,6 +36,7 @@ class RimSummaryCurveAppearanceCalculator public: explicit RimSummaryCurveAppearanceCalculator( const std::set& curveDefinitions ); explicit RimSummaryCurveAppearanceCalculator( const std::vector& curveDefinitions ); + enum CurveAppearanceType { NONE, @@ -46,17 +47,6 @@ public: LINE_THICKNESS }; - void assignDimensions( CurveAppearanceType caseAppearance, - CurveAppearanceType variAppearance, - CurveAppearanceType wellAppearance, - CurveAppearanceType gropAppearance, - CurveAppearanceType regiAppearance ); - void getDimensions( CurveAppearanceType* caseAppearance, - CurveAppearanceType* variAppearance, - CurveAppearanceType* wellAppearance, - CurveAppearanceType* gropAppearance, - CurveAppearanceType* regiAppearance ) const; - void setupCurveLook( RimSummaryCurve* curve ); static cvf::Color3f assignColorByPhase( const RifEclipseSummaryAddress& address ); @@ -82,9 +72,6 @@ private: cvf::Color3f gradeColor( const cvf::Color3f& color, float factor ); void assignColorByPhase( RimSummaryCurve* curve, int colorIndex ); - static std::set getAllSummaryCaseNames(); - static std::set getAllSummaryWellNames(); - cvf::Color3f m_currentCurveBaseColor; float m_currentCurveGradient; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index a57c121a5b..56f05c3c95 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -35,6 +35,9 @@ #include "Annotations/RimTimeAxisAnnotationUpdater.h" #include "RimAsciiDataCurve.h" +#include "RimCurveStyleRule.h" +#include "RimCurveStyleRules.h" +#include "RimCurveStyleSettings.h" #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" #include "RimGridTimeHistoryCurve.h" @@ -776,12 +779,163 @@ void RimSummaryPlot::applyDefaultCurveAppearances() applyDefaultCurveAppearances( ensembleCurveSetCollection()->curveSets() ); } +namespace +{ +//-------------------------------------------------------------------------------------------------- +/// Project-stored custom rules for specific items of the dimensions selected for color or symbol. Later rules win. +//-------------------------------------------------------------------------------------------------- +std::vector rulesForCurve( RimSummaryCurve* curve ) +{ + auto project = RimProject::current(); + if ( !project || !project->curveStyleRules() ) return {}; + + return project->curveStyleRules()->rulesFor( curve->summaryAddressY(), RimCurveStyleSettings::caseName( curve->summaryCaseY() ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// Custom color for an ensemble curve set, if any. Later matching rules win. +//-------------------------------------------------------------------------------------------------- +std::optional overriddenEnsembleColor( RimEnsembleCurveSet* curveSet ) +{ + auto project = RimProject::current(); + if ( !project || !project->curveStyleRules() ) return std::nullopt; + + const std::string caseName = curveSet->summaryEnsemble() ? curveSet->summaryEnsemble()->name().toStdString() : std::string(); + + const auto colorDimension = project->curveStyleRules()->settings()->colorDimension(); + + std::optional color; + for ( auto rule : project->curveStyleRules()->rulesFor( curveSet->summaryAddressY(), caseName ) ) + { + if ( rule->dimension() != colorDimension ) continue; + if ( auto overridden = rule->overriddenColor() ) color = overridden; + } + + return color; +} + +//-------------------------------------------------------------------------------------------------- +/// Maps the values of a dimension to indices used to pick palette colors and symbols. Cases and wells are +/// indexed among all items in the project to give the same item the same look in every plot, all other +/// dimensions among the values present in the plot. +//-------------------------------------------------------------------------------------------------- +class DimensionIndexer +{ +public: + using Settings = RimCurveStyleSettings; + + DimensionIndexer( Settings::Dimension dimension, const std::set& curveDefs ) + : m_dimension( dimension ) + { + if ( dimension == Settings::Dimension::NONE ) return; + + std::set values; + if ( dimension == Settings::Dimension::CASE || dimension == Settings::Dimension::WELL ) + { + for ( const auto& name : RimCurveStyleRule::availableNames( dimension ) ) + { + m_universe.push_back( name.toStdString() ); + } + } + else + { + for ( const auto& curveDef : curveDefs ) + { + auto value = Settings::dimensionValue( dimension, curveDef.summaryAddressY(), caseName( curveDef ) ); + if ( !value.empty() ) values.insert( value ); + } + m_universe.assign( values.begin(), values.end() ); + } + } + + static std::string caseName( RimSummaryCase* summaryCase ) { return Settings::caseName( summaryCase ); } + + static std::string caseName( const RiaSummaryCurveDefinition& curveDef ) + { + if ( curveDef.summaryCaseY() ) return caseName( curveDef.summaryCaseY() ); + return curveDef.ensemble() ? curveDef.ensemble()->name().toStdString() : std::string(); + } + + // -1 if the dimension has no value for the address + int index( const RifEclipseSummaryAddress& address, const std::string& caseName ) const + { + if ( m_dimension == Settings::Dimension::NONE ) return -1; + + const auto value = Settings::dimensionValue( m_dimension, address, caseName ); + const auto it = std::find( m_universe.begin(), m_universe.end(), value ); + return it == m_universe.end() ? -1 : static_cast( std::distance( m_universe.begin(), it ) ); + } + + Settings::Dimension dimension() const { return m_dimension; } + +private: + Settings::Dimension m_dimension; + std::vector m_universe; +}; + +//-------------------------------------------------------------------------------------------------- +/// Color from the global appearance. Vectors can be colored by phase. +//-------------------------------------------------------------------------------------------------- +std::optional globalColor( const DimensionIndexer& indexer, const RifEclipseSummaryAddress& address, const std::string& caseName ) +{ + if ( indexer.dimension() == RimCurveStyleSettings::Dimension::NONE ) return std::nullopt; + + if ( indexer.dimension() == RimCurveStyleSettings::Dimension::VECTOR && RiaPreferencesSummary::current()->colorCurvesByPhase() ) + { + return RimSummaryCurveAppearanceCalculator::assignColorByPhase( address ); + } + + const int index = indexer.index( address, caseName ); + if ( index < 0 ) return std::nullopt; + + return RimSummaryCurveAppearanceCalculator::cycledPaletteColor( index ); +} +} // namespace + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimSummaryPlot::applyDefaultCurveAppearances( std::vector curvesToUpdate ) { std::set allCurveDefs = summaryAndEnsembleCurveDefinitions(); + + const RimCurveStyleSettings* settings = nullptr; + if ( useGlobalCurveAppearance() ) + { + settings = RimProject::current()->curveStyleRules()->settings(); + + // Indices depend on all curves in the plot, so all curves must be updated to stay consistent + curvesToUpdate = summaryCurves(); + } + + if ( settings ) + { + const DimensionIndexer colorIndexer( settings->colorDimension(), allCurveDefs ); + const DimensionIndexer symbolIndexer( settings->symbolDimension(), allCurveDefs ); + + for ( auto& curve : curvesToUpdate ) + { + curve->resetAppearance(); + + const auto address = curve->summaryAddressY(); + const auto caseName = DimensionIndexer::caseName( curve->summaryCaseY() ); + + if ( auto color = globalColor( colorIndexer, address, caseName ) ) curve->setColor( *color ); + + const int symbolIndex = symbolIndexer.index( address, caseName ); + if ( symbolIndex >= 0 ) curve->setSymbol( RimSummaryCurveAppearanceCalculator::cycledSymbol( symbolIndex ) ); + + curve->setCurveAppearanceFromCaseType(); + + for ( auto rule : rulesForCurve( curve ) ) + { + rule->applyToCurve( curve, rule->dimension() == settings->colorDimension(), rule->dimension() == settings->symbolDimension() ); + } + } + + return; + } + RimSummaryCurveAppearanceCalculator curveLookCalc( allCurveDefs ); for ( auto& curve : curvesToUpdate ) @@ -791,11 +945,45 @@ void RimSummaryPlot::applyDefaultCurveAppearances( std::vector } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimSummaryPlot::useGlobalCurveAppearance() const +{ + auto project = RimProject::current(); + if ( !project || !project->curveStyleRules() ) return false; + + return project->curveStyleRules()->useGlobalAppearance(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::updateCurveAppearanceFromGlobalSettings() +{ + if ( !useGlobalCurveAppearance() ) return; + + applyDefaultCurveAppearances( summaryCurves() ); + applyDefaultCurveAppearances( ensembleCurveSetCollection()->curveSets() ); + + updateConnectedEditors(); + loadDataAndUpdate(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimSummaryPlot::applyDefaultCurveAppearances( std::vector ensembleCurvesToUpdate ) { + // Indices depend on all curve sets in the plot, so all must be updated to stay consistent + std::optional globalColorIndexer; + if ( useGlobalCurveAppearance() ) + { + ensembleCurvesToUpdate = ensembleCurveSetCollection()->curveSets(); + globalColorIndexer.emplace( RimProject::current()->curveStyleRules()->settings()->colorDimension(), + summaryAndEnsembleCurveDefinitions() ); + } + std::vector usedColors; for ( auto c : ensembleCurveSetCollection()->curveSets() ) { @@ -820,7 +1008,24 @@ void RimSummaryPlot::applyDefaultCurveAppearances( std::vectorcolorMode() ) ) { + if ( globalColorIndexer ) + { + if ( auto overrideColor = overriddenEnsembleColor( curveSet ) ) + { + curveSet->setColorAndUpdateCurves( *overrideColor ); + continue; + } + + const auto caseName = curveSet->summaryEnsemble() ? curveSet->summaryEnsemble()->name().toStdString() : std::string(); + if ( auto color = globalColor( *globalColorIndexer, adr, caseName ) ) + { + curveSet->setColorAndUpdateCurves( *color ); + continue; + } + } + std::vector candidateColors; + if ( RiaPreferencesSummary::current()->colorCurvesByPhase() ) { // Put the the phase color as first candidate, will then be used if there is only one ensemble in the plot diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h index 803a0c8254..4a0c13fd01 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h @@ -36,6 +36,7 @@ #include +#include #include #include #include @@ -66,6 +67,7 @@ class RiaSummaryCurveDefinition; class RifEclipseSummaryAddress; class RiaSummaryCurveAddress; class RimStackablePlotCurve; +class RimPlotCurve; class QwtInterval; class QwtPlotCurve; @@ -187,6 +189,8 @@ public: void applyDefaultCurveAppearances(); void applyDefaultCurveAppearances( std::vector curvesToUpdate ); void applyDefaultCurveAppearances( std::vector ensembleCurvesToUpdate ); + bool useGlobalCurveAppearance() const; + void updateCurveAppearanceFromGlobalSettings(); void setNormalizationEnabled( bool enable ); bool isNormalizationEnabled(); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp index 680aeec838..1e063aa8b1 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp @@ -549,6 +549,24 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi( const caf::PdmFieldHandle* if ( triggerLoadDataAndUpdate ) { + // Plots using global curve appearance must be restyled after the stepped addresses and cases are updated + std::set plotsToRestyle; + for ( auto curve : curves ) + { + if ( auto plot = curve->firstAncestorOfType() ) plotsToRestyle.insert( plot ); + } + if ( dataSourceSteppingObject() ) + { + for ( auto curveSet : dataSourceSteppingObject()->curveSets() ) + { + if ( auto plot = curveSet->firstAncestorOfType() ) plotsToRestyle.insert( plot ); + } + } + for ( auto plot : plotsToRestyle ) + { + plot->updateCurveAppearanceFromGlobalSettings(); + } + RimSummaryMultiPlot* summaryMultiPlot = dynamic_cast( m_objectForSourceStepping.p() ); if ( summaryMultiPlot ) {