From 36772e77b141630e59302b40d5af20047547eb59 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 22 Nov 2019 14:22:00 +0100 Subject: [PATCH] #5079 Curve Error Bars : Move to RimPlotCurve --- .../Application/Tools/RiaCurveDataTools.h | 6 + .../ProjectDataModel/RimPlotCurve.cpp | 121 ++++++++++- .../ProjectDataModel/RimPlotCurve.h | 15 +- .../ProjectDataModel/RimWellLogCurve.cpp | 2 +- .../ProjectDataModel/RimWellLogRftCurve.cpp | 49 +++-- .../Summary/RimSummaryCurve.cpp | 21 +- .../UserInterface/RiuQwtPlotCurve.cpp | 196 +++--------------- .../UserInterface/RiuQwtPlotCurve.h | 56 ++--- 8 files changed, 225 insertions(+), 241 deletions(-) diff --git a/ApplicationCode/Application/Tools/RiaCurveDataTools.h b/ApplicationCode/Application/Tools/RiaCurveDataTools.h index 235cc3543e..72508b1d54 100644 --- a/ApplicationCode/Application/Tools/RiaCurveDataTools.h +++ b/ApplicationCode/Application/Tools/RiaCurveDataTools.h @@ -36,6 +36,12 @@ class RiaCurveDataTools public: typedef std::vector> CurveIntervals; + enum ErrorAxis + { + ERROR_ALONG_X_AXIS, + ERROR_ALONG_Y_AXIS + }; + public: static CurveIntervals calculateIntervalsOfValidValues( const std::vector& values, bool includePositiveValuesOnly ); diff --git a/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp b/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp index 14cbf83229..1c2c78264b 100644 --- a/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp @@ -18,7 +18,9 @@ #include "RimPlotCurve.h" +#include "RiaCurveDataTools.h" #include "RiaGuiApplication.h" + #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" #include "RimNameConfig.h" @@ -35,12 +37,16 @@ #include "cvfAssert.h" +#include "qwt_date.h" +#include "qwt_interval_symbol.h" #include "qwt_plot.h" #include "qwt_symbol.h" // NB! Special macro for pure virtual class CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlotCurve, "PlotCurve" ); +#define DOUBLE_INF std::numeric_limits::infinity() + namespace caf { template <> @@ -147,7 +153,12 @@ RimPlotCurve::RimPlotCurve() CAF_PDM_InitFieldNoDefault( &m_symbolLabelPosition, "SymbolLabelPosition", "Symbol Label Position", "", "", "" ); - m_qwtPlotCurve = new RiuRimQwtPlotCurve( this ); + m_qwtPlotCurve = new RiuRimQwtPlotCurve( this ); + m_qwtCurveErrorBars = new QwtPlotIntervalCurve(); + m_qwtCurveErrorBars->setStyle( QwtPlotIntervalCurve::CurveStyle::NoCurve ); + m_qwtCurveErrorBars->setSymbol( new QwtIntervalSymbol( QwtIntervalSymbol::Bar ) ); + m_qwtCurveErrorBars->setItemAttribute( QwtPlotItem::Legend, false ); + m_qwtCurveErrorBars->setZ( RiuQwtPlotCurve::Z_ERROR_BARS ); m_parentQwtPlot = nullptr; } @@ -164,6 +175,13 @@ RimPlotCurve::~RimPlotCurve() m_qwtPlotCurve = nullptr; } + if ( m_qwtCurveErrorBars ) + { + m_qwtCurveErrorBars->detach(); + delete m_qwtCurveErrorBars; + m_qwtCurveErrorBars = nullptr; + } + if ( m_parentQwtPlot ) { m_parentQwtPlot->replot(); @@ -220,7 +238,6 @@ void RimPlotCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField, } else if ( changedField == &m_showErrorBars ) { - m_qwtPlotCurve->showErrorBars( m_showErrorBars ); updateCurveAppearance(); } RiuPlotMainWindowTools::refreshToolbars(); @@ -271,11 +288,12 @@ void RimPlotCurve::updateCurveVisibility( bool updateParentPlot ) { if ( canCurveBeAttached() ) { - m_qwtPlotCurve->attach( m_parentQwtPlot ); + attachCurveAndErrorBars(); } else { m_qwtPlotCurve->detach(); + m_qwtCurveErrorBars->detach(); } if ( updateParentPlot ) @@ -323,7 +341,8 @@ void RimPlotCurve::setParentQwtPlotAndReplot( QwtPlot* plot ) m_parentQwtPlot = plot; if ( canCurveBeAttached() ) { - m_qwtPlotCurve->attach( m_parentQwtPlot ); + attachCurveAndErrorBars(); + m_parentQwtPlot->replot(); } } @@ -336,11 +355,12 @@ void RimPlotCurve::setParentQwtPlotNoReplot( QwtPlot* plot ) m_parentQwtPlot = plot; if ( canCurveBeAttached() ) { - m_qwtPlotCurve->attach( m_parentQwtPlot ); + attachCurveAndErrorBars(); } else { m_qwtPlotCurve->detach(); + m_qwtCurveErrorBars->detach(); } } @@ -366,6 +386,7 @@ void RimPlotCurve::setColor( const cvf::Color3f& color ) void RimPlotCurve::detachQwtCurve() { m_qwtPlotCurve->detach(); + m_qwtCurveErrorBars->detach(); } //-------------------------------------------------------------------------------------------------- @@ -376,7 +397,7 @@ void RimPlotCurve::reattachQwtCurve() detachQwtCurve(); if ( canCurveBeAttached() ) { - m_qwtPlotCurve->attach( m_parentQwtPlot ); + attachCurveAndErrorBars(); } } @@ -486,6 +507,75 @@ void RimPlotCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& u throw std::logic_error( "The method or operation is not implemented." ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::setSamplesFromXYErrorValues( + const std::vector& xValues, + const std::vector& yValues, + const std::vector& errorValues, + bool keepOnlyPositiveValues, + RiaCurveDataTools::ErrorAxis errorAxis /*= RiuQwtPlotCurve::ERROR_ALONG_Y_AXIS */ ) +{ + CVF_ASSERT( xValues.size() == yValues.size() ); + CVF_ASSERT( xValues.size() == errorValues.size() ); + + auto intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues( yValues, keepOnlyPositiveValues ); + std::vector filteredYValues; + std::vector filteredXValues; + + RiaCurveDataTools::getValuesByIntervals( yValues, intervalsOfValidValues, &filteredYValues ); + RiaCurveDataTools::getValuesByIntervals( xValues, intervalsOfValidValues, &filteredXValues ); + + std::vector filteredErrorValues; + RiaCurveDataTools::getValuesByIntervals( errorValues, intervalsOfValidValues, &filteredErrorValues ); + + QVector errorIntervals; + + errorIntervals.reserve( static_cast( filteredXValues.size() ) ); + + for ( size_t i = 0; i < filteredXValues.size(); i++ ) + { + if ( filteredYValues[i] != DOUBLE_INF && filteredErrorValues[i] != DOUBLE_INF ) + { + if ( errorAxis == RiaCurveDataTools::ERROR_ALONG_Y_AXIS ) + { + errorIntervals << QwtIntervalSample( filteredXValues[i], + filteredYValues[i] - filteredErrorValues[i], + filteredYValues[i] + filteredErrorValues[i] ); + } + else + { + errorIntervals << QwtIntervalSample( filteredYValues[i], + filteredXValues[i] - filteredErrorValues[i], + filteredXValues[i] + filteredErrorValues[i] ); + } + } + } + + if ( m_qwtPlotCurve ) + { + m_qwtPlotCurve->setSamples( filteredXValues.data(), + filteredYValues.data(), + static_cast( filteredXValues.size() ) ); + + m_qwtPlotCurve->setLineSegmentStartStopIndices( intervalsOfValidValues ); + } + + if ( m_qwtCurveErrorBars ) + { + m_qwtCurveErrorBars->setSamples( errorIntervals ); + if ( errorAxis == RiaCurveDataTools::ERROR_ALONG_Y_AXIS ) + { + m_qwtCurveErrorBars->setOrientation( Qt::Vertical ); + } + else + { + m_qwtCurveErrorBars->setOrientation( Qt::Horizontal ); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -557,6 +647,19 @@ bool RimPlotCurve::canCurveBeAttached() const return isVisibleInPossibleParent; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::attachCurveAndErrorBars() +{ + m_qwtPlotCurve->attach( m_parentQwtPlot ); + + if ( m_showErrorBars ) + { + m_qwtCurveErrorBars->attach( m_parentQwtPlot ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -585,7 +688,11 @@ void RimPlotCurve::updateCurveAppearance() m_qwtPlotCurve->setSymbol( symbol ); m_qwtPlotCurve->setSymbolSkipPixelDistance( m_symbolSkipPixelDistance() ); - m_qwtPlotCurve->setErrorBarsColor( curveColor ); + { + QwtIntervalSymbol* newSymbol = new QwtIntervalSymbol( QwtIntervalSymbol::Bar ); + newSymbol->setPen( QPen( curveColor ) ); + m_qwtCurveErrorBars->setSymbol( newSymbol ); + } // Make sure the legend lines are long enough to distinguish between line types. // Standard width in Qwt is 8 which is too short. diff --git a/ApplicationCode/ProjectDataModel/RimPlotCurve.h b/ApplicationCode/ProjectDataModel/RimPlotCurve.h index d17a720bb7..d4696ccf87 100644 --- a/ApplicationCode/ProjectDataModel/RimPlotCurve.h +++ b/ApplicationCode/ProjectDataModel/RimPlotCurve.h @@ -18,6 +18,9 @@ #pragma once #include "RifEclipseSummaryAddress.h" + +#include "RiaCurveDataTools.h" + #include "RiuQwtPlotCurve.h" #include "RiuQwtSymbol.h" @@ -29,6 +32,7 @@ class QwtPlot; class QwtPlotCurve; +class QwtPlotIntervalCurve; //================================================================================================== /// @@ -120,6 +124,12 @@ protected: virtual void updateLegendsInPlot(); void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void setSamplesFromXYErrorValues( const std::vector& xValues, + const std::vector& yValues, + const std::vector& errorValues, + bool keepOnlyPositiveValues, + RiaCurveDataTools::ErrorAxis errorAxis = RiaCurveDataTools::ERROR_ALONG_Y_AXIS ); + protected: // Overridden PDM methods void fieldChangedByUi( const caf::PdmFieldHandle* changedField, @@ -134,10 +144,13 @@ protected: private: bool canCurveBeAttached() const; + void attachCurveAndErrorBars(); protected: QPointer m_parentQwtPlot; - RiuQwtPlotCurve* m_qwtPlotCurve; + + RiuQwtPlotCurve* m_qwtPlotCurve; + QwtPlotIntervalCurve* m_qwtCurveErrorBars; caf::PdmField m_showCurve; caf::PdmField m_curveName; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp index f7dc139592..56e1ffdb47 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp @@ -47,7 +47,7 @@ RimWellLogCurve::RimWellLogCurve() CAF_PDM_InitObject( "WellLogCurve", ":/WellLogCurve16x16.png", "", "" ); m_qwtPlotCurve->setXAxis( QwtPlot::xTop ); - m_qwtPlotCurve->setErrorBarsXAxis( QwtPlot::xTop ); + m_qwtCurveErrorBars->setXAxis( QwtPlot::xTop ); m_qwtPlotCurve->setYAxis( QwtPlot::yLeft ); m_curveData = new RigWellLogCurveData; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp index b10ebca117..4c89bfa4d3 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp @@ -378,6 +378,7 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) RimWellRftPlot* rftPlot = dynamic_cast( wellLogPlot ); bool showErrorBarsInObservedData = rftPlot ? rftPlot->showErrorBarsForObservedData() : false; + m_showErrorBars = showErrorBarsInObservedData; std::vector measuredDepthVector = measuredDepthValues(); std::vector tvDepthVector = tvDepthValues(); @@ -447,14 +448,24 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) if ( wellLogPlot->depthType() == RiaDefines::MEASURED_DEPTH ) { - m_qwtPlotCurve->showErrorBars( showErrorBarsInObservedData ); m_qwtPlotCurve->setPerPointLabels( perPointLabels ); - m_qwtPlotCurve->setSamplesFromXValuesAndYValues( this->curveData()->xPlotValues(), - this->curveData()->depthPlotValues( RiaDefines::MEASURED_DEPTH, - displayUnit ), - errors, - false, - RiuQwtPlotCurve::ERROR_ALONG_X_AXIS ); + + auto xValues = this->curveData()->xPlotValues(); + auto yValues = this->curveData()->depthPlotValues( RiaDefines::MEASURED_DEPTH, displayUnit ); + bool keepOnlyPositiveValues = false; + + if ( !errors.empty() ) + { + this->setSamplesFromXYErrorValues( xValues, + yValues, + errors, + keepOnlyPositiveValues, + RiaCurveDataTools::ERROR_ALONG_X_AXIS ); + } + else + { + m_qwtPlotCurve->setSamplesFromXValuesAndYValues( xValues, yValues, keepOnlyPositiveValues ); + } RimWellLogTrack* wellLogTrack; firstAncestorOrThisOfType( wellLogTrack ); @@ -483,14 +494,24 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) } else { - m_qwtPlotCurve->showErrorBars( showErrorBarsInObservedData ); m_qwtPlotCurve->setPerPointLabels( perPointLabels ); - m_qwtPlotCurve->setSamplesFromXValuesAndYValues( this->curveData()->xPlotValues(), - this->curveData()->depthPlotValues( RiaDefines::TRUE_VERTICAL_DEPTH, - displayUnit ), - errors, - false, - RiuQwtPlotCurve::ERROR_ALONG_X_AXIS ); + + auto xValues = this->curveData()->xPlotValues(); + auto yValues = this->curveData()->depthPlotValues( RiaDefines::TRUE_VERTICAL_DEPTH, displayUnit ); + bool isLogCurve = false; + + if ( !errors.empty() ) + { + this->setSamplesFromXYErrorValues( xValues, + yValues, + errors, + isLogCurve, + RiaCurveDataTools::ERROR_ALONG_X_AXIS ); + } + else + { + m_qwtPlotCurve->setSamplesFromXValuesAndYValues( xValues, yValues, isLogCurve ); + } } m_qwtPlotCurve->setLineSegmentStartStopIndices( this->curveData()->polylineStartStopIndices() ); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 84fa1f6727..1511229997 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -151,7 +151,7 @@ void RimSummaryCurve::setSummaryCaseY( RimSummaryCase* sumCase ) { if ( m_yValuesSummaryCase != sumCase ) { - m_qwtPlotCurve->clearErrorBars(); + m_qwtCurveErrorBars->setSamples( nullptr ); } m_yValuesSummaryCase = sumCase; @@ -208,7 +208,7 @@ void RimSummaryCurve::setSummaryAddressY( const RifEclipseSummaryAddress& addres { if ( m_yValuesSummaryAddress->address() != address ) { - m_qwtPlotCurve->clearErrorBars(); + m_qwtCurveErrorBars->setSamples( nullptr ); } m_yValuesSummaryAddress->setAddress( address ); @@ -520,10 +520,17 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot ) { std::vector errValues; reader->values( errAddress, &errValues ); - m_qwtPlotCurve->setSamplesFromTimeTAndYValues( curveTimeStepsY, - curveValuesY, - errValues, - isLogCurve ); + + auto timeSteps = RiuQwtPlotCurve::fromTime_t( curveTimeStepsY ); + + if ( !errValues.empty() ) + { + this->setSamplesFromXYErrorValues( timeSteps, curveValuesY, errValues, isLogCurve ); + } + else + { + m_qwtPlotCurve->setSamplesFromXValuesAndYValues( timeSteps, curveValuesY, isLogCurve ); + } } else { @@ -564,8 +571,6 @@ void RimSummaryCurve::onLoadDataAndUpdate( bool updateParentPlot ) updateZoomInParentPlot(); m_parentQwtPlot->replot(); } - - m_qwtPlotCurve->showErrorBars( m_showErrorBars ); } if ( updateParentPlot ) updateQwtPlotAxis(); diff --git a/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp b/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp index b53ca9d2db..6cb0a6d6bf 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp +++ b/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp @@ -21,12 +21,12 @@ #include "RiaCurveDataTools.h" #include "RiaImageTools.h" + #include "RiuQwtSymbol.h" #include "qwt_date.h" #include "qwt_interval_symbol.h" #include "qwt_painter.h" -#include "qwt_plot_intervalcurve.h" #include "qwt_point_mapper.h" #include "qwt_scale_map.h" #include "qwt_symbol.h" @@ -52,14 +52,6 @@ RiuQwtPlotCurve::RiuQwtPlotCurve( const QString& title ) m_symbolSkipPixelDistance = 10.0f; - m_errorBars = new QwtPlotIntervalCurve(); - m_errorBars->setStyle( QwtPlotIntervalCurve::CurveStyle::NoCurve ); - m_errorBars->setSymbol( new QwtIntervalSymbol( QwtIntervalSymbol::Bar ) ); - m_errorBars->setItemAttribute( QwtPlotItem::Legend, false ); - m_errorBars->setZ( Z_ERROR_BARS ); - - m_showErrorBars = true; - m_attachedToPlot = nullptr; m_blackAndWhiteLegendIcon = false; } @@ -68,81 +60,6 @@ RiuQwtPlotCurve::RiuQwtPlotCurve( const QString& title ) //-------------------------------------------------------------------------------------------------- RiuQwtPlotCurve::~RiuQwtPlotCurve() {} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::setSamplesFromXValuesAndYValues( const std::vector& xValues, - const std::vector& yValues, - const std::vector& errorValues, - bool keepOnlyPositiveValues, - ErrorAxis errorAxis ) -{ - CVF_ASSERT( xValues.size() == yValues.size() ); - CVF_ASSERT( errorValues.empty() || errorValues.size() == xValues.size() ); - - bool showErrorBars = m_showErrorBars && !errorValues.empty(); - QPolygonF points; - QVector errorIntervals; - std::vector> filteredIntervals; - { - std::vector filteredYValues; - std::vector filteredXValues; - std::vector filteredErrorValues; - - { - auto intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues( yValues, - keepOnlyPositiveValues ); - - RiaCurveDataTools::getValuesByIntervals( yValues, intervalsOfValidValues, &filteredYValues ); - RiaCurveDataTools::getValuesByIntervals( xValues, intervalsOfValidValues, &filteredXValues ); - - if ( showErrorBars ) - RiaCurveDataTools::getValuesByIntervals( errorValues, intervalsOfValidValues, &filteredErrorValues ); - - filteredIntervals = RiaCurveDataTools::computePolyLineStartStopIndices( intervalsOfValidValues ); - } - - points.reserve( static_cast( filteredXValues.size() ) ); - errorIntervals.reserve( static_cast( filteredXValues.size() ) ); - for ( size_t i = 0; i < filteredXValues.size(); i++ ) - { - points << QPointF( filteredXValues[i], filteredYValues[i] ); - - if ( showErrorBars && filteredYValues[i] != DOUBLE_INF && filteredErrorValues[i] != DOUBLE_INF ) - { - if ( errorAxis == ERROR_ALONG_Y_AXIS ) - { - errorIntervals << QwtIntervalSample( filteredXValues[i], - filteredYValues[i] - filteredErrorValues[i], - filteredYValues[i] + filteredErrorValues[i] ); - } - else - { - errorIntervals << QwtIntervalSample( filteredYValues[i], - filteredXValues[i] - filteredErrorValues[i], - filteredXValues[i] + filteredErrorValues[i] ); - } - } - } - } - - this->setSamples( points ); - this->setLineSegmentStartStopIndices( filteredIntervals ); - - if ( showErrorBars ) - { - m_errorBars->setSamples( errorIntervals ); - if ( errorAxis == ERROR_ALONG_Y_AXIS ) - { - m_errorBars->setOrientation( Qt::Vertical ); - } - else - { - m_errorBars->setOrientation( Qt::Horizontal ); - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -150,7 +67,7 @@ void RiuQwtPlotCurve::setSamplesFromXValuesAndYValues( const std::vector const std::vector& yValues, bool keepOnlyPositiveValues ) { - setSamplesFromXValuesAndYValues( xValues, yValues, std::vector(), keepOnlyPositiveValues ); + computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues ); } //-------------------------------------------------------------------------------------------------- @@ -160,10 +77,9 @@ void RiuQwtPlotCurve::setSamplesFromDatesAndYValues( const std::vector& yValues, bool keepOnlyPositiveValues ) { - setSamplesFromXValuesAndYValues( RiuQwtPlotCurve::fromQDateTime( dateTimes ), - yValues, - std::vector(), - keepOnlyPositiveValues ); + auto xValues = RiuQwtPlotCurve::fromQDateTime( dateTimes ); + + computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues ); } //-------------------------------------------------------------------------------------------------- @@ -173,24 +89,9 @@ void RiuQwtPlotCurve::setSamplesFromTimeTAndYValues( const std::vector& const std::vector& yValues, bool keepOnlyPositiveValues ) { - setSamplesFromXValuesAndYValues( RiuQwtPlotCurve::fromTime_t( dateTimes ), - yValues, - std::vector(), - keepOnlyPositiveValues ); -} + auto xValues = RiuQwtPlotCurve::fromTime_t( dateTimes ); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::setSamplesFromTimeTAndYValues( const std::vector& dateTimes, - const std::vector& yValues, - const std::vector& yErrorValues, - bool keepOnlyPositiveValues ) -{ - setSamplesFromXValuesAndYValues( RiuQwtPlotCurve::fromTime_t( dateTimes ), - yValues, - yErrorValues, - keepOnlyPositiveValues ); + computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues ); } //-------------------------------------------------------------------------------------------------- @@ -348,69 +249,6 @@ void RiuQwtPlotCurve::setSymbolSkipPixelDistance( float distance ) m_symbolSkipPixelDistance = distance >= 0.0f ? distance : 0.0f; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::attach( QwtPlot* plot ) -{ - QwtPlotItem::attach( plot ); - if ( m_showErrorBars ) - { - m_errorBars->attach( plot ); - } - m_attachedToPlot = plot; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::detach() -{ - QwtPlotItem::detach(); - m_errorBars->detach(); - m_attachedToPlot = nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::clearErrorBars() -{ - m_errorBars->setSamples( nullptr ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::showErrorBars( bool show ) -{ - m_showErrorBars = show; - if ( m_showErrorBars && m_attachedToPlot ) - m_errorBars->attach( m_attachedToPlot ); - else - m_errorBars->detach(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::setErrorBarsColor( QColor color ) -{ - QwtIntervalSymbol* newSymbol = new QwtIntervalSymbol( QwtIntervalSymbol::Bar ); - newSymbol->setPen( QPen( color ) ); - m_errorBars->setSymbol( newSymbol ); -} - -//-------------------------------------------------------------------------------------------------- -/// Set the Qwt X-Axis (QwtPlot::xBottom or QwtPlot::xTop). -/// This is important to make sure the x-axis interval is set correctly. -/// WellLogPlots use top-axis and Summary uses bottom axis. -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotCurve::setErrorBarsXAxis( int axis ) -{ - m_errorBars->setXAxis( axis ); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -499,6 +337,26 @@ QwtGraphic RiuQwtPlotCurve::legendIcon( int index, const QSizeF& size ) const return icon; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::computeValidIntervalsAndSetCurveData( const std::vector& xValues, + const std::vector& yValues, + bool keepOnlyPositiveValues ) +{ + auto intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues( yValues, keepOnlyPositiveValues ); + + std::vector validYValues; + std::vector validXValues; + + RiaCurveDataTools::getValuesByIntervals( yValues, intervalsOfValidValues, &validYValues ); + RiaCurveDataTools::getValuesByIntervals( xValues, intervalsOfValidValues, &validXValues ); + + setSamples( validXValues.data(), validYValues.data(), static_cast( validXValues.size() ) ); + + setLineSegmentStartStopIndices( intervalsOfValidValues ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuQwtPlotCurve.h b/ApplicationCode/UserInterface/RiuQwtPlotCurve.h index 596e2d7160..1e68655e65 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotCurve.h +++ b/ApplicationCode/UserInterface/RiuQwtPlotCurve.h @@ -23,10 +23,6 @@ #include "qwt_plot_intervalcurve.h" #include "qwt_symbol.h" -#include - -class RiuErrorBarsQwtPlotCurve; - //================================================================================================== // // If infinite data is present in the curve data, Qwt is not able to draw a nice curve. @@ -50,12 +46,6 @@ class RiuErrorBarsQwtPlotCurve; class RiuQwtPlotCurve : public QwtPlotCurve { public: - enum ErrorAxis - { - ERROR_ALONG_X_AXIS, - ERROR_ALONG_Y_AXIS - }; - enum CurveInterpolationEnum { INTERPOLATION_POINT_TO_POINT, @@ -89,12 +79,6 @@ public: const std::vector& yValues, bool keepOnlyPositiveValues ); - void setSamplesFromXValuesAndYValues( const std::vector& xValues, - const std::vector& yValues, - const std::vector& errorValues, - bool keepOnlyPositiveValues, - ErrorAxis errorAxis = ERROR_ALONG_Y_AXIS ); - void setSamplesFromDatesAndYValues( const std::vector& dateTimes, const std::vector& yValues, bool keepOnlyPositiveValues ); @@ -103,30 +87,22 @@ public: const std::vector& yValues, bool keepOnlyPositiveValues ); - void setSamplesFromTimeTAndYValues( const std::vector& dateTimes, - const std::vector& yValues, - const std::vector& yErrorValues, - bool keepOnlyPositiveValues ); - void setLineSegmentStartStopIndices( const std::vector>& lineSegmentStartStopIndices ); void setSymbolSkipPixelDistance( float distance ); - - void attach( QwtPlot* plot ); - void detach(); - void clearErrorBars(); - void showErrorBars( bool show ); - void setErrorBarsColor( QColor color ); - void setErrorBarsXAxis( int axis ); void setPerPointLabels( const std::vector& labels ); - void setAppearance( LineStyleEnum lineStyle, - CurveInterpolationEnum interpolationType, - int curveThickness, - const QColor& curveColor ); + void setAppearance( LineStyleEnum lineStyle, + CurveInterpolationEnum interpolationType, + int curveThickness, + const QColor& curveColor ); + void setBlackAndWhiteLegendIcon( bool blackAndWhite ); QwtGraphic legendIcon( int index, const QSizeF& size ) const override; + static std::vector fromQDateTime( const std::vector& dateTimes ); + static std::vector fromTime_t( const std::vector& timeSteps ); + protected: void drawCurve( QPainter* p, int style, @@ -145,17 +121,15 @@ protected: int to ) const override; private: - static std::vector fromQDateTime( const std::vector& dateTimes ); - static std::vector fromTime_t( const std::vector& timeSteps ); + void computeValidIntervalsAndSetCurveData( const std::vector& xValues, + const std::vector& yValues, + bool keepOnlyPositiveValues ); private: - std::vector> m_polyLineStartStopIndices; - float m_symbolSkipPixelDistance; - - bool m_showErrorBars; - QwtPlotIntervalCurve* m_errorBars; - QwtPlot* m_attachedToPlot; - bool m_blackAndWhiteLegendIcon; + float m_symbolSkipPixelDistance; + bool m_blackAndWhiteLegendIcon; std::vector m_perPointLabels; + + std::vector> m_polyLineStartStopIndices; };