Correlation: Sync report plots, fix stale annotations and selection highlight, tune RFT defaults

This commit is contained in:
Magne Sjaastad
2026-04-27 15:44:14 +02:00
parent bc7fbc7b76
commit 72b6aafa01
8 changed files with 190 additions and 10 deletions
@@ -88,6 +88,7 @@ public:
public:
QString parameter;
RiaSummaryCurveDefinition curveDef;
int rowIdx = -1;
};
class TextScaleDraw : public QwtScaleDraw
@@ -156,6 +157,14 @@ bool RimCorrelationMatrixPlot::showAbsoluteValues() const
return m_showAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationMatrixPlot::setShowAbsoluteValues( bool showAbsoluteValues )
{
m_showAbsoluteValues = showAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -164,6 +173,14 @@ bool RimCorrelationMatrixPlot::sortByAbsoluteValues() const
return m_sortByAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationMatrixPlot::setSortByAbsoluteValues( bool sortByAbsoluteValues )
{
m_sortByAbsoluteValues = sortByAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -196,6 +213,14 @@ bool RimCorrelationMatrixPlot::showTopNCorrelations() const
return m_showOnlyTopNCorrelations();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationMatrixPlot::setShowTopNCorrelations( bool showTopN )
{
m_showOnlyTopNCorrelations = showTopN;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -204,6 +229,14 @@ int RimCorrelationMatrixPlot::topNFilterCount() const
return m_topNFilterCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationMatrixPlot::setTopNFilterCount( int filterCount )
{
m_topNFilterCount = filterCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -364,6 +397,7 @@ void RimCorrelationMatrixPlot::onLoadDataAndUpdate()
updateLegend();
createMatrix();
applySelectedParameterHighlight();
m_plotWidget->qwtPlot()->insertLegend( nullptr );
@@ -373,6 +407,52 @@ void RimCorrelationMatrixPlot::onLoadDataAndUpdate()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationMatrixPlot::setSelectedParameter( const QString& paramName )
{
m_selectedParameter = paramName;
applySelectedParameterHighlight();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationMatrixPlot::applySelectedParameterHighlight()
{
if ( !m_plotWidget ) return;
// Reuse the plot widget's built-in click-selection highlight (green frame). Find a cell in the
// same row as the last matrix click whose parameter matches; if none matches, clear the highlight.
const CorrelationMatrixShapeItem* matchingItem = nullptr;
if ( !m_selectedParameter.isEmpty() && m_selectedRowIdx >= 0 )
{
for ( QwtPlotItem* item : m_plotWidget->qwtPlot()->itemList() )
{
auto* matrixItem = dynamic_cast<CorrelationMatrixShapeItem*>( item );
if ( matrixItem && matrixItem->rowIdx == m_selectedRowIdx && matrixItem->parameter == m_selectedParameter )
{
matchingItem = matrixItem;
break;
}
}
}
if ( matchingItem )
{
m_plotWidget->highlightPlotItem( matchingItem );
}
else
{
m_selectedParameter.clear();
m_selectedRowIdx = -1;
m_plotWidget->resetPlotItemHighlighting();
}
m_plotWidget->scheduleReplot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -614,6 +694,7 @@ void RimCorrelationMatrixPlot::createMatrix()
qColor );
rectangle->curveDef = correlationMatrixRows[rowIdx].m_key;
rectangle->parameter = correlationMatrixRows[rowIdx].m_values[colIdx];
rectangle->rowIdx = static_cast<int>( rowIdx );
QwtText textLabel( label );
cvf::Color3f contrastColor = RiaColorTools::contrastColor( cvf::Color3f( color ) );
textLabel.setColor( RiaColorTools::toQColor( contrastColor ) );
@@ -680,6 +761,8 @@ void RimCorrelationMatrixPlot::onPlotItemSelected( std::shared_ptr<RiuPlotItem>
CorrelationMatrixShapeItem* matrixItem = dynamic_cast<CorrelationMatrixShapeItem*>( qwtPlotItem->qwtPlotItem() );
if ( matrixItem )
{
m_selectedRowIdx = matrixItem->rowIdx;
m_selectedParameter = matrixItem->parameter;
matrixCellSelected.send( std::make_pair( matrixItem->parameter, matrixItem->curveDef ) );
}
}
@@ -99,14 +99,20 @@ public:
~RimCorrelationMatrixPlot() override;
bool showAbsoluteValues() const;
void setShowAbsoluteValues( bool showAbsoluteValues );
bool sortByAbsoluteValues() const;
void setSortByAbsoluteValues( bool sortByAbsoluteValues );
RimRegularLegendConfig* legendConfig();
void selectAllParameters();
bool showTopNCorrelations() const;
void setShowTopNCorrelations( bool showTopN );
int topNFilterCount() const;
void setTopNFilterCount( int filterCount );
bool isCurveHighlightSupported() const override;
QString asciiDataForPlotExport() const override;
void setSelectedParameter( const QString& paramName );
private:
// Overridden PDM methods
@@ -126,6 +132,7 @@ private:
void updatePlotTitle() override;
void updateLegend() override;
void onPlotItemSelected( std::shared_ptr<RiuPlotItem> plotItem, bool toggle, int sampleIndex ) override;
void applySelectedParameterHighlight();
private:
caf::PdmField<bool> m_showAbsoluteValues;
@@ -142,4 +149,7 @@ private:
std::map<size_t, QString> m_resultLabels;
std::vector<CorrelationMatrixRow> m_valuesForTextReport;
QString m_selectedParameter;
int m_selectedRowIdx = -1;
};
@@ -349,6 +349,14 @@ void RimCorrelationPlot::selectAllParameters()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCorrelationPlot::showOnlyTopNCorrelations() const
{
return m_showOnlyTopNCorrelations;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -357,6 +365,14 @@ void RimCorrelationPlot::setShowOnlyTopNCorrelations( bool showOnlyTopNCorrelati
m_showOnlyTopNCorrelations = showOnlyTopNCorrelations;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimCorrelationPlot::topNFilterCount() const
{
return m_topNFilterCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -52,7 +52,9 @@ public:
void setSortByAbsoluteValues( bool sortByAbsoluteValues );
void selectAllParameters();
bool showOnlyTopNCorrelations() const;
void setShowOnlyTopNCorrelations( bool showOnlyTopNCorrelations );
int topNFilterCount() const;
void setTopNFilterCount( int filterCount );
void setSelectedParameter( const QString& paramName );
@@ -23,6 +23,7 @@
#include "RiaTimeTTools.h"
#include "Summary/RiaSummaryCurveDefinition.h"
#include "RimAbstractCorrelationPlot.h"
#include "RimCorrelationMatrixPlot.h"
#include "RimCorrelationPlot.h"
#include "RimCorrelationPlotCollection.h"
@@ -606,21 +607,43 @@ void RimCorrelationReportPlot::onLoadDataAndUpdate()
m_summaryPlot->loadDataAndUpdate();
if ( m_summaryPlot->plotWidget() ) m_summaryPlot->plotWidget()->setPlotTitleEnabled( true );
// Add static line for the currently selected time step.
// Must be done after loadDataAndUpdate() since that clears all annotations internally.
auto* timeAxisProps = m_summaryPlot->timeAxisProperties();
if ( timeAxisProps )
{
timeAxisProps->appendAnnotation( RimTimeAxisAnnotation::createTimeAnnotation( timeStep, TRACKING_ANNOTATION_COLOR ) );
m_summaryPlot->updateAnnotationsInPlotWidget();
}
}
updateSummaryPlotTimeAnnotation();
}
updateLayout();
}
//--------------------------------------------------------------------------------------------------
/// Called after PDM fields have been deserialized from the project file. Transient annotations
/// (selected-time highlight, mouse-tracking dashed line) are PDM-serialized and may persist across
/// save/load; reset them to a clean single highlight at the restored time step.
//--------------------------------------------------------------------------------------------------
void RimCorrelationReportPlot::initAfterRead()
{
updateSummaryPlotTimeAnnotation();
}
//--------------------------------------------------------------------------------------------------
/// Idempotent: clears any existing time-axis annotations on the summary plot and appends a single
/// highlight at the matrix plot's current time step. Safe to call before the widget is created —
/// the data model is updated regardless; rendering happens once the widget exists.
//--------------------------------------------------------------------------------------------------
void RimCorrelationReportPlot::updateSummaryPlotTimeAnnotation()
{
if ( !m_summaryPlot ) return;
auto* timeAxisProps = m_summaryPlot->timeAxisProperties();
if ( !timeAxisProps ) return;
timeAxisProps->removeAllAnnotations();
auto timeStep = m_correlationMatrixPlot->timeStep().toSecsSinceEpoch();
timeAxisProps->appendAnnotation( RimTimeAxisAnnotation::createTimeAnnotation( timeStep, TRACKING_ANNOTATION_COLOR ) );
m_summaryPlot->updateAnnotationsInPlotWidget();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -702,9 +725,39 @@ void RimCorrelationReportPlot::childFieldChangedByUi( const caf::PdmFieldHandle*
else if ( m_summaryDockWidget && changedChildField == &m_summaryPlot )
m_summaryDockWidget->toggleView( m_summaryPlot->showWindow() );
// onLoadDataAndUpdate treats the matrix plot as the source of truth and copies its shared
// properties to the others. When the change originated on the correlation or cross plot,
// first mirror it back to the matrix plot so the subsequent propagation reflects the change.
if ( changedChildField == &m_correlationPlot )
syncSharedPropertiesToMatrixPlotFrom( m_correlationPlot() );
else if ( changedChildField == &m_parameterResultCrossPlot )
syncSharedPropertiesToMatrixPlotFrom( m_parameterResultCrossPlot() );
loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationReportPlot::syncSharedPropertiesToMatrixPlotFrom( RimAbstractCorrelationPlot* source )
{
if ( !source || source == m_correlationMatrixPlot() ) return;
// Properties defined on RimAbstractCorrelationPlot — shared by all three plots.
m_correlationMatrixPlot->setTimeStep( source->timeStep().toSecsSinceEpoch() );
m_correlationMatrixPlot->enableCaseFilter( source->isCaseFilterEnabled() );
m_correlationMatrixPlot->setCaseFilterDataSource( source->caseFilterDataSource() );
// Properties shared only between matrix plot and correlation (tornado) plot.
if ( source == m_correlationPlot() )
{
m_correlationMatrixPlot->setShowAbsoluteValues( m_correlationPlot->showAbsoluteValues() );
m_correlationMatrixPlot->setSortByAbsoluteValues( m_correlationPlot->sortByAbsoluteValues() );
m_correlationMatrixPlot->setShowTopNCorrelations( m_correlationPlot->showOnlyTopNCorrelations() );
m_correlationMatrixPlot->setTopNFilterCount( m_correlationPlot->topNFilterCount() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -721,6 +774,8 @@ void RimCorrelationReportPlot::onDataSelection( const caf::SignalEmitter*
auto paramName = parameterAndCurveDef.first;
auto curveDef = parameterAndCurveDef.second;
m_correlationMatrixPlot->setSelectedParameter( paramName );
m_correlationPlot->setCurveDefinitions( { curveDef } );
m_correlationPlot->setSelectedParameter( paramName );
m_correlationPlot->loadDataAndUpdate();
@@ -740,6 +795,8 @@ void RimCorrelationReportPlot::onDataSelection( const caf::SignalEmitter*
if ( m_summaryPlot->plotWidget() ) m_summaryPlot->plotWidget()->setPlotTitleEnabled( true );
}
updateSummaryPlotTimeAnnotation();
updateConnectedEditors();
}
@@ -28,6 +28,7 @@
#include <QDateTime>
#include <QObject>
class RimAbstractCorrelationPlot;
class RimCorrelationMatrixPlot;
class RimParameterResultCrossPlot;
class RimSummaryEnsemble;
@@ -71,6 +72,7 @@ private:
void cleanupBeforeClose();
void setupBeforeSave() override;
void initAfterRead() override;
void doRenderWindowContent( QPaintDevice* paintDevice ) override;
QWidget* createViewWidget( QWidget* mainWindowParent = nullptr ) override;
void deleteViewWidget() override;
@@ -86,6 +88,8 @@ private:
void onSaveDefaultDockLayout();
void onRestoreDefaultDockLayout();
void updateDockTitleBarsVisibility();
void syncSharedPropertiesToMatrixPlotFrom( RimAbstractCorrelationPlot* source );
void updateSummaryPlotTimeAnnotation();
private:
caf::PdmProxyValueField<QString> m_name;
@@ -199,6 +199,14 @@ void RimRftCorrelationReportPlot::initializeFromSourcePlot( RimWellRftPlot* sour
}
m_wellRftPlot->initializeDataSources( source );
// The correlation report operates on a single time step; trim any extras that
// initializeDataSources may have preselected when only a few were available.
auto selectedTimeSteps = m_wellRftPlot->selectedTimeSteps();
if ( selectedTimeSteps.size() > 1 )
{
m_wellRftPlot->setSelectedTimeSteps( { selectedTimeSteps.front() } );
}
}
//--------------------------------------------------------------------------------------------------
@@ -66,7 +66,7 @@ RimRftTornadoPlot::RimRftTornadoPlot()
CAF_PDM_InitField( &m_showAbsoluteValues, "ShowAbsoluteValues", false, "Show Absolute Values" );
CAF_PDM_InitField( &m_sortByAbsoluteValues, "SortByAbsoluteValues", true, "Sort by Absolute Values" );
CAF_PDM_InitField( &m_showOnlyTopNCorrelations, "ShowOnlyTopN", true, "Show Only Top Correlations" );
CAF_PDM_InitField( &m_topNFilterCount, "TopNFilterCount", 20, "Number of Rows" );
CAF_PDM_InitField( &m_topNFilterCount, "TopNFilterCount", 10, "Number of Rows" );
QColor qColor = QColor( "#3173b2" );
CAF_PDM_InitField( &m_barColor, "BarColor", RiaColorTools::fromQColorTo3f( qColor ), "Bar Color (Positive)" );