#12168 Allow highlight of curves based on selection of realization object

Use the first available highlighted curve as basis for display of horizontal readout value. Fallback to single realization curves.
When selecting a realization in project tree, highlight all related curves
Make sure zoom rect works when readout annotations are active
This commit is contained in:
Magne Sjaastad
2025-02-18 11:04:40 +01:00
committed by GitHub
parent eac1c84ed4
commit bbd79cca6a
15 changed files with 121 additions and 49 deletions

View File

@@ -51,6 +51,21 @@ void caf::AppEnum<RimSummaryCurveAppearanceCalculator::CurveAppearanceType>::set
}
} // namespace caf
namespace internal
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotCurveDefines::LineStyleEnum cycledLineStyle( int index )
{
if ( index < 0 ) return RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID;
return caf::AppEnum<RiuQwtPlotCurveDefines::LineStyleEnum>::fromIndex(
1 + ( index % ( caf::AppEnum<RiuQwtPlotCurveDefines::LineStyleEnum>::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<RiuQwtPlotCurveDefines::LineStyleEnum>::fromIndex(
1 + ( index % ( caf::AppEnum<RiuQwtPlotCurveDefines::LineStyleEnum>::size() - 1 ) ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -18,7 +18,6 @@
#pragma once
#include "RiuPlotCurveSymbol.h"
#include "RiuQwtPlotCurveDefines.h"
#include "cvfColor3.h"
@@ -77,9 +76,8 @@ private:
void updateApperanceIndices();
std::map<std::string, size_t> mapNameToAppearanceIndex( CurveAppearanceType& appearance, const std::set<std::string>& 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 );

View File

@@ -349,7 +349,7 @@ bool RimSummaryEnsembleTools::isEnsembleCurve( RimPlotCurve* sourceCurve )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleTools::highlightCurvesForSameRealization( RimPlotCurve* sourceCurve )
void RimSummaryEnsembleTools::highlightCurvesForSameRealizationFromCurve( RimPlotCurve* sourceCurve )
{
auto sourceSummaryCurve = dynamic_cast<RimSummaryCurve*>( 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() )

View File

@@ -39,7 +39,8 @@ std::vector<RigEnsembleParameter> createVariationSortedEnsembleParameters( const
size_t calculateEnsembleParametersIntersectionHash( const std::vector<RimSummaryCase*>& summaryCases );
bool isEnsembleCurve( RimPlotCurve* sourceCurve );
void highlightCurvesForSameRealization( RimPlotCurve* sourceCurve );
void highlightCurvesForSameRealizationFromCurve( RimPlotCurve* sourceCurve );
void highlightCurvesForSameRealization( RimSummaryCase* sourceCase );
void resetHighlightAllPlots();
} // namespace RimSummaryEnsembleTools

View File

@@ -1760,23 +1760,44 @@ void RimSummaryMultiPlot::updateReadOutLines( double qwtTimeValue, double yValue
if ( m_readOutSettings->enableHorizontalLine() )
{
if ( auto leftAxisProperties = dynamic_cast<RimPlotAxisProperties*>( plot->axisPropertiesForPlotAxis( RiuPlotAxis::defaultLeft() ) ) )
{
leftAxisProperties->removeAllAnnotations();
std::vector<RimSummaryCurve*> summaryCurves;
auto summaryCurves = plot->summaryCurves();
if ( !summaryCurves.empty() )
// 1. Check if any curves are highlighted
if ( auto plotWidget = dynamic_cast<RiuQwtPlotWidget*>( plot->plotWidget() ) )
{
for ( auto highlightCurve : plotWidget->highlightedCurves() )
{
auto firstCurve = summaryCurves.front();
yValue = firstCurve->yValueAtTimeT( timeTValue );
if ( auto summaryCurve = dynamic_cast<RimSummaryCurve*>( 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<RimPlotAxisProperties*>( plot->axisPropertiesForPlotAxis( RiuPlotAxis::defaultLeft() ) );
if ( !summaryCurves.empty() )
{
auto firstCurve = summaryCurves.front();
yValue = firstCurve->yValueAtTimeT( timeTValue );
annotationAxis = dynamic_cast<RimPlotAxisProperties*>( 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();
}
}

View File

@@ -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 );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -129,6 +129,7 @@ public:
RimTimeAxisAnnotation* addTimeRangeAnnotation( time_t startTime, time_t endTime );
void removeTimeAnnotation( RimTimeAxisAnnotation* annotation );
void removeAllTimeAnnotations();
void updateAnnotationsInPlotWidget();
void updateAxes() override;

View File

@@ -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 ) );
}

View File

@@ -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;

View File

@@ -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<RimSummaryCase*>( firstSelectedObject ) )
{
RimSummaryEnsembleTools::highlightCurvesForSameRealization( summaryCase );
}
RimViewWindow* selectedWindow = dynamic_cast<RimViewWindow*>( firstSelectedObject );
if ( !selectedWindow )
{

View File

@@ -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" );

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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<RimPlotCurve*>& 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<RimPlotCurve*> RiuQwtPlotWidget::highlightedCurves() const
{
return m_hightlightedCurves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::resetPlotCurveHighlighting()
{
m_hightlightedCurves.clear();
if ( !m_plotDefinition || m_originalZValues.empty() )
{
return;

View File

@@ -164,9 +164,10 @@ public:
QwtAxisId toQwtPlotAxis( RiuPlotAxis axis ) const;
void highlightPlotItem( const QwtPlotItem* plotItem );
void highlightCurvesUpdateOrder( const std::set<RimPlotCurve*>& curves );
void resetPlotItemHighlighting( bool doUpdateCurveOrder = true );
void highlightPlotItem( const QwtPlotItem* plotItem );
void highlightCurvesUpdateOrder( const std::set<RimPlotCurve*>& curves );
void resetPlotItemHighlighting( bool doUpdateCurveOrder = true );
std::vector<RimPlotCurve*> highlightedCurves() const;
void replot() override;
@@ -231,6 +232,7 @@ private:
};
std::map<QwtPlotCurve*, double> m_originalZValues;
std::vector<RimPlotCurve*> m_hightlightedCurves;
std::map<RiuPlotAxis, QwtAxisId> m_axisMapping;
QPointer<QwtPlot> m_plot;