#10358 Regression Analysis: Allow selecting subset of time range for regression

This commit is contained in:
Kristian Bendiksen 2023-06-07 11:23:42 +02:00
parent 5bd492dc56
commit f1794abff2
9 changed files with 188 additions and 37 deletions

View File

@ -90,6 +90,7 @@ RimSummaryRegressionAnalysisCurve*
summaryPlot->addCurveAndUpdate( newCurve ); summaryPlot->addCurveAndUpdate( newCurve );
newCurve->updateDefaultValues();
newCurve->loadDataAndUpdate( true ); newCurve->loadDataAndUpdate( true );
newCurve->updateConnectedEditors(); newCurve->updateConnectedEditors();

View File

@ -708,6 +708,8 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot )
{ {
shouldPopulateViewWithEmptyData = true; shouldPopulateViewWithEmptyData = true;
} }
updateTimeAnnotations();
} }
if ( shouldPopulateViewWithEmptyData ) if ( shouldPopulateViewWithEmptyData )
@ -1293,3 +1295,10 @@ void RimSummaryCurve::calculateCurveInterpolationFromAddress()
} }
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::updateTimeAnnotations()
{
}

View File

@ -115,6 +115,8 @@ protected:
virtual std::vector<time_t> timeStepsX() const; virtual std::vector<time_t> timeStepsX() const;
virtual void updateTimeAnnotations();
// Overridden PDM methods // Overridden PDM methods
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;

View File

