mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Well Allocation over time adjustements (#9738)
- Add font size settings - Move legend to right side of plot - Set default selected time steps to time step count = 10 - When excluding time steps, duplicates rates from next valid time step onto excluded time steps - Allow time step selection "Show all time steps" or "Time step count" for subset of time steps - Allow excluding on the active set, i.e. all or subset, of time steps
This commit is contained in:
parent
0fcbf0f821
commit
6f34a730a0
@ -33,9 +33,8 @@ RimWellAllocationOverTimeCollection::RimWellAllocationOverTimeCollection(
|
|||||||
const std::vector<QDateTime>& timeStepDates,
|
const std::vector<QDateTime>& timeStepDates,
|
||||||
const std::map<QDateTime, RigAccWellFlowCalculator>& timeStepAndCalculatorPairs )
|
const std::map<QDateTime, RigAccWellFlowCalculator>& timeStepAndCalculatorPairs )
|
||||||
: m_timeStepDates( timeStepDates )
|
: m_timeStepDates( timeStepDates )
|
||||||
, m_timeStepAndCalculatorPairs( timeStepAndCalculatorPairs )
|
|
||||||
{
|
{
|
||||||
for ( const auto& [date, calculator] : m_timeStepAndCalculatorPairs )
|
for ( const auto& [date, calculator] : timeStepAndCalculatorPairs )
|
||||||
{
|
{
|
||||||
std::string err = "Calculator for time step date " + date.toString().toStdString() +
|
std::string err = "Calculator for time step date " + date.toString().toStdString() +
|
||||||
" does not exist in time step dates vector ";
|
" does not exist in time step dates vector ";
|
||||||
@ -43,6 +42,25 @@ RimWellAllocationOverTimeCollection::RimWellAllocationOverTimeCollection(
|
|||||||
err.data() );
|
err.data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Time steps not present in input map is considered "excluded" time steps
|
||||||
|
// Build new time step and calculator map using calculator for "next" valid time step for
|
||||||
|
// "excluded" time steps
|
||||||
|
QDateTime prevValidTimeStep;
|
||||||
|
for ( auto it = m_timeStepDates.rbegin(); it != m_timeStepDates.rend(); ++it )
|
||||||
|
{
|
||||||
|
const QDateTime& timeStep = *it;
|
||||||
|
if ( timeStepAndCalculatorPairs.contains( timeStep ) )
|
||||||
|
{
|
||||||
|
m_timeStepAndCalculatorPairs.emplace( timeStep, timeStepAndCalculatorPairs.at( timeStep ) );
|
||||||
|
prevValidTimeStep = timeStep;
|
||||||
|
}
|
||||||
|
else if ( prevValidTimeStep.isValid() )
|
||||||
|
{
|
||||||
|
// If no calculator for this time step, use the previous valid time step calculator
|
||||||
|
m_timeStepAndCalculatorPairs.emplace( timeStep, timeStepAndCalculatorPairs.at( prevValidTimeStep ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::sort( m_timeStepDates.begin(), m_timeStepDates.end() );
|
std::sort( m_timeStepDates.begin(), m_timeStepDates.end() );
|
||||||
|
|
||||||
// Retrieve union of well names across all calculators
|
// Retrieve union of well names across all calculators
|
||||||
|
@ -47,8 +47,8 @@ private:
|
|||||||
double threshold );
|
double threshold );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::map<QDateTime, RigAccWellFlowCalculator>& m_timeStepAndCalculatorPairs;
|
std::map<QDateTime, RigAccWellFlowCalculator> m_timeStepAndCalculatorPairs;
|
||||||
std::vector<QDateTime> m_timeStepDates;
|
std::vector<QDateTime> m_timeStepDates;
|
||||||
std::map<QString, std::map<QDateTime, double>> m_defaultWellValuesMap;
|
std::map<QString, std::map<QDateTime, double>> m_defaultWellValuesMap;
|
||||||
std::map<QString, std::map<QDateTime, double>> m_wellValuesMap;
|
std::map<QString, std::map<QDateTime, double>> m_wellValuesMap;
|
||||||
};
|
};
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "RiuQwtPlotWidget.h"
|
#include "RiuQwtPlotWidget.h"
|
||||||
|
|
||||||
#include "cafCmdFeatureMenuBuilder.h"
|
#include "cafCmdFeatureMenuBuilder.h"
|
||||||
|
#include "cafFontTools.h"
|
||||||
#include "cafPdmUiComboBoxEditor.h"
|
#include "cafPdmUiComboBoxEditor.h"
|
||||||
#include "cafPdmUiPushButtonEditor.h"
|
#include "cafPdmUiPushButtonEditor.h"
|
||||||
#include "cafPdmUiTreeSelectionEditor.h"
|
#include "cafPdmUiTreeSelectionEditor.h"
|
||||||
@ -79,6 +80,20 @@ void AppEnum<RimWellAllocationOverTimePlot::FlowValueType>::setUp()
|
|||||||
}
|
}
|
||||||
} // namespace caf
|
} // namespace caf
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
namespace caf
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
void AppEnum<RimWellAllocationOverTimePlot::TimeStepFilterMode>::setUp()
|
||||||
|
{
|
||||||
|
addItem( RimWellAllocationOverTimePlot::TimeStepFilterMode::NONE, "NONE", "Show All Time Steps" );
|
||||||
|
addItem( RimWellAllocationOverTimePlot::TimeStepFilterMode::TIME_STEP_COUNT, "TIME_STEP_COUNT", "Time Step Count" );
|
||||||
|
setDefault( RimWellAllocationOverTimePlot::TimeStepFilterMode::TIME_STEP_COUNT );
|
||||||
|
}
|
||||||
|
} // namespace caf
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -97,16 +112,25 @@ RimWellAllocationOverTimePlot::RimWellAllocationOverTimePlot()
|
|||||||
m_selectedFromTimeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
m_selectedFromTimeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_selectedToTimeStep, "ToTimeStep", "To Time Step" );
|
CAF_PDM_InitFieldNoDefault( &m_selectedToTimeStep, "ToTimeStep", "To Time Step" );
|
||||||
m_selectedToTimeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
m_selectedToTimeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_timeStepFilterMode, "TimeStepFilterMode", "Filter" );
|
||||||
|
m_timeStepFilterMode.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||||
|
CAF_PDM_InitField( &m_timeStepCount, "TimeStepCount", m_initialNumberOfTimeSteps, "Number of Time Steps" );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_excludeTimeSteps, "ExcludeTimeSteps", "" );
|
CAF_PDM_InitFieldNoDefault( &m_excludeTimeSteps, "ExcludeTimeSteps", "" );
|
||||||
m_excludeTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
m_excludeTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_applyExcludeTimeSteps, "ApplyExcludeTimeSteps", "" );
|
CAF_PDM_InitFieldNoDefault( &m_applyTimeStepSelections, "ApplyTimeStepSelections", "" );
|
||||||
caf::PdmUiPushButtonEditor::configureEditorForField( &m_applyExcludeTimeSteps );
|
caf::PdmUiPushButtonEditor::configureEditorForField( &m_applyTimeStepSelections );
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault( &m_flowDiagSolution, "FlowDiagSolution", "Plot Type" );
|
CAF_PDM_InitFieldNoDefault( &m_flowDiagSolution, "FlowDiagSolution", "Plot Type" );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_flowValueType, "FlowValueType", "Value Type" );
|
CAF_PDM_InitFieldNoDefault( &m_flowValueType, "FlowValueType", "Value Type" );
|
||||||
CAF_PDM_InitField( &m_groupSmallContributions, "GroupSmallContributions", true, "Group Small Contributions" );
|
CAF_PDM_InitField( &m_groupSmallContributions, "GroupSmallContributions", true, "Group Small Contributions" );
|
||||||
CAF_PDM_InitField( &m_smallContributionsThreshold, "SmallContributionsThreshold", 0.005, "Threshold" );
|
CAF_PDM_InitField( &m_smallContributionsThreshold, "SmallContributionsThreshold", 0.005, "Threshold" );
|
||||||
|
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_axisTitleFontSize, "AxisTitleFontSize", "Axis Title Font Size" );
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_axisValueFontSize, "AxisValueFontSize", "Axis Value Font Size" );
|
||||||
|
m_axisTitleFontSize = caf::FontTools::RelativeSize::Large;
|
||||||
|
m_axisValueFontSize = caf::FontTools::RelativeSize::Medium;
|
||||||
|
m_legendFontSize = caf::FontTools::RelativeSize::Medium;
|
||||||
|
|
||||||
setAsPlotMdiWindow();
|
setAsPlotMdiWindow();
|
||||||
setShowWindow( false );
|
setShowWindow( false );
|
||||||
}
|
}
|
||||||
@ -226,6 +250,14 @@ QImage RimWellAllocationOverTimePlot::snapshotWindowContent()
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimWellAllocationOverTimePlot::isCurveHighlightSupported() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -247,14 +279,19 @@ RiuPlotWidget* RimWellAllocationOverTimePlot::doCreatePlotViewWidget( QWidget* m
|
|||||||
new RiuContextMenuLauncher( plotWidget, menuBuilder );
|
new RiuContextMenuLauncher( plotWidget, menuBuilder );
|
||||||
|
|
||||||
m_plotWidget = plotWidget;
|
m_plotWidget = plotWidget;
|
||||||
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), true );
|
|
||||||
|
|
||||||
RiuQwtPlotTools::enableDateBasedBottomXAxis( m_plotWidget->qwtPlot(),
|
RiuQwtPlotTools::enableDateBasedBottomXAxis( m_plotWidget->qwtPlot(),
|
||||||
RiaPreferences::current()->dateFormat(),
|
RiaPreferences::current()->dateFormat(),
|
||||||
QString(),
|
QString(),
|
||||||
RiaDefines::DateFormatComponents::DATE_FORMAT_YEAR_MONTH_DAY,
|
RiaDefines::DateFormatComponents::DATE_FORMAT_YEAR_MONTH_DAY,
|
||||||
RiaDefines::TimeFormatComponents::TIME_FORMAT_NONE );
|
RiaDefines::TimeFormatComponents::TIME_FORMAT_NONE );
|
||||||
|
|
||||||
|
// Workaround: Enable axis title for bottom axis to activate correct font size for date axis
|
||||||
|
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultBottom(), true );
|
||||||
|
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), true );
|
||||||
|
m_plotWidget->insertLegend( RiuPlotWidget::Legend::RIGHT );
|
||||||
|
|
||||||
|
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultBottom(), "[Date]" );
|
||||||
|
|
||||||
updateLegend();
|
updateLegend();
|
||||||
onLoadDataAndUpdate();
|
onLoadDataAndUpdate();
|
||||||
|
|
||||||
@ -294,6 +331,25 @@ void RimWellAllocationOverTimePlot::onLoadDataAndUpdate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateFromWell();
|
updateFromWell();
|
||||||
|
|
||||||
|
// Must be called after curves are added to plot - to apply correct legend font size
|
||||||
|
doUpdateLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimWellAllocationOverTimePlot::doUpdateLayout()
|
||||||
|
{
|
||||||
|
if ( m_plotWidget == nullptr )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_plotWidget->setPlotTitleFontSize( titleFontSize() );
|
||||||
|
m_plotWidget->setLegendFontSize( legendFontSize() );
|
||||||
|
m_plotWidget->setAxisFontsAndAlignment( RiuPlotAxis::defaultBottom(), axisTitleFontSize(), axisValueFontSize() );
|
||||||
|
m_plotWidget->setAxisFontsAndAlignment( RiuPlotAxis::defaultLeft(), axisTitleFontSize(), axisValueFontSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -305,7 +361,6 @@ void RimWellAllocationOverTimePlot::updateFromWell()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_plotWidget->insertLegend( RiuPlotWidget::Legend::BOTTOM );
|
|
||||||
m_plotWidget->detachItems( RiuPlotWidget::PlotItemType::CURVE );
|
m_plotWidget->detachItems( RiuPlotWidget::PlotItemType::CURVE );
|
||||||
|
|
||||||
// Retrieve collection of total fraction data for wells
|
// Retrieve collection of total fraction data for wells
|
||||||
@ -346,9 +401,22 @@ void RimWellAllocationOverTimePlot::updateFromWell()
|
|||||||
setDescription( newDescription );
|
setDescription( newDescription );
|
||||||
m_plotWidget->setWindowTitle( newDescription );
|
m_plotWidget->setWindowTitle( newDescription );
|
||||||
m_plotWidget->setPlotTitle( descriptionText + "<br>" + valueTypeText + "</br>" );
|
m_plotWidget->setPlotTitle( descriptionText + "<br>" + valueTypeText + "</br>" );
|
||||||
|
|
||||||
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultLeft(), valueTypeText );
|
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultLeft(), valueTypeText );
|
||||||
m_plotWidget->scheduleReplot();
|
|
||||||
|
if ( m_plotWidget->qwtPlot() )
|
||||||
|
{
|
||||||
|
m_plotWidget->qwtPlot()->replot();
|
||||||
|
|
||||||
|
// Workaround: For some reason, the ordering of items is not updated correctly. Adjusting the z-value of curves
|
||||||
|
// will trigger a replot of items in correct order.
|
||||||
|
|
||||||
|
auto plotItemList = m_plotWidget->qwtPlot()->itemList();
|
||||||
|
for ( QwtPlotItem* plotItem : plotItemList )
|
||||||
|
{
|
||||||
|
auto zValue = plotItem->z() + 1;
|
||||||
|
plotItem->setZ( zValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -383,21 +451,17 @@ RimWellAllocationOverTimeCollection RimWellAllocationOverTimePlot::createWellAll
|
|||||||
? m_smallContributionsThreshold
|
? m_smallContributionsThreshold
|
||||||
: 0.0;
|
: 0.0;
|
||||||
|
|
||||||
auto isTimeStepInSelectedRange = [&]( const QDateTime& timeStep ) -> bool {
|
const bool branchDetection = false;
|
||||||
return m_selectedFromTimeStep() <= timeStep && timeStep <= m_selectedToTimeStep();
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<QDateTime, RigAccWellFlowCalculator> timeStepAndCalculatorPairs;
|
std::map<QDateTime, RigAccWellFlowCalculator> timeStepAndCalculatorPairs;
|
||||||
std::set<QDateTime> excludedTimeSteps = std::set( m_excludeTimeSteps().begin(), m_excludeTimeSteps().end() );
|
std::vector<QDateTime> allTimeSteps = m_case->timeStepDates();
|
||||||
std::vector<QDateTime> allTimeSteps = m_case->timeStepDates();
|
std::set<QDateTime> selectedTimeSteps = getSelectedTimeSteps( allTimeSteps );
|
||||||
std::vector<QDateTime> selectedTimeSteps;
|
std::set<QDateTime> excludedTimeSteps = std::set( m_excludeTimeSteps().begin(), m_excludeTimeSteps().end() );
|
||||||
std::copy_if( allTimeSteps.begin(), allTimeSteps.end(), std::back_inserter( selectedTimeSteps ), isTimeStepInSelectedRange );
|
|
||||||
|
|
||||||
const bool branchDetection = false;
|
// NOTE: Must iterate all time step dates for case to have correct time step index for simulation well data
|
||||||
for ( size_t i = 0; i < allTimeSteps.size(); ++i )
|
for ( size_t i = 0; i < allTimeSteps.size(); ++i )
|
||||||
{
|
{
|
||||||
// NOTE: Must have all time step dates for case due to have correct time step index for simulation well data
|
// Time step must be among selected time steps and not excluded
|
||||||
if ( !isTimeStepInSelectedRange( allTimeSteps[i] ) ||
|
if ( selectedTimeSteps.find( allTimeSteps[i] ) == selectedTimeSteps.end() ||
|
||||||
excludedTimeSteps.find( allTimeSteps[i] ) != excludedTimeSteps.end() )
|
excludedTimeSteps.find( allTimeSteps[i] ) != excludedTimeSteps.end() )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -446,7 +510,8 @@ RimWellAllocationOverTimeCollection RimWellAllocationOverTimePlot::createWellAll
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create collection
|
// Create collection
|
||||||
RimWellAllocationOverTimeCollection collection( selectedTimeSteps, timeStepAndCalculatorPairs );
|
const auto selectedTimeStepsVector = std::vector( selectedTimeSteps.begin(), selectedTimeSteps.end() );
|
||||||
|
RimWellAllocationOverTimeCollection collection( selectedTimeStepsVector, timeStepAndCalculatorPairs );
|
||||||
|
|
||||||
if ( m_flowValueType == FlowValueType::FLOW_RATE_PERCENTAGE )
|
if ( m_flowValueType == FlowValueType::FLOW_RATE_PERCENTAGE )
|
||||||
{
|
{
|
||||||
@ -506,11 +571,19 @@ void RimWellAllocationOverTimePlot::defineUiOrdering( QString uiConfigName, caf:
|
|||||||
caf::PdmUiGroup& timeStepGroup = *uiOrdering.addNewGroup( "Time Step" );
|
caf::PdmUiGroup& timeStepGroup = *uiOrdering.addNewGroup( "Time Step" );
|
||||||
timeStepGroup.add( &m_selectedFromTimeStep );
|
timeStepGroup.add( &m_selectedFromTimeStep );
|
||||||
timeStepGroup.add( &m_selectedToTimeStep );
|
timeStepGroup.add( &m_selectedToTimeStep );
|
||||||
|
timeStepGroup.add( &m_timeStepFilterMode );
|
||||||
|
|
||||||
|
if ( m_timeStepFilterMode == TimeStepFilterMode::TIME_STEP_COUNT )
|
||||||
|
{
|
||||||
|
timeStepGroup.add( &m_timeStepCount );
|
||||||
|
}
|
||||||
|
|
||||||
caf::PdmUiGroup& excludeTimeStepGroup = *timeStepGroup.addNewGroup( "Exclude Time Steps" );
|
caf::PdmUiGroup& excludeTimeStepGroup = *timeStepGroup.addNewGroup( "Exclude Time Steps" );
|
||||||
excludeTimeStepGroup.add( &m_excludeTimeSteps );
|
excludeTimeStepGroup.add( &m_excludeTimeSteps );
|
||||||
excludeTimeStepGroup.add( &m_applyExcludeTimeSteps );
|
|
||||||
excludeTimeStepGroup.setCollapsedByDefault();
|
excludeTimeStepGroup.setCollapsedByDefault();
|
||||||
|
|
||||||
|
timeStepGroup.add( &m_applyTimeStepSelections );
|
||||||
|
|
||||||
caf::PdmUiGroup& optionGroup = *uiOrdering.addNewGroup( "Options" );
|
caf::PdmUiGroup& optionGroup = *uiOrdering.addNewGroup( "Options" );
|
||||||
optionGroup.add( &m_flowDiagSolution );
|
optionGroup.add( &m_flowDiagSolution );
|
||||||
optionGroup.add( &m_flowValueType );
|
optionGroup.add( &m_flowValueType );
|
||||||
@ -518,6 +591,12 @@ void RimWellAllocationOverTimePlot::defineUiOrdering( QString uiConfigName, caf:
|
|||||||
optionGroup.add( &m_smallContributionsThreshold );
|
optionGroup.add( &m_smallContributionsThreshold );
|
||||||
m_smallContributionsThreshold.uiCapability()->setUiReadOnly( !m_groupSmallContributions() );
|
m_smallContributionsThreshold.uiCapability()->setUiReadOnly( !m_groupSmallContributions() );
|
||||||
|
|
||||||
|
caf::PdmUiGroup* fontGroup = uiOrdering.addNewGroup( "Fonts" );
|
||||||
|
fontGroup->setCollapsedByDefault();
|
||||||
|
RimPlotWindow::uiOrderingForFonts( uiConfigName, *fontGroup );
|
||||||
|
fontGroup->add( &m_axisTitleFontSize );
|
||||||
|
fontGroup->add( &m_axisValueFontSize );
|
||||||
|
|
||||||
uiOrdering.skipRemainingFields( true );
|
uiOrdering.skipRemainingFields( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +607,7 @@ void RimWellAllocationOverTimePlot::defineEditorAttribute( const caf::PdmFieldHa
|
|||||||
QString uiConfigName,
|
QString uiConfigName,
|
||||||
caf::PdmUiEditorAttribute* attribute )
|
caf::PdmUiEditorAttribute* attribute )
|
||||||
{
|
{
|
||||||
if ( field == &m_applyExcludeTimeSteps )
|
if ( field == &m_applyTimeStepSelections )
|
||||||
{
|
{
|
||||||
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
||||||
if ( attrib )
|
if ( attrib )
|
||||||
@ -570,12 +649,22 @@ void RimWellAllocationOverTimePlot::fieldChangedByUi( const caf::PdmFieldHandle*
|
|||||||
onLoadDataAndUpdate();
|
onLoadDataAndUpdate();
|
||||||
}
|
}
|
||||||
else if ( changedField == &m_wellName || changedField == &m_flowDiagSolution || changedField == &m_flowValueType ||
|
else if ( changedField == &m_wellName || changedField == &m_flowDiagSolution || changedField == &m_flowValueType ||
|
||||||
changedField == &m_groupSmallContributions || changedField == &m_smallContributionsThreshold ||
|
changedField == &m_groupSmallContributions || changedField == &m_smallContributionsThreshold )
|
||||||
changedField == &m_selectedFromTimeStep || changedField == &m_selectedToTimeStep ||
|
|
||||||
changedField == &m_applyExcludeTimeSteps )
|
|
||||||
{
|
{
|
||||||
onLoadDataAndUpdate();
|
onLoadDataAndUpdate();
|
||||||
}
|
}
|
||||||
|
else if ( changedField == &m_timeStepCount && m_timeStepFilterMode == TimeStepFilterMode::TIME_STEP_COUNT )
|
||||||
|
{
|
||||||
|
m_excludeTimeSteps.setValue( {} );
|
||||||
|
}
|
||||||
|
else if ( changedField == &m_applyTimeStepSelections )
|
||||||
|
{
|
||||||
|
onLoadDataAndUpdate();
|
||||||
|
}
|
||||||
|
else if ( changedField == &m_axisTitleFontSize || changedField == &m_axisValueFontSize )
|
||||||
|
{
|
||||||
|
doUpdateLayout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -632,8 +721,7 @@ QList<caf::PdmOptionItemInfo>
|
|||||||
options.push_back( caf::PdmOptionItemInfo( "Allocation", defaultFlowSolution ) );
|
options.push_back( caf::PdmOptionItemInfo( "Allocation", defaultFlowSolution ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( m_case && ( fieldNeedingOptions == &m_excludeTimeSteps || fieldNeedingOptions == &m_selectedFromTimeStep ||
|
else if ( m_case && ( fieldNeedingOptions == &m_selectedFromTimeStep || fieldNeedingOptions == &m_selectedToTimeStep ) )
|
||||||
fieldNeedingOptions == &m_selectedToTimeStep ) )
|
|
||||||
{
|
{
|
||||||
const QString dateFormatStr = dateFormatString();
|
const QString dateFormatStr = dateFormatString();
|
||||||
const auto timeSteps = m_case->timeStepDates();
|
const auto timeSteps = m_case->timeStepDates();
|
||||||
@ -642,6 +730,19 @@ QList<caf::PdmOptionItemInfo>
|
|||||||
options.push_back( caf::PdmOptionItemInfo( timeStep.toString( dateFormatStr ), timeStep ) );
|
options.push_back( caf::PdmOptionItemInfo( timeStep.toString( dateFormatStr ), timeStep ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( m_case && ( fieldNeedingOptions == &m_excludeTimeSteps ) )
|
||||||
|
{
|
||||||
|
const QString dateFormatStr = dateFormatString();
|
||||||
|
const auto selectedTimeSteps = getSelectedTimeSteps( m_case->timeStepDates() );
|
||||||
|
for ( const auto& timeStep : selectedTimeSteps )
|
||||||
|
{
|
||||||
|
options.push_back( caf::PdmOptionItemInfo( timeStep.toString( dateFormatStr ), timeStep ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( fieldNeedingOptions == &m_axisTitleFontSize || fieldNeedingOptions == &m_axisValueFontSize )
|
||||||
|
{
|
||||||
|
options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() );
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +803,7 @@ QString RimWellAllocationOverTimePlot::dateFormatString() const
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Update selected "From Time Step" and "To Time Step" according to selected case.
|
/// Update selected "From Time Step" and "To Time Step" according to selected case.
|
||||||
/// If both selected time steps exist for case, keep as is. Otherwise set the 10 last time steps
|
/// If both selected time steps exist for case, keep as is. Otherwise set the 10 first time steps
|
||||||
/// for case. If less than 10 time steps exist, all are selected.
|
/// for case. If less than 10 time steps exist, all are selected.
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RimWellAllocationOverTimePlot::setValidTimeStepRangeForCase()
|
void RimWellAllocationOverTimePlot::setValidTimeStepRangeForCase()
|
||||||
@ -722,7 +823,101 @@ void RimWellAllocationOverTimePlot::setValidTimeStepRangeForCase()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numTimeSteps = m_case->timeStepDates().size();
|
m_selectedFromTimeStep = m_case->timeStepDates().front();
|
||||||
m_selectedToTimeStep = m_case->timeStepDates().back();
|
m_selectedToTimeStep = m_case->timeStepDates().back();
|
||||||
m_selectedFromTimeStep = m_case->timeStepDates().at( std::max( numTimeSteps - m_initialNumberOfTimeSteps, 0 ) );
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
int RimWellAllocationOverTimePlot::axisTitleFontSize() const
|
||||||
|
{
|
||||||
|
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisTitleFontSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
int RimWellAllocationOverTimePlot::axisValueFontSize() const
|
||||||
|
{
|
||||||
|
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisValueFontSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<QDateTime>
|
||||||
|
RimWellAllocationOverTimePlot::getTimeStepsWithinSelectedRange( const std::vector<QDateTime>& timeSteps ) const
|
||||||
|
{
|
||||||
|
std::vector<QDateTime> selectedTimeSteps;
|
||||||
|
auto isTimeStepInSelectedRange = [&]( const QDateTime& timeStep ) -> bool {
|
||||||
|
return m_selectedFromTimeStep() <= timeStep && timeStep <= m_selectedToTimeStep();
|
||||||
|
};
|
||||||
|
std::copy_if( timeSteps.begin(), timeSteps.end(), std::back_inserter( selectedTimeSteps ), isTimeStepInSelectedRange );
|
||||||
|
|
||||||
|
return selectedTimeSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::set<QDateTime> RimWellAllocationOverTimePlot::getSelectedTimeSteps( const std::vector<QDateTime>& timeSteps ) const
|
||||||
|
{
|
||||||
|
const auto timeStepsInRange = getTimeStepsWithinSelectedRange( timeSteps );
|
||||||
|
return m_timeStepFilterMode == TimeStepFilterMode::TIME_STEP_COUNT
|
||||||
|
? createEvenlyDistributedDates( timeStepsInRange, m_timeStepCount )
|
||||||
|
: std::set( timeStepsInRange.begin(), timeStepsInRange.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::set<QDateTime>
|
||||||
|
RimWellAllocationOverTimePlot::createEvenlyDistributedDates( const std::vector<QDateTime>& inputDates, int numDates )
|
||||||
|
{
|
||||||
|
std::set<QDateTime> outputDates;
|
||||||
|
if ( inputDates.empty() || numDates <= 0 )
|
||||||
|
{
|
||||||
|
return outputDates;
|
||||||
|
}
|
||||||
|
if ( static_cast<size_t>( numDates ) > inputDates.size() )
|
||||||
|
{
|
||||||
|
outputDates = std::set( inputDates.begin(), inputDates.end() );
|
||||||
|
return outputDates;
|
||||||
|
}
|
||||||
|
if ( numDates == 1 )
|
||||||
|
{
|
||||||
|
outputDates = { inputDates.front() };
|
||||||
|
return outputDates;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the minimum and maximum dates in the input vector
|
||||||
|
QDateTime minDate = *std::min_element( inputDates.begin(), inputDates.end() );
|
||||||
|
QDateTime maxDate = *std::max_element( inputDates.begin(), inputDates.end() );
|
||||||
|
|
||||||
|
// Calculate the time step between each selected date
|
||||||
|
qint64 timeStep =
|
||||||
|
( maxDate.toMSecsSinceEpoch() - minDate.toMSecsSinceEpoch() ) / ( static_cast<qint64>( numDates ) - 1 );
|
||||||
|
|
||||||
|
// Find the index of the input date that is closest to each new date
|
||||||
|
for ( int i = 0; i < numDates; ++i )
|
||||||
|
{
|
||||||
|
qint64 targetTime = minDate.toMSecsSinceEpoch() + i * timeStep;
|
||||||
|
int closestIndex = 0;
|
||||||
|
qint64 closestTimeDiff = std::numeric_limits<qint64>::max();
|
||||||
|
for ( size_t j = 0; j < inputDates.size(); ++j )
|
||||||
|
{
|
||||||
|
qint64 timeDiff = std::abs( inputDates[j].toMSecsSinceEpoch() - targetTime );
|
||||||
|
if ( timeDiff < closestTimeDiff )
|
||||||
|
{
|
||||||
|
closestIndex = j;
|
||||||
|
closestTimeDiff = timeDiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the closest date to the output vector
|
||||||
|
outputDates.insert( inputDates[closestIndex] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputDates;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,13 @@ public:
|
|||||||
ACCUMULATED_FLOW_VOLUME,
|
ACCUMULATED_FLOW_VOLUME,
|
||||||
ACCUMULATED_FLOW_VOLUME_PERCENTAGE,
|
ACCUMULATED_FLOW_VOLUME_PERCENTAGE,
|
||||||
};
|
};
|
||||||
|
enum class TimeStepFilterMode
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
TIME_STEP_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isCurveHighlightSupported() const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RimWellAllocationOverTimePlot();
|
RimWellAllocationOverTimePlot();
|
||||||
@ -94,6 +101,8 @@ private:
|
|||||||
caf::PdmFieldHandle* userDescriptionField() override;
|
caf::PdmFieldHandle* userDescriptionField() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void doUpdateLayout() override;
|
||||||
|
|
||||||
void updateFromWell();
|
void updateFromWell();
|
||||||
RimWellAllocationOverTimeCollection createWellAllocationOverTimeCollection() const;
|
RimWellAllocationOverTimeCollection createWellAllocationOverTimeCollection() const;
|
||||||
std::set<QString> findSortedWellNames();
|
std::set<QString> findSortedWellNames();
|
||||||
@ -110,22 +119,33 @@ private:
|
|||||||
|
|
||||||
void setValidTimeStepRangeForCase();
|
void setValidTimeStepRangeForCase();
|
||||||
|
|
||||||
|
int axisTitleFontSize() const;
|
||||||
|
int axisValueFontSize() const;
|
||||||
|
|
||||||
|
std::vector<QDateTime> getTimeStepsWithinSelectedRange( const std::vector<QDateTime>& timeSteps ) const;
|
||||||
|
std::set<QDateTime> getSelectedTimeSteps( const std::vector<QDateTime>& timeSteps ) const;
|
||||||
|
static std::set<QDateTime> createEvenlyDistributedDates( const std::vector<QDateTime>& inputDates, int numDates );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
caf::PdmField<QString> m_userName;
|
caf::PdmField<QString> m_userName;
|
||||||
caf::PdmPtrField<RimEclipseResultCase*> m_case;
|
caf::PdmPtrField<RimEclipseResultCase*> m_case;
|
||||||
caf::PdmField<QString> m_wellName;
|
caf::PdmField<QString> m_wellName;
|
||||||
|
|
||||||
caf::PdmField<QDateTime> m_selectedFromTimeStep;
|
caf::PdmField<QDateTime> m_selectedFromTimeStep;
|
||||||
caf::PdmField<QDateTime> m_selectedToTimeStep;
|
caf::PdmField<QDateTime> m_selectedToTimeStep;
|
||||||
caf::PdmField<std::vector<QDateTime>> m_excludeTimeSteps;
|
caf::PdmField<caf::AppEnum<TimeStepFilterMode>> m_timeStepFilterMode;
|
||||||
caf::PdmField<bool> m_applyExcludeTimeSteps;
|
caf::PdmField<int> m_timeStepCount;
|
||||||
|
caf::PdmField<std::vector<QDateTime>> m_excludeTimeSteps;
|
||||||
|
caf::PdmField<bool> m_applyTimeStepSelections;
|
||||||
|
|
||||||
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
|
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
|
||||||
caf::PdmField<caf::AppEnum<FlowValueType>> m_flowValueType;
|
caf::PdmField<caf::AppEnum<FlowValueType>> m_flowValueType;
|
||||||
caf::PdmField<bool> m_groupSmallContributions;
|
caf::PdmField<bool> m_groupSmallContributions;
|
||||||
caf::PdmField<double> m_smallContributionsThreshold;
|
caf::PdmField<double> m_smallContributionsThreshold;
|
||||||
|
|
||||||
QPointer<RiuQwtPlotWidget> m_plotWidget;
|
QPointer<RiuQwtPlotWidget> m_plotWidget;
|
||||||
|
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_axisTitleFontSize;
|
||||||
|
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_axisValueFontSize;
|
||||||
|
|
||||||
const int m_initialNumberOfTimeSteps = 10;
|
const int m_initialNumberOfTimeSteps = 10;
|
||||||
};
|
};
|
||||||
|
@ -290,10 +290,24 @@ void RiuQwtPlotWidget::setInternalLegendVisible( bool visible )
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RiuQwtPlotWidget::insertLegend( RiuPlotWidget::Legend legendPosition )
|
void RiuQwtPlotWidget::insertLegend( RiuPlotWidget::Legend legendPosition )
|
||||||
{
|
{
|
||||||
CAF_ASSERT( legendPosition == RiuPlotWidget::Legend::BOTTOM );
|
CAF_ASSERT( legendPosition == RiuPlotWidget::Legend::BOTTOM || legendPosition == RiuPlotWidget::Legend::TOP ||
|
||||||
|
legendPosition == RiuPlotWidget::Legend::LEFT || legendPosition == RiuPlotWidget::Legend::RIGHT );
|
||||||
|
|
||||||
|
QwtPlot::LegendPosition pos = QwtPlot::LegendPosition::BottomLegend;
|
||||||
|
if ( legendPosition == RiuPlotWidget::Legend::TOP )
|
||||||
|
{
|
||||||
|
pos = QwtPlot::LegendPosition::TopLegend;
|
||||||
|
}
|
||||||
|
else if ( legendPosition == RiuPlotWidget::Legend::LEFT )
|
||||||
|
{
|
||||||
|
pos = QwtPlot::LegendPosition::LeftLegend;
|
||||||
|
}
|
||||||
|
else if ( legendPosition == RiuPlotWidget::Legend::RIGHT )
|
||||||
|
{
|
||||||
|
pos = QwtPlot::LegendPosition::RightLegend;
|
||||||
|
}
|
||||||
auto* legend = new QwtLegend( this );
|
auto* legend = new QwtLegend( this );
|
||||||
m_plot->insertLegend( legend, QwtPlot::BottomLegend );
|
m_plot->insertLegend( legend, pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -581,7 +595,11 @@ bool RiuQwtPlotWidget::eventFilter( QObject* watched, QEvent* event )
|
|||||||
auto* scaleWidget = qobject_cast<QwtScaleWidget*>( childClicked );
|
auto* scaleWidget = qobject_cast<QwtScaleWidget*>( childClicked );
|
||||||
if ( scaleWidget )
|
if ( scaleWidget )
|
||||||
{
|
{
|
||||||
onAxisSelected( scaleWidget, toggleItemInSelection );
|
if ( m_plotDefinition && m_plotDefinition->isCurveHighlightSupported() )
|
||||||
|
{
|
||||||
|
onAxisSelected( scaleWidget, toggleItemInSelection );
|
||||||
|
}
|
||||||
|
|
||||||
m_clickPosition = QPoint();
|
m_clickPosition = QPoint();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user