diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp index eef1eb2a7d..5747c996c0 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp @@ -1703,6 +1703,7 @@ void RimEnsembleCurveSet::updateEnsembleCurves( const std::vectorsetSummaryCaseY( sumCase ); curve->setSummaryAddressYAndApplyInterpolation( addr->address() ); curve->setResampling( m_resampling() ); + curve->setLineThickness( 1 ); addCurve( curve ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp index 07762d8f55..4dd261cb3e 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp @@ -362,6 +362,31 @@ void RimSummaryCurveAppearanceCalculator::assignColorByPhase( RimSummaryCurve* c } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimSummaryCurveAppearanceCalculator::assignColorByPhase( const RifEclipseSummaryAddress& address ) +{ + char secondChar = 0; + std::string vectorName = address.vectorName(); + + if ( vectorName.size() > 1 ) + { + secondChar = vectorName[1]; + if ( !isExcplicitHandled( secondChar ) ) + { + secondChar = 0; // Consider all others as one group for coloring + } + } + + if ( secondChar == 'W' ) return cycledBlueColor( 0 ); + if ( secondChar == 'O' ) return cycledGreenColor( 0 ); + if ( secondChar == 'G' ) return cycledRedColor( 0 ); + if ( secondChar == 'V' ) return cycledBrownColor( 0 ); + + return cycledNoneRGBBrColor( 0 ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h index 66706df477..a50b85ee35 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h @@ -60,6 +60,8 @@ public: void setupCurveLook( RimSummaryCurve* curve ); + static cvf::Color3f assignColorByPhase( const RifEclipseSummaryAddress& address ); + void assignColorByPhase( RimSummaryCurve* curve, int colorIndex ); static cvf::Color3f cycledPaletteColor( int colorIndex ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index 16c07bbaea..e1b5110ac6 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -19,6 +19,7 @@ #include "RimSummaryPlot.h" #include "RiaColorTables.h" +#include "RiaColorTools.h" #include "RiaDefines.h" #include "RiaFieldHandleTools.h" #include "RiaPlotDefines.h" @@ -30,6 +31,7 @@ #include "RiaSummaryCurveDefinition.h" #include "RiaSummaryTools.h" #include "RiaTimeHistoryCurveResampler.h" + #include "RifReaderEclipseSummary.h" #include "RicfCommandObject.h" @@ -763,7 +765,20 @@ void RimSummaryPlot::applyDefaultCurveAppearances() for ( auto& curveSet : this->ensembleCurveSetCollection()->curveSets() ) { if ( curveSet->colorMode() != RimEnsembleCurveSet::ColorMode::SINGLE_COLOR ) continue; - curveSet->setColor( RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f( colorIndex++ ) ); + + cvf::Color3f curveColor; + if ( RiaPreferencesSummary::current()->colorCurvesByPhase() ) + { + auto basePhaseColor = RimSummaryCurveAppearanceCalculator::assignColorByPhase( curveSet->summaryAddress() ); + + curveColor = RiaColorTools::blendCvfColors( basePhaseColor, cvf::Color3f::WHITE, 1, 3 ); + } + else + { + curveColor = RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f( colorIndex++ ); + } + + curveSet->setColor( curveColor ); } } @@ -1942,7 +1957,11 @@ std::pair> RimSummaryPlot::handleSummaryCaseD { auto historyAddr = addr; historyAddr.setVectorName( addr.vectorName() + RifReaderEclipseSummary::historyIdentifier() ); - dataVectorMap[historyAddr].insert( curve->summaryCaseY() ); + + if ( summaryCase->summaryReader() && summaryCase->summaryReader()->hasAddress( historyAddr ) ) + { + dataVectorMap[historyAddr].insert( curve->summaryCaseY() ); + } } } @@ -2044,13 +2063,21 @@ std::pair> if ( curveDef.ensemble() ) { - addNewEnsembleCurveY( curveDef.summaryAddress(), curveDef.ensemble() ); - newCurves++; + auto addresses = curveDef.ensemble()->ensembleSummaryAddresses(); + if ( addresses.find( curveDef.summaryAddress() ) != addresses.end() ) + { + addNewEnsembleCurveY( curveDef.summaryAddress(), curveDef.ensemble() ); + newCurves++; + } } else if ( curveDef.summaryCase() ) { - curves.push_back( addNewCurveY( curveDef.summaryAddress(), curveDef.summaryCase() ) ); - newCurves++; + if ( curveDef.summaryCase()->summaryReader() && + curveDef.summaryCase()->summaryReader()->hasAddress( curveDef.summaryAddress() ) ) + { + curves.push_back( addNewCurveY( curveDef.summaryAddress(), curveDef.summaryCase() ) ); + newCurves++; + } } } @@ -2089,8 +2116,10 @@ std::pair> RimSummaryPlot::handleSummaryAddre { for ( const auto& droppedAddress : newCurveAddresses ) { - bool skipAddress = false; + auto addresses = ensemble->ensembleSummaryAddresses(); + if ( addresses.find( droppedAddress ) == addresses.end() ) continue; + bool skipAddress = false; if ( dataVectorMap.count( droppedAddress ) > 0 ) { skipAddress = ( dataVectorMap[droppedAddress].count( ensemble ) > 0 ); @@ -2119,6 +2148,9 @@ std::pair> RimSummaryPlot::handleSummaryAddre { for ( const auto& droppedAddress : newCurveAddresses ) { + if ( !summaryCase->summaryReader() || !summaryCase->summaryReader()->hasAddress( droppedAddress ) ) + continue; + bool skipAddress = false; if ( dataVectorMap.count( droppedAddress ) > 0 ) @@ -2192,14 +2224,6 @@ void RimSummaryPlot::handleDroppedObjects( const std::vectorensembleCurveSetCollection()->curveSets() ) - { - if ( curveSet->colorMode() != RimEnsembleCurveSet::ColorMode::SINGLE_COLOR ) continue; - curveSet->setColor( RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f( colorIndex++ ) ); - } - loadDataAndUpdate(); curvesChanged.send(); @@ -2230,6 +2254,21 @@ void RimSummaryPlot::addNewEnsembleCurveY( const RifEclipseSummaryAddress& addre curveSet->setSummaryCaseCollection( ensemble ); curveSet->setSummaryAddress( address ); + + cvf::Color3f curveColor; + if ( RiaPreferencesSummary::current()->colorCurvesByPhase() ) + { + auto basePhaseColor = RimSummaryCurveAppearanceCalculator::assignColorByPhase( curveSet->summaryAddress() ); + + curveColor = RiaColorTools::blendCvfColors( basePhaseColor, cvf::Color3f::WHITE, 1, 3 ); + } + else + { + curveColor = RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f( + ensembleCurveSetCollection()->curveSetCount() ); + } + curveSet->setColor( curveColor ); + ensembleCurveSetCollection()->addCurveSet( curveSet ); } diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp index 49576546bd..051d5bcd3d 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp @@ -827,6 +827,14 @@ void RiuQwtPlotWidget::recalculateAxisExtents( RiuPlotAxis axis ) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RiuQwtPlotWidget::highlightItemWidthAdjustment() +{ + return 2; +} + //-------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -967,13 +975,57 @@ void RiuQwtPlotWidget::replot() //-------------------------------------------------------------------------------------------------- void RiuQwtPlotWidget::highlightPlotItems( const std::set& closestItems ) { + if ( closestItems.size() == 1 ) + { + auto* constPlotCurve = dynamic_cast( *closestItems.begin() ); + auto* plotCurve = const_cast( constPlotCurve ); + + if ( plotCurve ) + { + auto curveColor = plotCurve->pen().color(); + if ( RiaColorTools::isBrightnessAboveThreshold( RiaColorTools::fromQColorTo3f( curveColor ) ) ) + { + // The brightness of selected curve is above threshold. Modify the saturation, and leave the other + // curves unchanged + + QColor symbolColor; + QColor symbolLineColor; + auto* symbol = const_cast( plotCurve->symbol() ); + if ( symbol ) + { + symbolColor = symbol->brush().color(); + symbolLineColor = symbol->pen().color(); + } + + double zValue = plotCurve->z(); + plotCurve->setZ( zValue + 100.0 ); + highlightPlotAxes( plotCurve->xAxis(), plotCurve->yAxis() ); + + auto hightlightColor = curveColor; + qreal h, s, v; + hightlightColor.getHsvF( &h, &s, &v ); + hightlightColor.setHsvF( h, 0.95, v ); + + auto curveWidth = plotCurve->pen().width(); + plotCurve->setPen( hightlightColor, + plotCurve->pen().width() + highlightItemWidthAdjustment(), + plotCurve->pen().style() ); + + CurveProperties properties = { curveColor, symbolColor, symbolLineColor, curveWidth }; + m_originalCurveProperties.insert( std::make_pair( plotCurve, properties ) ); + m_originalZValues.insert( std::make_pair( plotCurve, zValue ) ); + + return; + } + } + } + // NB! Create a copy of the item list before the loop to avoid invalidated iterators when iterating the list // plotCurve->setZ() causes the ordering of items in the list to change auto plotItemList = m_plot->itemList(); for ( QwtPlotItem* plotItem : plotItemList ) { - auto* plotCurve = dynamic_cast( plotItem ); - auto* plotShapeItem = dynamic_cast( plotItem ); + auto* plotCurve = dynamic_cast( plotItem ); if ( plotCurve ) { QPen existingPen = plotCurve->pen(); @@ -982,6 +1034,7 @@ void RiuQwtPlotWidget::highlightPlotItems( const std::set& c QColor curveColor = existingPen.color(); QColor symbolColor; QColor symbolLineColor; + auto penWidth = existingPen.width(); auto* symbol = const_cast( plotCurve->symbol() ); if ( symbol ) @@ -993,6 +1046,8 @@ void RiuQwtPlotWidget::highlightPlotItems( const std::set& c double zValue = plotCurve->z(); if ( closestItems.count( plotCurve ) > 0 ) { + existingPen.setWidth( penWidth + highlightItemWidthAdjustment() ); + plotCurve->setPen( existingPen ); plotCurve->setZ( zValue + 100.0 ); highlightPlotAxes( plotCurve->xAxis(), plotCurve->yAxis() ); } @@ -1009,12 +1064,15 @@ void RiuQwtPlotWidget::highlightPlotItems( const std::set& c symbol->setPen( blendedSymbolLineColor, symbol->pen().width(), symbol->pen().style() ); } } - CurveColors curveColors = { curveColor, symbolColor, symbolLineColor }; - m_originalCurveColors.insert( std::make_pair( plotCurve, curveColors ) ); - m_originalCurveColors.insert( std::make_pair( plotCurve, curveColors ) ); + CurveProperties properties = { curveColor, symbolColor, symbolLineColor, penWidth }; + m_originalCurveProperties.insert( std::make_pair( plotCurve, properties ) ); m_originalZValues.insert( std::make_pair( plotCurve, zValue ) ); + + continue; } - else if ( plotShapeItem && closestItems.count( plotItem ) > 0 ) + + auto* plotShapeItem = dynamic_cast( plotItem ); + if ( plotShapeItem && closestItems.count( plotItem ) > 0 ) { QPen pen = plotShapeItem->pen(); pen.setColor( QColor( Qt::green ) ); @@ -1035,24 +1093,27 @@ void RiuQwtPlotWidget::resetPlotItemHighlighting() auto plotItemList = m_plot->itemList(); for ( QwtPlotItem* plotItem : plotItemList ) { - auto* plotCurve = dynamic_cast( plotItem ); - auto* plotShapeItem = dynamic_cast( plotItem ); - if ( plotCurve && m_originalCurveColors.count( plotCurve ) ) + auto* plotCurve = dynamic_cast( plotItem ); + if ( plotCurve && m_originalCurveProperties.count( plotCurve ) ) { const QPen& existingPen = plotCurve->pen(); - auto colors = m_originalCurveColors[plotCurve]; + auto properties = m_originalCurveProperties[plotCurve]; double zValue = m_originalZValues[plotCurve]; - plotCurve->setPen( colors.lineColor, existingPen.width(), existingPen.style() ); + plotCurve->setPen( properties.lineColor, properties.lineWidth, existingPen.style() ); plotCurve->setZ( zValue ); auto* symbol = const_cast( plotCurve->symbol() ); if ( symbol ) { - symbol->setColor( colors.symbolColor ); - symbol->setPen( colors.symbolLineColor, symbol->pen().width(), symbol->pen().style() ); + symbol->setColor( properties.symbolColor ); + symbol->setPen( properties.symbolLineColor, symbol->pen().width(), symbol->pen().style() ); } + + continue; } - else if ( plotShapeItem ) + + auto* plotShapeItem = dynamic_cast( plotItem ); + if ( plotShapeItem ) { QPen pen = plotShapeItem->pen(); @@ -1064,7 +1125,7 @@ void RiuQwtPlotWidget::resetPlotItemHighlighting() plotShapeItem->setZ( plotShapeItem->z() - 100.0 ); } } - m_originalCurveColors.clear(); + m_originalCurveProperties.clear(); m_originalZValues.clear(); resetPlotAxisHighlighting(); diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h index 85534b68c6..75f85ddbdf 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h @@ -216,17 +216,20 @@ private: void onAxisSelected( QwtScaleWidget* scale, bool toggleItemInSelection ); void recalculateAxisExtents( RiuPlotAxis axis ); + static int highlightItemWidthAdjustment(); + private: - struct CurveColors + struct CurveProperties { QColor lineColor; QColor symbolColor; QColor symbolLineColor; + int lineWidth; }; - std::map m_originalCurveColors; - std::map m_originalZValues; - std::map m_axisMapping; + std::map m_originalCurveProperties; + std::map m_originalZValues; + std::map m_axisMapping; QPointer m_plot; };