@ -1345,29 +1345,29 @@ void RimSummaryPlot::updateCaseNameHasChanged()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimSummaryPlot::addTimeAnnotation( time_t time ) RimTimeAxisAnnotation* RimSummaryPlot::addTimeAnnotation( time_t time )
{ {
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties(); RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
{
auto* annotation = new RimTimeAxisAnnotation; auto* annotation = new RimTimeAxisAnnotation;
annotation->setTime( time ); annotation->setTime( time );
axisProps->appendAnnotation( annotation ); axisProps->appendAnnotation( annotation );
} return annotation;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimSummaryPlot::addTimeRangeAnnotation( time_t startTime, time_t endTime ) RimTimeAxisAnnotation* RimSummaryPlot::addTimeRangeAnnotation( time_t startTime, time_t endTime )
{ {
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties(); RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
{
auto* annotation = new RimTimeAxisAnnotation; auto* annotation = new RimTimeAxisAnnotation;
annotation->setTimeRange( startTime, endTime ); annotation->setTimeRange( startTime, endTime );
axisProps->appendAnnotation( annotation ); axisProps->appendAnnotation( annotation );
} return annotation;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1379,6 +1379,15 @@ void RimSummaryPlot::removeAllTimeAnnotations()
axisProps->removeAllAnnotations(); axisProps->removeAllAnnotations();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::removeTimeAnnotation( RimTimeAxisAnnotation* annotation )
{
RimSummaryTimeAxisProperties* axisProps = timeAxisProperties();
axisProps->removeAnnotation( annotation );
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -60,6 +60,7 @@ class RimSummaryNameHelper;
class RimSummaryPlotNameHelper; class RimSummaryPlotNameHelper;
class RimPlotTemplateFileItem; class RimPlotTemplateFileItem;
class RimSummaryPlotSourceStepping; class RimSummaryPlotSourceStepping;
class RimTimeAxisAnnotation;
class RiaSummaryCurveDefinition; class RiaSummaryCurveDefinition;
class QwtInterval; class QwtInterval;
@ -122,8 +123,9 @@ public:
void reattachAllCurves() override; void reattachAllCurves() override;
void updateCaseNameHasChanged(); void updateCaseNameHasChanged();
void addTimeAnnotation( time_t time ); RimTimeAxisAnnotation* addTimeAnnotation( time_t time );
void addTimeRangeAnnotation( time_t startTime, time_t endTime ); RimTimeAxisAnnotation* addTimeRangeAnnotation( time_t startTime, time_t endTime );
void removeTimeAnnotation( RimTimeAxisAnnotation* annotation );
void removeAllTimeAnnotations(); void removeAllTimeAnnotations();
void updateAxes() override; void updateAxes() override;

View File

@ -22,8 +22,11 @@
#include "RiaTimeTTools.h" #include "RiaTimeTTools.h"
#include "RimSummaryPlot.h" #include "RimSummaryPlot.h"
#include "RimTimeAxisAnnotation.h"
#include "cafPdmUiDateEditor.h"
#include "cafPdmUiLineEditor.h" #include "cafPdmUiLineEditor.h"
#include "cafPdmUiSliderEditor.h"
#include "cafPdmUiTextEditor.h" #include "cafPdmUiTextEditor.h"
#include "ExponentialRegression.hpp" #include "ExponentialRegression.hpp"
@ -78,6 +81,14 @@ RimSummaryRegressionAnalysisCurve::RimSummaryRegressionAnalysisCurve()
CAF_PDM_InitFieldNoDefault( &m_forecastUnit, "ForecastUnit", "Unit" ); CAF_PDM_InitFieldNoDefault( &m_forecastUnit, "ForecastUnit", "Unit" );
CAF_PDM_InitField( &m_polynominalDegree, "PolynominalDegree", 3, "Degree" ); CAF_PDM_InitField( &m_polynominalDegree, "PolynominalDegree", 3, "Degree" );
CAF_PDM_InitFieldNoDefault( &m_minTimeStep, "MinTimeStep", "From" );
m_minTimeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_maxTimeStep, "MaxTimeStep", "To" );
m_maxTimeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_showTimeSelectionInPlot, "ShowTimeSelectionInPlot", false, "Show In Plot" );
CAF_PDM_InitFieldNoDefault( &m_expressionText, "ExpressionText", "Expression" ); CAF_PDM_InitFieldNoDefault( &m_expressionText, "ExpressionText", "Expression" );
m_expressionText.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() ); m_expressionText.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
m_expressionText.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); m_expressionText.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
@ -90,6 +101,8 @@ RimSummaryRegressionAnalysisCurve::RimSummaryRegressionAnalysisCurve()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimSummaryRegressionAnalysisCurve::~RimSummaryRegressionAnalysisCurve() RimSummaryRegressionAnalysisCurve::~RimSummaryRegressionAnalysisCurve()
{ {
auto plot = firstAncestorOrThisOfType<RimSummaryPlot>();
if ( plot && m_timeRangeAnnotation ) plot->removeTimeAnnotation( m_timeRangeAnnotation );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -148,29 +161,38 @@ std::tuple<std::vector<time_t>, std::vector<double>, QString>
{ {
if ( values.empty() || timeSteps.empty() ) return { timeSteps, values, "" }; if ( values.empty() || timeSteps.empty() ) return { timeSteps, values, "" };
std::vector<double> timeStepsD = convertToDouble( timeSteps ); auto [timeStepsInRange, valuesInRange] = getInRangeValues( timeSteps, values, m_minTimeStep, m_maxTimeStep );
std::vector<time_t> outputTimeSteps = getOutputTimeSteps( timeSteps, m_forecastBackward(), m_forecastForward(), m_forecastUnit() ); if ( timeStepsInRange.empty() || valuesInRange.empty() ) return {};
std::vector<double> timeStepsD = convertToDouble( timeStepsInRange );
std::vector<time_t> outputTimeSteps = getOutputTimeSteps( timeStepsInRange, m_forecastBackward(), m_forecastForward(), m_forecastUnit() );
std::vector<double> outputTimeStepsD = convertToDouble( outputTimeSteps ); std::vector<double> outputTimeStepsD = convertToDouble( outputTimeSteps );
if ( timeStepsD.empty() || valuesInRange.empty() )
{
return {};
}
if ( m_regressionType == RegressionType::LINEAR ) if ( m_regressionType == RegressionType::LINEAR )
{ {
regression::LinearRegression linearRegression; regression::LinearRegression linearRegression;
linearRegression.fit( timeStepsD, values ); linearRegression.fit( timeStepsD, valuesInRange );
std::vector<double> predictedValues = linearRegression.predict( outputTimeStepsD ); std::vector<double> predictedValues = linearRegression.predict( outputTimeStepsD );
return { outputTimeSteps, predictedValues, generateRegressionText( linearRegression ) }; return { outputTimeSteps, predictedValues, generateRegressionText( linearRegression ) };
} }
else if ( m_regressionType == RegressionType::POLYNOMINAL ) else if ( m_regressionType == RegressionType::POLYNOMINAL )
{ {
regression::PolynominalRegression polynominalRegression; regression::PolynominalRegression polynominalRegression;
polynominalRegression.fit( timeStepsD, values, m_polynominalDegree ); polynominalRegression.fit( timeStepsD, valuesInRange, m_polynominalDegree );
std::vector<double> predictedValues = polynominalRegression.predict( outputTimeStepsD ); std::vector<double> predictedValues = polynominalRegression.predict( outputTimeStepsD );
return { outputTimeSteps, predictedValues, generateRegressionText( polynominalRegression ) }; return { outputTimeSteps, predictedValues, generateRegressionText( polynominalRegression ) };
} }
else if ( m_regressionType == RegressionType::POWER_FIT ) else if ( m_regressionType == RegressionType::POWER_FIT )
{ {
auto [filteredTimeSteps, filteredValues] = getPositiveValues( timeStepsD, values ); auto [filteredTimeSteps, filteredValues] = getPositiveValues( timeStepsD, valuesInRange );
regression::PowerFitRegression powerFitRegression; regression::PowerFitRegression powerFitRegression;
powerFitRegression.fit( filteredTimeSteps, filteredValues ); powerFitRegression.fit( filteredTimeSteps, filteredValues );
std::vector<double> predictedValues = powerFitRegression.predict( outputTimeStepsD ); std::vector<double> predictedValues = powerFitRegression.predict( outputTimeStepsD );
@ -178,7 +200,7 @@ std::tuple<std::vector<time_t>, std::vector<double>, QString>
} }
else if ( m_regressionType == RegressionType::EXPONENTIAL ) else if ( m_regressionType == RegressionType::EXPONENTIAL )
{ {
auto [filteredTimeSteps, filteredValues] = getPositiveValues( timeStepsD, values ); auto [filteredTimeSteps, filteredValues] = getPositiveValues( timeStepsD, valuesInRange );
regression::ExponentialRegression exponentialRegression; regression::ExponentialRegression exponentialRegression;
exponentialRegression.fit( filteredTimeSteps, filteredValues ); exponentialRegression.fit( filteredTimeSteps, filteredValues );
std::vector<double> predictedValues = exponentialRegression.predict( outputTimeStepsD ); std::vector<double> predictedValues = exponentialRegression.predict( outputTimeStepsD );
@ -186,7 +208,7 @@ std::tuple<std::vector<time_t>, std::vector<double>, QString>
} }
else if ( m_regressionType == RegressionType::LOGARITHMIC ) else if ( m_regressionType == RegressionType::LOGARITHMIC )
{ {
auto [filteredTimeSteps, filteredValues] = getPositiveValues( timeStepsD, values ); auto [filteredTimeSteps, filteredValues] = getPositiveValues( timeStepsD, valuesInRange );
regression::LogarithmicRegression logarithmicRegression; regression::LogarithmicRegression logarithmicRegression;
logarithmicRegression.fit( filteredTimeSteps, filteredValues ); logarithmicRegression.fit( filteredTimeSteps, filteredValues );
std::vector<double> predictedValues = logarithmicRegression.predict( outputTimeStepsD ); std::vector<double> predictedValues = logarithmicRegression.predict( outputTimeStepsD );
@ -195,7 +217,7 @@ std::tuple<std::vector<time_t>, std::vector<double>, QString>
else if ( m_regressionType == RegressionType::LOGISTIC ) else if ( m_regressionType == RegressionType::LOGISTIC )
{ {
regression::LogisticRegression logisticRegression; regression::LogisticRegression logisticRegression;
logisticRegression.fit( timeStepsD, values ); logisticRegression.fit( timeStepsD, valuesInRange );
std::vector<double> predictedValues = logisticRegression.predict( outputTimeStepsD ); std::vector<double> predictedValues = logisticRegression.predict( outputTimeStepsD );
return { convertToTimeT( outputTimeStepsD ), predictedValues, generateRegressionText( logisticRegression ) }; return { convertToTimeT( outputTimeStepsD ), predictedValues, generateRegressionText( logisticRegression ) };
} }
@ -220,6 +242,11 @@ void RimSummaryRegressionAnalysisCurve::defineUiOrdering( QString uiConfigName,
regressionCurveGroup->add( &m_expressionText ); regressionCurveGroup->add( &m_expressionText );
caf::PdmUiGroup* timeSelectionGroup = uiOrdering.addNewGroup( "Time Selection" );
timeSelectionGroup->add( &m_minTimeStep );
timeSelectionGroup->add( &m_maxTimeStep );
timeSelectionGroup->add( &m_showTimeSelectionInPlot );
caf::PdmUiGroup* forecastingGroup = uiOrdering.addNewGroup( "Forecasting" ); caf::PdmUiGroup* forecastingGroup = uiOrdering.addNewGroup( "Forecasting" );
forecastingGroup->add( &m_forecastForward ); forecastingGroup->add( &m_forecastForward );
forecastingGroup->add( &m_forecastBackward ); forecastingGroup->add( &m_forecastBackward );
@ -235,11 +262,23 @@ void RimSummaryRegressionAnalysisCurve::fieldChangedByUi( const caf::PdmFieldHan
const QVariant& oldValue, const QVariant& oldValue,
const QVariant& newValue ) const QVariant& newValue )
{ {
if ( &m_minTimeStep == changedField && m_minTimeStep > m_maxTimeStep )
{
m_maxTimeStep = m_minTimeStep;
}
if ( &m_maxTimeStep == changedField && m_maxTimeStep < m_minTimeStep )
{
m_minTimeStep = m_maxTimeStep;
}
RimSummaryCurve::fieldChangedByUi( changedField, oldValue, newValue ); RimSummaryCurve::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_regressionType || changedField == &m_polynominalDegree || changedField == &m_forecastBackward || if ( changedField == &m_regressionType || changedField == &m_polynominalDegree || changedField == &m_forecastBackward ||
changedField == &m_forecastForward || changedField == &m_forecastUnit ) changedField == &m_forecastForward || changedField == &m_forecastUnit || changedField == &m_minTimeStep ||
changedField == &m_maxTimeStep || changedField == &m_showTimeSelectionInPlot )
{ {
loadAndUpdateDataAndPlot(); loadAndUpdateDataAndPlot();
auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>(); auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
if ( plot ) plot->zoomAll(); if ( plot ) plot->zoomAll();
} }
@ -270,6 +309,19 @@ void RimSummaryRegressionAnalysisCurve::defineEditorAttribute( const caf::PdmFie
lineEditorAttr->validator = new QIntValidator( 0, 50, nullptr ); lineEditorAttr->validator = new QIntValidator( 0, 50, nullptr );
} }
} }
else if ( field == &m_minTimeStep || field == &m_maxTimeStep )
{
if ( auto* myAttr = dynamic_cast<caf::PdmUiSliderEditorAttribute*>( attribute ) )
{
auto timeSteps = RimSummaryCurve::timeStepsY();
if ( !timeSteps.empty() )
{
myAttr->m_minimum = *timeSteps.begin();
myAttr->m_maximum = *timeSteps.rbegin();
}
myAttr->m_showSpinBox = false;
}
}
else if ( field == &m_expressionText ) else if ( field == &m_expressionText )
{ {
auto myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute ); auto myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute );
@ -480,3 +532,55 @@ std::pair<std::vector<double>, std::vector<double>>
return std::make_pair( filteredTimeSteps, filteredValues ); return std::make_pair( filteredTimeSteps, filteredValues );
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<std::vector<time_t>, std::vector<double>> RimSummaryRegressionAnalysisCurve::getInRangeValues( const std::vector<time_t>& timeSteps,
const std::vector<double>& values,
time_t minTimeStep,
time_t maxTimeStep )
{
CAF_ASSERT( timeSteps.size() == values.size() );
std::vector<time_t> filteredTimeSteps;
std::vector<double> filteredValues;
for ( size_t i = 0; i < timeSteps.size(); i++ )
{
time_t timeStep = timeSteps[i];
if ( timeStep >= minTimeStep && timeStep <= maxTimeStep )
{
filteredTimeSteps.push_back( timeStep );
filteredValues.push_back( values[i] );
}
}
return std::make_pair( filteredTimeSteps, filteredValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryRegressionAnalysisCurve::updateTimeAnnotations()
{
auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
if ( m_timeRangeAnnotation ) plot->removeTimeAnnotation( m_timeRangeAnnotation );
if ( m_showTimeSelectionInPlot )
{
m_timeRangeAnnotation = plot->addTimeRangeAnnotation( m_minTimeStep, m_maxTimeStep );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryRegressionAnalysisCurve::updateDefaultValues()
{
auto timeSteps = RimSummaryCurve::timeStepsY();
if ( !timeSteps.empty() )
{
m_minTimeStep = timeSteps.front();
m_maxTimeStep = timeSteps.back();
}
}

View File

@ -18,14 +18,12 @@
#pragma once #pragma once
#include "cafAppEnum.h"
#include "cafPdmField.h" #include "cafPdmField.h"
#include "cafPdmObject.h" #include "cafPdmObject.h"
#include "RimSummaryCurve.h" #include "RimSummaryCurve.h"
#include "cafAppEnum.h"
#include "regression-analysis/src/PowerFitRegression.hpp"
#include <utility> #include <utility>
namespace regression namespace regression
@ -38,6 +36,8 @@ class PolynominalRegression;
class PowerFitRegression; class PowerFitRegression;
} // namespace regression } // namespace regression
class RimTimeAxisAnnotation;
//================================================================================================== //==================================================================================================
/// ///
/// ///
@ -77,6 +77,11 @@ public:
static std::vector<time_t> static std::vector<time_t>
getOutputTimeSteps( const std::vector<time_t>& timeSteps, int forecastBackward, int forecastForward, ForecastUnit forecastUnit ); getOutputTimeSteps( const std::vector<time_t>& timeSteps, int forecastBackward, int forecastForward, ForecastUnit forecastUnit );
void updateDefaultValues();
protected:
void updateTimeAnnotations() override;
private: private:
void onLoadDataAndUpdate( bool updateParentPlot ) override; void onLoadDataAndUpdate( bool updateParentPlot ) override;
@ -97,6 +102,9 @@ private:
static std::pair<std::vector<double>, std::vector<double>> getPositiveValues( const std::vector<double>& timeSteps, static std::pair<std::vector<double>, std::vector<double>> getPositiveValues( const std::vector<double>& timeSteps,
const std::vector<double>& values ); const std::vector<double>& values );
static std::pair<std::vector<time_t>, std::vector<double>>
getInRangeValues( const std::vector<time_t>& timeSteps, const std::vector<double>& values, time_t minTimeStep, time_t maxTimeStep );
static QString generateRegressionText( const regression::LinearRegression& reg ); static QString generateRegressionText( const regression::LinearRegression& reg );
static QString generateRegressionText( const regression::PolynominalRegression& reg ); static QString generateRegressionText( const regression::PolynominalRegression& reg );
static QString generateRegressionText( const regression::PowerFitRegression& reg ); static QString generateRegressionText( const regression::PowerFitRegression& reg );
@ -109,12 +117,17 @@ private:
static void appendTimeSteps( std::vector<time_t>& destinationTimeSteps, const std::set<QDateTime>& sourceTimeSteps ); static void appendTimeSteps( std::vector<time_t>& destinationTimeSteps, const std::set<QDateTime>& sourceTimeSteps );
caf::PdmField<caf::AppEnum<RegressionType>> m_regressionType; caf::PdmField<caf::AppEnum<RegressionType>> m_regressionType;
caf::PdmField<time_t> m_minTimeStep;
caf::PdmField<time_t> m_maxTimeStep;
caf::PdmField<bool> m_showTimeSelectionInPlot;
caf::PdmField<int> m_polynominalDegree; caf::PdmField<int> m_polynominalDegree;
caf::PdmField<QString> m_expressionText; caf::PdmField<QString> m_expressionText;
caf::PdmField<int> m_forecastForward; caf::PdmField<int> m_forecastForward;
caf::PdmField<int> m_forecastBackward; caf::PdmField<int> m_forecastBackward;
caf::PdmField<caf::AppEnum<ForecastUnit>> m_forecastUnit; caf::PdmField<caf::AppEnum<ForecastUnit>> m_forecastUnit;
caf::PdmPointer<RimTimeAxisAnnotation> m_timeRangeAnnotation;
std::vector<double> m_valuesX; std::vector<double> m_valuesX;
std::vector<time_t> m_timeStepsX; std::vector<time_t> m_timeStepsX;
std::vector<double> m_valuesY; std::vector<double> m_valuesY;

View File

@ -150,6 +150,7 @@ RimSummaryTimeAxisProperties::RimSummaryTimeAxisProperties()
CAF_PDM_InitFieldNoDefault( &m_annotations, "Annotations", "" ); CAF_PDM_InitFieldNoDefault( &m_annotations, "Annotations", "" );
m_annotations.uiCapability()->setUiTreeHidden( true ); m_annotations.uiCapability()->setUiTreeHidden( true );
m_annotations.uiCapability()->setUiTreeChildrenHidden( true );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -758,6 +759,14 @@ void RimSummaryTimeAxisProperties::removeAllAnnotations()
m_annotations.deleteChildren(); m_annotations.deleteChildren();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryTimeAxisProperties::removeAnnotation( RimTimeAxisAnnotation* annotation )
{
m_annotations.removeChild( annotation );
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -101,6 +101,8 @@ public:
std::vector<RimPlotAxisAnnotation*> annotations() const override; std::vector<RimPlotAxisAnnotation*> annotations() const override;
void appendAnnotation( RimPlotAxisAnnotation* annotation ) override; void appendAnnotation( RimPlotAxisAnnotation* annotation ) override;
void removeAnnotation( RimTimeAxisAnnotation* annotation );
void removeAllAnnotations() override; void removeAllAnnotations() override;
const QString& dateFormat() const; const QString& dateFormat() const;