#14203 Add cumulative curve option to Grid Statistics plot

A new "Show Cumulative Curve" checkbox on the grid statistics data source adds a cumulative curve on the right axis, in addition to the regular histogram curve. The cumulative curve shares the data source of its non-cumulative counterpart and follows all changes to it. The cumulative sum works with all frequency types and both graph types.

Remove the legacy Grid Statistics dialog (RicGridStatisticsDialog) and its context menu command, which provided the previous cumulative display.
This commit is contained in:
Kristian Bendiksen authored and GitHub committed 2026-07-27 12:37:59 +02:00
1 parent 5dc3374733
commit 280763f4c0
28 files changed
+408 -638

No files matched your search

@@ -111,8 +111,9 @@ std::string RimEnsembleFractureHistogramDataSource::unitNameX() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimHistogramDataSource::HistogramResult RimEnsembleFractureHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType ) const
RimHistogramDataSource::HistogramResult RimEnsembleFractureHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative ) const
{
RimHistogramDataSource::HistogramResult result;
@@ -126,8 +127,8 @@ RimHistogramDataSource::HistogramResult RimEnsembleFractureHistogramDataSource::
double min = histogramData.min;
double max = histogramData.max;
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType );
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative );
result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType, cumulative );
result.p10 = histogramData.p10;
result.mean = histogramData.mean;
@@ -45,7 +45,9 @@ public:
std::string unitNameX() const override;
std::string unitNameY() const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative = false ) const override;
void setDefaults() override;
@@ -147,8 +147,9 @@ std::string RimEnsembleParameterHistogramDataSource::unitNameX() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType ) const
RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative ) const
{
RimHistogramDataSource::HistogramResult result;
@@ -159,7 +160,7 @@ RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource:
double min = parameter.minValue;
double max = parameter.maxValue;
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative );
std::vector<double> values;
for ( const QVariant& v : parameter.values )
@@ -171,7 +172,7 @@ RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource:
RigHistogramCalculator histCalc( min, max, m_numBins, &histogram );
histCalc.addData( values );
result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType );
result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType, cumulative );
double p10, p50, p90, mean;
RigStatisticsMath::calculateStatisticsCurves( values, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED );
@@ -46,7 +46,9 @@ public:
std::string unitNameX() const override;
std::string unitNameY() const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative = false ) const override;
void setDefaults() override;
@@ -229,8 +229,9 @@ std::vector<double> RimEnsembleSummaryVectorHistogramDataSource::extractValuesFr
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType ) const
RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative ) const
{
RimHistogramDataSource::HistogramResult result;
@@ -241,13 +242,13 @@ RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSou
double min = *min_it;
double max = *max_it;
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative );
std::vector<size_t> histogram;
RigHistogramCalculator histCalc( min, max, m_numBins, &histogram );
histCalc.addData( values );
result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType );
result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType, cumulative );
double p10, p50, p90, mean;
RigStatisticsMath::calculateStatisticsCurves( values, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED );
@@ -48,7 +48,9 @@ public:
std::string unitNameX() const override;
std::string unitNameY() const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative = false ) const override;
void setDefaults() override;
@@ -51,6 +51,24 @@ RimGridStatisticsHistogramDataSource::RimGridStatisticsHistogramDataSource()
m_property->setTernaryEnabled( false );
CAF_PDM_InitField( &m_numBins, "NumBins", 15, "Number of Bins" );
CAF_PDM_InitField( &m_cumulative, "Cumulative", false, "Show Cumulative Curve" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGridStatisticsHistogramDataSource::showCumulativeCurve() const
{
return m_cumulative();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridStatisticsHistogramDataSource::setShowCumulativeCurve( bool showCumulativeCurve )
{
m_cumulative = showCumulativeCurve;
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
@@ -107,6 +125,7 @@ void RimGridStatisticsHistogramDataSource ::defineUiOrdering( QString uiConfigNa
{
uiOrdering.add( &m_timeStep );
uiOrdering.add( &m_cellFilterView );
uiOrdering.add( &m_cumulative );
caf::PdmUiGroup* propertyGroup = uiOrdering.addNewGroup( "Property" );
m_property->uiOrdering( uiConfigName, *propertyGroup );
}
@@ -132,6 +151,13 @@ void RimGridStatisticsHistogramDataSource::fieldChangedByUi( const caf::PdmField
dataSourceChanged.send();
}
}
else if ( changedField == &m_cumulative )
{
// Handled by the owning curve, which creates or deletes the cumulative companion curve.
// Not sent as dataSourceChanged: the companion curve observes that signal, and must not be
// deleted while it is being emitted.
cumulativeChanged.send();
}
else
{
dataSourceChanged.send();
@@ -158,7 +184,8 @@ std::string RimGridStatisticsHistogramDataSource::unitNameX() const
///
//--------------------------------------------------------------------------------------------------
RimHistogramDataSource::HistogramResult RimGridStatisticsHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType ) const
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative ) const
{
RimHistogramDataSource::HistogramResult result;
@@ -168,8 +195,8 @@ RimHistogramDataSource::HistogramResult RimGridStatisticsHistogramDataSource::co
double min = histogramData.min;
double max = histogramData.max;
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType );
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative );
result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType, cumulative );
result.p10 = histogramData.p10;
result.mean = histogramData.mean;
@@ -45,7 +45,12 @@ public:
std::string unitNameX() const override;
std::string unitNameY() const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
HistogramResult compute( RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative = false ) const override;
bool showCumulativeCurve() const override;
void setShowCumulativeCurve( bool showCumulativeCurve ) override;
std::string name() const override;
@@ -70,4 +75,5 @@ protected:
caf::PdmPtrField<RimGridView*> m_cellFilterView;
caf::PdmChildField<RimEclipseResultDefinition*> m_property;
caf::PdmField<int> m_numBins;
caf::PdmField<bool> m_cumulative;
};
@@ -54,6 +54,12 @@ RimHistogramCurve::RimHistogramCurve()
CAF_PDM_InitFieldNoDefault( &m_dataSource, "DataSource", "Data Source" );
m_dataSource.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_dataSourceReference, "DataSourceReference", "Data Source Reference" );
m_dataSourceReference.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_isCumulative, "IsCumulative", false, "Cumulative" );
m_isCumulative.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_showP10Curve, "ShowP10Curve", true, "P10" );
CAF_PDM_InitField( &m_showP90Curve, "ShowP90Curve", true, "P90" );
CAF_PDM_InitField( &m_showMeanCurve, "ShowMeanCurve", true, "Mean" );
@@ -83,6 +89,9 @@ RimHistogramCurve::~RimHistogramCurve()
void RimHistogramCurve::initAfterRead()
{
setDataSource( m_dataSource );
// NB: m_dataSourceReference is not resolved yet. The signal connection for referenced data
// sources is established in onLoadDataAndUpdate().
}
//--------------------------------------------------------------------------------------------------
@@ -107,15 +116,64 @@ void RimHistogramCurve::setDataSource( RimHistogramDataSource* dataSource )
{
m_dataSource->uiCapability()->setUiTreeHidden( true );
m_dataSource->dataSourceChanged.connect( this, &RimHistogramCurve::onDataSourceChanged );
m_dataSource->cumulativeChanged.connect( this, &RimHistogramCurve::onCumulativeChanged );
}
}
//--------------------------------------------------------------------------------------------------
/// Use the data source owned by another curve. Used by cumulative curves, which share the data
/// source of their non-cumulative counterpart.
//--------------------------------------------------------------------------------------------------
void RimHistogramCurve::setDataSourceReference( RimHistogramDataSource* dataSource )
{
m_dataSourceReference = dataSource;
connectReferencedDataSourceSignals();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimHistogramCurve::connectReferencedDataSourceSignals()
{
if ( m_dataSourceReference() )
{
// Connecting an already connected observer is a no-op
m_dataSourceReference()->dataSourceChanged.connect( this, &RimHistogramCurve::onDataSourceChanged );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimHistogramCurve::setCumulative( bool cumulative )
{
m_isCumulative = cumulative;
if ( cumulative )
{
// The percentile annotations are shown by the non-cumulative counterpart curve
m_showP10Curve = false;
m_showP90Curve = false;
m_showMeanCurve = false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimHistogramCurve::isCumulative() const
{
return m_isCumulative();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimHistogramDataSource* RimHistogramCurve::dataSource() const
{
return m_dataSource;
if ( m_dataSource() ) return m_dataSource();
return m_dataSourceReference();
}
//--------------------------------------------------------------------------------------------------
@@ -134,8 +192,8 @@ RiuPlotAxis RimHistogramCurve::axisX() const
//--------------------------------------------------------------------------------------------------
std::string RimHistogramCurve::unitNameY() const
{
if ( m_dataSource )
return m_dataSource()->unitNameY();
if ( dataSource() )
return dataSource()->unitNameY();
else
return "";
}
@@ -145,8 +203,8 @@ std::string RimHistogramCurve::unitNameY() const
//--------------------------------------------------------------------------------------------------
std::string RimHistogramCurve::unitNameX() const
{
if ( m_dataSource )
return m_dataSource()->unitNameX();
if ( dataSource() )
return dataSource()->unitNameX();
else
return "";
}
@@ -156,10 +214,10 @@ std::string RimHistogramCurve::unitNameX() const
//--------------------------------------------------------------------------------------------------
std::vector<double> RimHistogramCurve::valuesY() const
{
if ( m_dataSource )
if ( dataSource() )
{
RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
return m_dataSource()->compute( plot->graphType(), plot->frequencyType() ).valuesY;
return dataSource()->compute( plot->graphType(), plot->frequencyType(), m_isCumulative() ).valuesY;
}
else
return {};
@@ -170,10 +228,10 @@ std::vector<double> RimHistogramCurve::valuesY() const
//--------------------------------------------------------------------------------------------------
std::vector<double> RimHistogramCurve::valuesX() const
{
if ( m_dataSource )
if ( dataSource() )
{
RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
return m_dataSource()->compute( plot->graphType(), plot->frequencyType() ).valuesX;
return dataSource()->compute( plot->graphType(), plot->frequencyType(), m_isCumulative() ).valuesX;
}
else
return {};
@@ -237,9 +295,10 @@ QList<caf::PdmOptionItemInfo> RimHistogramCurve::calculateValueOptions( const ca
QString RimHistogramCurve::createCurveAutoName()
{
QString curveName = "";
if ( m_dataSource )
if ( dataSource() )
{
curveName = QString::fromStdString( m_dataSource->name() );
curveName = QString::fromStdString( dataSource()->name() );
if ( m_isCumulative() ) curveName += ", Cumulative";
}
if ( curveName.isEmpty() )
@@ -271,11 +330,13 @@ void RimHistogramCurve::onLoadDataAndUpdate( bool updateParentPlot )
m_annotationTool->detachAllAnnotations();
if ( isChecked() && m_dataSource() )
connectReferencedDataSourceSignals();
if ( isChecked() && dataSource() )
{
RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
auto result = m_dataSource->compute( plot->graphType(), plot->frequencyType() );
auto result = dataSource()->compute( plot->graphType(), plot->frequencyType(), m_isCumulative() );
bool useLogarithmicScale = plot->isLogarithmicScaleEnabled( axisY() );
@@ -486,11 +547,84 @@ void RimHistogramCurve::onDataSourceChanged( const caf::SignalEmitter* emitter )
loadAndUpdateDataAndPlot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimHistogramCurve::onCumulativeChanged( const caf::SignalEmitter* emitter )
{
updateCumulativeCurve();
}
//--------------------------------------------------------------------------------------------------
/// Create or delete the cumulative companion curve to match the data source setting. The companion
/// curve shares this curve's data source and is shown on the right axis.
//--------------------------------------------------------------------------------------------------
void RimHistogramCurve::updateCumulativeCurve()
{
if ( m_isCumulative() || !m_dataSource() ) return;
auto plot = firstAncestorOrThisOfType<RimHistogramPlot>();
if ( !plot ) return;
RimHistogramCurve* cumulativeCurve = nullptr;
for ( RimHistogramCurve* curve : plot->histogramCurves() )
{
if ( curve != this && curve->isCumulative() && curve->dataSource() == m_dataSource() )
{
cumulativeCurve = curve;
break;
}
}
bool showCumulativeCurve = m_dataSource->showCumulativeCurve();
if ( showCumulativeCurve && !cumulativeCurve )
{
auto newCurve = new RimHistogramCurve();
newCurve->setCumulative( true );
newCurve->setDataSourceReference( m_dataSource() );
newCurve->setColor( color() );
newCurve->setFillStyle( Qt::NoBrush );
plot->addCurveNoUpdate( newCurve, false );
if ( !plot->axisPropertiesForPlotAxis( RiuPlotAxis::defaultRight() ) )
{
plot->addNewAxisProperties( RiuPlotAxis::defaultRight(), "Right" );
}
if ( plot->plotWidget() ) plot->plotWidget()->ensureAxisIsCreated( RiuPlotAxis::defaultRight() );
newCurve->setLeftOrRightAxisY( RiuPlotAxis::defaultRight() );
newCurve->setTopOrBottomAxisX( RiuPlotAxis::defaultBottom() );
newCurve->loadDataAndUpdate( true );
plot->updateAxes();
plot->updateConnectedEditors();
}
else if ( !showCumulativeCurve && cumulativeCurve )
{
auto curveCollection = cumulativeCurve->firstAncestorOrThisOfType<RimHistogramCurveCollection>();
if ( curveCollection )
{
curveCollection->deleteCurve( cumulativeCurve );
plot->updateAxes();
plot->updateConnectedEditors();
plot->scheduleReplotIfVisible();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimHistogramCurve::setAppearanceFromGraphType( RimHistogramPlot::GraphType graphType )
{
if ( m_isCumulative() )
{
// Cumulative curves are always drawn as lines, also when the histogram is a bar graph
setFillStyle( Qt::NoBrush );
setFillColorOpacity( 1.0 );
return;
}
auto fillType = graphType == RimHistogramPlot::GraphType::BAR_GRAPH ? Qt::SolidPattern : Qt::NoBrush;
setFillStyle( fillType );
float opacity = graphType == RimHistogramPlot::GraphType::BAR_GRAPH ? 0.2 : 1.0;
@@ -58,8 +58,12 @@ public:
void updateLegendEntryVisibilityNoPlotUpdate() override;
void setDataSource( RimHistogramDataSource* dataSource );
void setDataSourceReference( RimHistogramDataSource* dataSource );
void setAppearanceFromGraphType( RimHistogramPlot::GraphType graphType );
void setCumulative( bool cumulative );
bool isCumulative() const;
RimHistogramDataSource* dataSource() const;
protected:
@@ -83,6 +87,10 @@ protected:
void hideXAxisGroup();
void onDataSourceChanged( const caf::SignalEmitter* emitter );
void onCumulativeChanged( const caf::SignalEmitter* emitter );
void updateCumulativeCurve();
void connectReferencedDataSourceSignals();
void initAfterRead() override;
@@ -91,6 +99,9 @@ private:
caf::PdmPtrField<RimPlotAxisPropertiesInterface*> m_xPlotAxisProperties;
caf::PdmChildField<RimHistogramDataSource*> m_dataSource;
caf::PdmPtrField<RimHistogramDataSource*> m_dataSourceReference;
caf::PdmField<bool> m_isCumulative;
caf::PdmField<bool> m_showP10Curve;
caf::PdmField<bool> m_showP90Curve;
@@ -19,6 +19,7 @@
#include "RimHistogramCurveCollection.h"
#include "RimHistogramCurve.h"
#include "RimHistogramDataSource.h"
#include "RimHistogramPlot.h"
#include "cafPdmFieldReorderCapability.h"
@@ -262,6 +263,38 @@ void RimHistogramCurveCollection::onCurvesReordered( const SignalEmitter* emitte
void RimHistogramCurveCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects )
{
// Delete cumulative curves when the curve owning their referenced data source is deleted
std::vector<RimHistogramCurve*> orphanedCurves;
for ( RimHistogramCurve* curve : curves() )
{
if ( curve->isCumulative() && !curve->dataSource() ) orphanedCurves.push_back( curve );
}
for ( RimHistogramCurve* curve : orphanedCurves )
{
deleteCurve( curve );
}
// Uncheck "Show Cumulative Curve" on data sources whose cumulative curve was deleted
for ( RimHistogramCurve* curve : curves() )
{
if ( curve->isCumulative() ) continue;
RimHistogramDataSource* dataSource = curve->dataSource();
if ( !dataSource || !dataSource->showCumulativeCurve() ) continue;
bool hasCumulativeCurve = false;
for ( RimHistogramCurve* other : curves() )
{
if ( other->isCumulative() && other->dataSource() == dataSource )
{
hasCumulativeCurve = true;
break;
}
}
if ( !hasCumulativeCurve ) dataSource->setShowCumulativeCurve( false );
}
curvesChanged.send();
}
@@ -50,6 +50,8 @@ public:
void updateCurveOrder();
void deleteCurve( RimHistogramCurve* curve );
private:
void setParentPlotAndReplot( RiuPlotWidget* plot );
void setParentPlotNoReplot( RiuPlotWidget* plot );
@@ -58,7 +60,6 @@ private:
void addCurve( RimHistogramCurve* curve );
void insertCurve( RimHistogramCurve* curve, size_t index );
void deleteCurve( RimHistogramCurve* curve );
void removeCurve( RimHistogramCurve* curve );
void deleteAllCurves();
@@ -25,6 +25,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimHistogramDataSource, "HistogramDataSource"
//--------------------------------------------------------------------------------------------------
RimHistogramDataSource::RimHistogramDataSource()
: dataSourceChanged( this )
, cumulativeChanged( this )
{
CAF_PDM_InitObject( "Histogram Data Source", );
}
@@ -39,7 +40,23 @@ RimHistogramDataSource::~RimHistogramDataSource()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimHistogramDataSource::computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType )
bool RimHistogramDataSource::showCumulativeCurve() const
{
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimHistogramDataSource::setShowCumulativeCurve( bool showCumulativeCurve )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>
RimHistogramDataSource::computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType, bool cumulative )
{
const double binSize = ( max - min ) / numBins;
@@ -57,8 +74,9 @@ std::vector<double> RimHistogramDataSource::computeHistogramBins( double min, do
values.push_back( binMin );
values.push_back( binMax );
// Close last bar on right side
if ( i == numBins - 1 ) values.push_back( binMax );
// Close last bar on right side. A cumulative curve is not closed: it should end at its
// maximum instead of dropping back to zero.
if ( i == numBins - 1 && !cumulative ) values.push_back( binMax );
}
else if ( graphType == RimHistogramPlot::GraphType::LINE_GRAPH )
{
@@ -74,10 +92,11 @@ std::vector<double> RimHistogramDataSource::computeHistogramBins( double min, do
//--------------------------------------------------------------------------------------------------
std::vector<double> RimHistogramDataSource::computeHistogramFrequencies( const std::vector<size_t>& values,
RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType )
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative )
{
std::vector<double> valuesAsDouble( values.begin(), values.end() );
return computeHistogramFrequencies( valuesAsDouble, graphType, frequencyType );
return computeHistogramFrequencies( valuesAsDouble, graphType, frequencyType, cumulative );
}
//--------------------------------------------------------------------------------------------------
@@ -85,12 +104,15 @@ std::vector<double> RimHistogramDataSource::computeHistogramFrequencies( const s
//--------------------------------------------------------------------------------------------------
std::vector<double> RimHistogramDataSource::computeHistogramFrequencies( const std::vector<double>& values,
RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType )
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative )
{
double sumElements = 0.0;
for ( double value : values )
sumElements += value;
double runningSum = 0.0;
std::vector<double> frequencies;
for ( size_t i = 0; i < values.size(); i++ )
{
@@ -98,6 +120,12 @@ std::vector<double> RimHistogramDataSource::computeHistogramFrequencies( const s
if ( frequencyType == RimHistogramPlot::FrequencyType::RELATIVE_FREQUENCY ) value /= sumElements;
if ( frequencyType == RimHistogramPlot::FrequencyType::RELATIVE_FREQUENCY_PERCENT ) value = value / sumElements * 100.0;
if ( cumulative )
{
runningSum += value;
value = runningSum;
}
if ( graphType == RimHistogramPlot::GraphType::BAR_GRAPH )
{
// Close first bar on left side
@@ -106,8 +134,9 @@ std::vector<double> RimHistogramDataSource::computeHistogramFrequencies( const s
frequencies.push_back( value );
frequencies.push_back( value );
// Close last bar on right side
if ( i == values.size() - 1 ) frequencies.push_back( 0.0 );
// Close last bar on right side. A cumulative curve is not closed: it should end at its
// maximum instead of dropping back to zero.
if ( i == values.size() - 1 && !cumulative ) frequencies.push_back( 0.0 );
}
else if ( graphType == RimHistogramPlot::GraphType::LINE_GRAPH )
{
@@ -53,21 +53,29 @@ public:
~RimHistogramDataSource() override;
caf::Signal<> dataSourceChanged;
caf::Signal<> cumulativeChanged;
virtual std::string unitNameX() const = 0;
virtual std::string unitNameY() const = 0;
virtual HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const = 0;
virtual HistogramResult
compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType, bool cumulative = false ) const = 0;
virtual bool showCumulativeCurve() const;
virtual void setShowCumulativeCurve( bool showCumulativeCurve );
virtual void setDefaults() = 0;
virtual std::string name() const = 0;
static std::vector<double> computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType );
static std::vector<double>
computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType, bool cumulative = false );
static std::vector<double> computeHistogramFrequencies( const std::vector<size_t>& values,
RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType );
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative = false );
static std::vector<double> computeHistogramFrequencies( const std::vector<double>& values,
RimHistogramPlot::GraphType graphType,
RimHistogramPlot::FrequencyType frequencyType );
RimHistogramPlot::FrequencyType frequencyType,
bool cumulative = false );
};
@@ -222,13 +222,14 @@ QString RimHistogramPlot::asciiDataForPlotExport() const
if ( !curve->isChecked() || !curve->dataSource() ) continue;
// Compute as line graph to get one value per bin, independent of how the curve is rendered
auto result = curve->dataSource()->compute( GraphType::LINE_GRAPH, frequencyType() );
auto result = curve->dataSource()->compute( GraphType::LINE_GRAPH, frequencyType(), curve->isCumulative() );
if ( result.valuesX.empty() || result.valuesX.size() != result.valuesY.size() ) continue;
QString headerX = "Bin Center";
if ( !curve->unitNameX().empty() ) headerX += QString( " [%1]" ).arg( QString::fromStdString( curve->unitNameX() ) );
QString headerY = caf::AppEnum<FrequencyType>::uiText( frequencyType() );
if ( curve->isCumulative() ) headerY = "Cumulative " + headerY;
if ( !curve->unitNameY().empty() ) headerY += QString( " [%1]" ).arg( QString::fromStdString( curve->unitNameY() ) );
QString tableText;
@@ -20,14 +20,11 @@
#include "Rim3dOverlayInfoConfig.h"
#include "RiaGuiApplication.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
#include "RiaQDateTimeTools.h"
#include "RiuMessageDialog.h"
#include "RicGridStatisticsDialog.h"
#include "ContourMap/RigContourMapProjection.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
@@ -236,31 +233,6 @@ QString Rim3dOverlayInfoConfig::sampleCountText( const std::vector<size_t>& hist
return QString( "<br><b>Sample Count:</b> %1" ).arg( text );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicGridStatisticsDialog* Rim3dOverlayInfoConfig::getOrCreateGridStatisticsDialog()
{
if ( !m_gridStatisticsDialog )
{
m_gridStatisticsDialog = new RicGridStatisticsDialog( RiaGuiApplication::widgetToUseAsParent() );
}
CVF_ASSERT( m_gridStatisticsDialog );
return m_gridStatisticsDialog;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage Rim3dOverlayInfoConfig::statisticsDialogScreenShotImage()
{
if ( getOrCreateGridStatisticsDialog()->isVisible() )
{
return getOrCreateGridStatisticsDialog()->screenShotImage();
}
return QImage();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -740,29 +712,6 @@ QString Rim3dOverlayInfoConfig::resultInfoText( const RigHistogramData& histData
return infoText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dOverlayInfoConfig::showStatisticsInfoDialog( bool raise )
{
auto gridView = dynamic_cast<RimGridView*>( m_viewDef.p() );
if ( gridView )
{
RicGridStatisticsDialog* dialog = getOrCreateGridStatisticsDialog();
// Show dialog before setting data due to text edit auto height setting
dialog->resize( 600, 800 );
dialog->show();
dialog->setLabel( "Grid statistics" );
dialog->updateFromRimView( gridView );
if ( raise )
{
dialog->raise();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -806,9 +755,6 @@ void Rim3dOverlayInfoConfig::update3DInfo()
m_showVolumeWeightedMean = false;
}
updateEclipse3DInfo( reservoirView );
// Update statistics dialog
getOrCreateGridStatisticsDialog()->updateFromRimView( reservoirView );
}
RimGeoMechView* geoMechView = dynamic_cast<RimGeoMechView*>( m_viewDef.p() );
@@ -817,9 +763,6 @@ void Rim3dOverlayInfoConfig::update3DInfo()
m_showVolumeWeightedMean = false;
updateGeoMech3DInfo( geoMechView );
// Update statistics dialog
getOrCreateGridStatisticsDialog()->updateFromRimView( geoMechView );
}
RimSeismicView* seisView = dynamic_cast<RimSeismicView*>( m_viewDef.p() );
@@ -29,8 +29,6 @@
#include "cvfVector2.h"
#include <QPointer>
#include <cmath>
#include <memory>
@@ -39,7 +37,6 @@ class RimEclipseContourMapView;
class RimEclipseView;
class RimGeoMechView;
class Rim3dView;
class RicGridStatisticsDialog;
class RimSeismicView;
//==================================================================================================
@@ -65,10 +62,6 @@ public:
QString caseInfoText();
QString resultInfoText( const RigHistogramData& histData );
RicGridStatisticsDialog* getOrCreateGridStatisticsDialog();
void showStatisticsInfoDialog( bool raise = true );
QImage statisticsDialogScreenShotImage();
bool showAnimProgress() const;
bool showCaseInfo() const;
bool showResultInfo() const;
@@ -113,6 +106,4 @@ private:
cvf::Vec2ui m_position;
std::unique_ptr<RimHistogramCalculator> m_histogramCalculator;
QPointer<RicGridStatisticsDialog> m_gridStatisticsDialog;
};
@@ -881,7 +881,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
else if ( dynamic_cast<Rim3dOverlayInfoConfig*>( firstUiItem ) )
{
menuBuilder << "RicCreateGridStatisticsPlotFeature";
menuBuilder << "RicShowGridStatisticsFeature";
}
else if ( dynamic_cast<RimValveTemplateCollection*>( firstUiItem ) )
{