diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp index adb58c0d92..8a486a016a 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp @@ -51,6 +51,21 @@ void caf::AppEnum::set } } // namespace caf +namespace internal +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtPlotCurveDefines::LineStyleEnum cycledLineStyle( int index ) +{ + if ( index < 0 ) return RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID; + + return caf::AppEnum::fromIndex( + 1 + ( index % ( caf::AppEnum::size() - 1 ) ) ); +} + +} // namespace internal + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -514,7 +529,7 @@ void RimSummaryCurveAppearanceCalculator::setOneCurveAppearance( CurveAppearance m_currentCurveGradient = gradient( totalCount, appeaIdx ); break; case LINE_STYLE: - curve->setLineStyle( cycledLineStyle( appeaIdx ) ); + curve->setLineStyle( internal::cycledLineStyle( appeaIdx ) ); break; case SYMBOL: curve->setSymbol( cycledSymbol( appeaIdx ) ); @@ -585,17 +600,6 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledBrownColor( int colorInd return RiaColorTables::summaryCurveBrownPaletteColors().cycledColor3f( colorIndex ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiuQwtPlotCurveDefines::LineStyleEnum RimSummaryCurveAppearanceCalculator::cycledLineStyle( int index ) -{ - if ( index < 0 ) return RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID; - - return caf::AppEnum::fromIndex( - 1 + ( index % ( caf::AppEnum::size() - 1 ) ) ); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h index 26ba4a6308..4b98a2f795 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h @@ -18,7 +18,6 @@ #pragma once #include "RiuPlotCurveSymbol.h" -#include "RiuQwtPlotCurveDefines.h" #include "cvfColor3.h" @@ -77,9 +76,8 @@ private: void updateApperanceIndices(); std::map mapNameToAppearanceIndex( CurveAppearanceType& appearance, const std::set& names ); - RiuQwtPlotCurveDefines::LineStyleEnum cycledLineStyle( int index ); - int cycledLineThickness( int index ); - float gradient( size_t totalCount, int index ); + int cycledLineThickness( int index ); + float gradient( size_t totalCount, int index ); cvf::Color3f gradeColor( const cvf::Color3f& color, float factor ); void assignColorByPhase( RimSummaryCurve* curve, int colorIndex ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.cpp index 49142e9525..da224ae1cc 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.cpp @@ -349,7 +349,7 @@ bool RimSummaryEnsembleTools::isEnsembleCurve( RimPlotCurve* sourceCurve ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryEnsembleTools::highlightCurvesForSameRealization( RimPlotCurve* sourceCurve ) +void RimSummaryEnsembleTools::highlightCurvesForSameRealizationFromCurve( RimPlotCurve* sourceCurve ) { auto sourceSummaryCurve = dynamic_cast( sourceCurve ); if ( !sourceSummaryCurve ) return; @@ -369,6 +369,16 @@ void RimSummaryEnsembleTools::highlightCurvesForSameRealization( RimPlotCurve* s } } + highlightCurvesForSameRealization( sourceCase ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryEnsembleTools::highlightCurvesForSameRealization( RimSummaryCase* sourceCase ) +{ + if ( !sourceCase ) return; + auto summaryPlotColl = RiaSummaryTools::summaryMultiPlotCollection(); for ( auto multiPlot : summaryPlotColl->multiPlots() ) diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.h index 5974b668b4..442c5c65f9 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryEnsembleTools.h @@ -39,7 +39,8 @@ std::vector createVariationSortedEnsembleParameters( const size_t calculateEnsembleParametersIntersectionHash( const std::vector& summaryCases ); bool isEnsembleCurve( RimPlotCurve* sourceCurve ); -void highlightCurvesForSameRealization( RimPlotCurve* sourceCurve ); +void highlightCurvesForSameRealizationFromCurve( RimPlotCurve* sourceCurve ); +void highlightCurvesForSameRealization( RimSummaryCase* sourceCase ); void resetHighlightAllPlots(); } // namespace RimSummaryEnsembleTools diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp index 7db78b3ebe..3c771b0bf6 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp @@ -1760,23 +1760,44 @@ void RimSummaryMultiPlot::updateReadOutLines( double qwtTimeValue, double yValue if ( m_readOutSettings->enableHorizontalLine() ) { - if ( auto leftAxisProperties = dynamic_cast( plot->axisPropertiesForPlotAxis( RiuPlotAxis::defaultLeft() ) ) ) - { - leftAxisProperties->removeAllAnnotations(); + std::vector summaryCurves; - auto summaryCurves = plot->summaryCurves(); - if ( !summaryCurves.empty() ) + // 1. Check if any curves are highlighted + if ( auto plotWidget = dynamic_cast( plot->plotWidget() ) ) + { + for ( auto highlightCurve : plotWidget->highlightedCurves() ) { - auto firstCurve = summaryCurves.front(); - yValue = firstCurve->yValueAtTimeT( timeTValue ); + if ( auto summaryCurve = dynamic_cast( highlightCurve ) ) + { + summaryCurves.push_back( summaryCurve ); + } } + } + + // 2. If no curves are highlighted, use summary curves from single realizations + if ( summaryCurves.empty() ) + { + summaryCurves = plot->summaryCurves(); + } + + auto annotationAxis = dynamic_cast( plot->axisPropertiesForPlotAxis( RiuPlotAxis::defaultLeft() ) ); + if ( !summaryCurves.empty() ) + { + auto firstCurve = summaryCurves.front(); + yValue = firstCurve->yValueAtTimeT( timeTValue ); + annotationAxis = dynamic_cast( plot->axisPropertiesForPlotAxis( firstCurve->axisY() ) ); + } + + if ( annotationAxis ) + { + annotationAxis->removeAllAnnotations(); auto anno = new RimPlotAxisAnnotation(); anno->setAnnotationType( RimPlotAxisAnnotation::AnnotationType::LINE ); anno->setValue( yValue ); - auto scaledValue = yValue / leftAxisProperties->scaleFactor(); + auto scaledValue = yValue / annotationAxis->scaleFactor(); auto valueText = RiaNumberFormat::valueToText( scaledValue, RiaNumberFormat::NumberFormatType::FIXED, 2 ); anno->setName( valueText ); @@ -1788,10 +1809,12 @@ void RimSummaryMultiPlot::updateReadOutLines( double qwtTimeValue, double yValue anno->setColor( lineAppearance->color() ); anno->setAlignment( m_readOutSettings->horizontalLineLabelAlignment() ); - leftAxisProperties->appendAnnotation( anno ); + annotationAxis->appendAnnotation( anno ); } } - plot->updateAxes(); + // Calling plot->updateAxes() does not work for the first plot in a multiplot. Use fine grained update of annotation objects. + plot->updateAnnotationsInPlotWidget(); + plot->updatePlotWidgetFromAxisRanges(); } } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index c13c5f2e91..0ae0ff122b 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -212,18 +212,7 @@ void RimSummaryPlot::updateAxes() updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_LEFT ); updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_RIGHT ); - if ( m_summaryPlot ) m_summaryPlot->clearAnnotationObjects(); - - if ( timeAxisProperties() && plotWidget() ) - { - m_summaryPlot->updateAnnotationObjects( timeAxisProperties() ); - } - - RimPlotAxisPropertiesInterface* leftYAxisProperties = axisPropertiesForPlotAxis( RiuPlotAxis::defaultLeft() ); - if ( leftYAxisProperties && plotWidget() ) - { - m_summaryPlot->updateAnnotationObjects( leftYAxisProperties ); - } + updateAnnotationsInPlotWidget(); updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM ); updateNumericalAxis( RiaDefines::PlotAxis::PLOT_AXIS_TOP ); @@ -232,6 +221,26 @@ void RimSummaryPlot::updateAxes() updatePlotWidgetFromAxisRanges(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::updateAnnotationsInPlotWidget() +{ + if ( m_summaryPlot ) m_summaryPlot->clearAnnotationObjects(); + + if ( !plotWidget() ) return; + + if ( timeAxisProperties() ) + { + m_summaryPlot->updateAnnotationObjects( timeAxisProperties() ); + } + + if ( auto leftYAxisProperties = axisPropertiesForPlotAxis( RiuPlotAxis::defaultLeft() ) ) + { + m_summaryPlot->updateAnnotationObjects( leftYAxisProperties ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h index d8543f4fb4..790f218976 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h @@ -129,6 +129,7 @@ public: RimTimeAxisAnnotation* addTimeRangeAnnotation( time_t startTime, time_t endTime ); void removeTimeAnnotation( RimTimeAxisAnnotation* annotation ); void removeAllTimeAnnotations(); + void updateAnnotationsInPlotWidget(); void updateAxes() override; diff --git a/ApplicationLibCode/UserInterface/RiuPlotAnnotationTool.cpp b/ApplicationLibCode/UserInterface/RiuPlotAnnotationTool.cpp index d586508b6b..89cf05c9b4 100644 --- a/ApplicationLibCode/UserInterface/RiuPlotAnnotationTool.cpp +++ b/ApplicationLibCode/UserInterface/RiuPlotAnnotationTool.cpp @@ -20,6 +20,7 @@ #include "RimPlotAxisAnnotation.h" #include "RiuGuiTheme.h" +#include "RiuQwtPlotCurveDefines.h" #include "cafCategoryMapper.h" #include "cvfMath.h" @@ -408,4 +409,6 @@ void RiuPlotAnnotationTool::setLineProperties( QwtPlotMarker* line, line->setLineStyle( QwtPlotMarker::VLine ); line->setXValue( linePosition ); } + + line->setZ( RiuQwtPlotCurveDefines::zDepthForIndex( RiuQwtPlotCurveDefines::ZIndex::Z_ANNOTATION ) ); } diff --git a/ApplicationLibCode/UserInterface/RiuPlotCurve.h b/ApplicationLibCode/UserInterface/RiuPlotCurve.h index 5e55185ee7..5e7b491d1f 100644 --- a/ApplicationLibCode/UserInterface/RiuPlotCurve.h +++ b/ApplicationLibCode/UserInterface/RiuPlotCurve.h @@ -56,7 +56,6 @@ class RiuPlotCurve { public: explicit RiuPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title = QString() ); - explicit RiuPlotCurve(); virtual ~RiuPlotCurve(); virtual void setTitle( const QString& title ) = 0; diff --git a/ApplicationLibCode/UserInterface/RiuPlotMainWindow.cpp b/ApplicationLibCode/UserInterface/RiuPlotMainWindow.cpp index fab7c4bba0..c92417e830 100644 --- a/ApplicationLibCode/UserInterface/RiuPlotMainWindow.cpp +++ b/ApplicationLibCode/UserInterface/RiuPlotMainWindow.cpp @@ -31,8 +31,10 @@ #include "RimMainPlotCollection.h" #include "RimMultiPlot.h" #include "RimProject.h" +#include "RimSummaryCase.h" #include "RimSummaryCaseMainCollection.h" #include "RimSummaryCurveCollection.h" +#include "RimSummaryEnsembleTools.h" #include "RimSummaryMultiPlot.h" #include "RimSummaryMultiPlotCollection.h" #include "RimSummaryPlot.h" @@ -942,6 +944,11 @@ void RiuPlotMainWindow::selectedObjectsChanged( caf::PdmUiTreeView* projectTree, if ( !firstSelectedObject ) return; + if ( auto summaryCase = dynamic_cast( firstSelectedObject ) ) + { + RimSummaryEnsembleTools::highlightCurvesForSameRealization( summaryCase ); + } + RimViewWindow* selectedWindow = dynamic_cast( firstSelectedObject ); if ( !selectedWindow ) { diff --git a/ApplicationLibCode/UserInterface/RiuQwtCurvePointTracker.cpp b/ApplicationLibCode/UserInterface/RiuQwtCurvePointTracker.cpp index ab57583754..ceed8c7331 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtCurvePointTracker.cpp +++ b/ApplicationLibCode/UserInterface/RiuQwtCurvePointTracker.cpp @@ -19,6 +19,7 @@ #include "RiuQwtCurvePointTracker.h" #include "RiaQDateTimeTools.h" + #include "RiuGuiTheme.h" #include "RiuPlotCurve.h" #include "RiuPlotCurveInfoTextProvider.h" @@ -45,9 +46,7 @@ RiuQwtCurvePointTracker::RiuQwtCurvePointTracker( QwtPlot* plot, bool isMainAxis setTrackerMode( QwtPicker::AlwaysOn ); m_plotMarker = new QwtPlotMarker; - // Have this marker always on top of all curves/plot items. - double zAlwaysOnTop = 99999999; - m_plotMarker->setZ( zAlwaysOnTop ); + m_plotMarker->setZ( RiuQwtPlotCurveDefines::zDepthForIndex( RiuQwtPlotCurveDefines::ZIndex::Z_ANNOTATION ) ); auto color = RiuGuiTheme::getColorByVariableName( "markerColor" ); diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.cpp b/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.cpp index 46973d509d..5e1c0f4bf8 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.cpp +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.cpp @@ -73,6 +73,9 @@ int RiuQwtPlotCurveDefines::zDepthForIndex( ZIndex index ) case RiuQwtPlotCurveDefines::ZIndex::Z_REGRESSION_CURVE: return 700; break; + case RiuQwtPlotCurveDefines::ZIndex::Z_ANNOTATION: + return 9999; + break; default: break; diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.h b/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.h index 2a92f2acea..0adf441b98 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.h +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotCurveDefines.h @@ -47,7 +47,8 @@ enum class ZIndex Z_ERROR_BARS, Z_SINGLE_CURVE_OBSERVED, Z_PLOT_RECT_ANNOTATION, - Z_REGRESSION_CURVE + Z_REGRESSION_CURVE, + Z_ANNOTATION }; int zDepthForIndex( ZIndex index ); diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp index 203b17c0dd..45b68f3c53 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.cpp @@ -942,7 +942,7 @@ void RiuQwtPlotWidget::selectClosestPlotItem( const QPoint& pos, bool toggleItem const auto rimCurve = curve->ownerRimCurve(); if ( RimSummaryEnsembleTools::isEnsembleCurve( rimCurve ) ) { - RimSummaryEnsembleTools::highlightCurvesForSameRealization( rimCurve ); + RimSummaryEnsembleTools::highlightCurvesForSameRealizationFromCurve( rimCurve ); } else { @@ -1055,6 +1055,8 @@ void RiuQwtPlotWidget::highlightPlotCurves( const std::set& curve plotCurve->setPen( existingPen ); plotCurve->setZ( zValue + 100.0 ); highlightPlotAxes( plotCurve->xAxis(), plotCurve->yAxis() ); + + m_hightlightedCurves.push_back( currentRimPlotCurve ); } else { @@ -1110,11 +1112,21 @@ void RiuQwtPlotWidget::resetPlotItemHighlighting( bool doUpdateCurveOrder ) if ( doUpdateCurveOrder ) updateCurveOrder(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuQwtPlotWidget::highlightedCurves() const +{ + return m_hightlightedCurves; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuQwtPlotWidget::resetPlotCurveHighlighting() { + m_hightlightedCurves.clear(); + if ( !m_plotDefinition || m_originalZValues.empty() ) { return; diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h index 728445cbdc..ddbb7cc57f 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotWidget.h @@ -164,9 +164,10 @@ public: QwtAxisId toQwtPlotAxis( RiuPlotAxis axis ) const; - void highlightPlotItem( const QwtPlotItem* plotItem ); - void highlightCurvesUpdateOrder( const std::set& curves ); - void resetPlotItemHighlighting( bool doUpdateCurveOrder = true ); + void highlightPlotItem( const QwtPlotItem* plotItem ); + void highlightCurvesUpdateOrder( const std::set& curves ); + void resetPlotItemHighlighting( bool doUpdateCurveOrder = true ); + std::vector highlightedCurves() const; void replot() override; @@ -231,6 +232,7 @@ private: }; std::map m_originalZValues; + std::vector m_hightlightedCurves; std::map m_axisMapping; QPointer m_plot;