2015-09-17 11:42:35 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright (C) 2015- Statoil ASA
|
|
|
|
// Copyright (C) 2015- Ceetron Solutions AS
|
2019-09-06 03:40:57 -05:00
|
|
|
//
|
2015-09-17 11:42:35 -05:00
|
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
2019-09-06 03:40:57 -05:00
|
|
|
//
|
2015-09-17 11:42:35 -05:00
|
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
2019-09-06 03:40:57 -05:00
|
|
|
//
|
|
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
2015-09-17 11:42:35 -05:00
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-09-04 02:08:29 -05:00
|
|
|
#include "RiuQwtPlotCurve.h"
|
2015-09-17 11:42:35 -05:00
|
|
|
|
2018-06-08 08:10:45 -05:00
|
|
|
#include "RiaCurveDataTools.h"
|
2019-03-28 14:09:25 -05:00
|
|
|
#include "RiaImageTools.h"
|
2020-12-07 09:33:55 -06:00
|
|
|
#include "RiaTimeTTools.h"
|
2019-11-25 02:43:38 -06:00
|
|
|
|
2018-09-04 02:08:29 -05:00
|
|
|
#include "RiuQwtSymbol.h"
|
|
|
|
|
2016-05-24 03:30:50 -05:00
|
|
|
#include "qwt_date.h"
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "qwt_interval_symbol.h"
|
2016-06-22 03:38:04 -05:00
|
|
|
#include "qwt_painter.h"
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "qwt_point_mapper.h"
|
2018-05-25 04:10:03 -05:00
|
|
|
#include "qwt_scale_map.h"
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "qwt_symbol.h"
|
2015-10-15 04:27:12 -05:00
|
|
|
|
2018-07-04 02:53:00 -05:00
|
|
|
#include <limits>
|
|
|
|
|
2018-07-04 02:34:54 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
/// Internal constants
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
#define DOUBLE_INF std::numeric_limits<double>::infinity()
|
2018-07-04 02:34:54 -05:00
|
|
|
|
2015-09-17 11:42:35 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2015-09-17 11:42:35 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
RiuQwtPlotCurve::RiuQwtPlotCurve( const QString& title )
|
|
|
|
: QwtPlotCurve( title )
|
2015-09-17 11:42:35 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
this->setLegendAttribute( QwtPlotCurve::LegendShowLine, true );
|
|
|
|
this->setLegendAttribute( QwtPlotCurve::LegendShowSymbol, true );
|
|
|
|
this->setLegendAttribute( QwtPlotCurve::LegendShowBrush, true );
|
2016-06-22 03:38:04 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
this->setRenderHint( QwtPlotItem::RenderAntialiased, true );
|
2016-06-22 03:38:04 -05:00
|
|
|
|
|
|
|
m_symbolSkipPixelDistance = 10.0f;
|
2018-05-25 04:10:03 -05:00
|
|
|
|
2019-03-28 14:09:25 -05:00
|
|
|
m_blackAndWhiteLegendIcon = false;
|
2015-09-17 11:42:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2015-09-17 11:42:35 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-12 04:13:38 -06:00
|
|
|
RiuQwtPlotCurve::~RiuQwtPlotCurve()
|
|
|
|
{
|
|
|
|
}
|
2015-09-17 11:42:35 -05:00
|
|
|
|
2018-05-25 04:10:03 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2018-05-25 04:10:03 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuQwtPlotCurve::setSamplesFromXValuesAndYValues( const std::vector<double>& xValues,
|
|
|
|
const std::vector<double>& yValues,
|
|
|
|
bool keepOnlyPositiveValues )
|
2018-05-25 04:10:03 -05:00
|
|
|
{
|
2019-11-25 02:43:38 -06:00
|
|
|
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
|
2016-11-22 04:13:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2016-11-22 04:13:34 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuQwtPlotCurve::setSamplesFromDatesAndYValues( const std::vector<QDateTime>& dateTimes,
|
|
|
|
const std::vector<double>& yValues,
|
|
|
|
bool keepOnlyPositiveValues )
|
2016-11-22 04:13:34 -06:00
|
|
|
{
|
2019-11-25 02:43:38 -06:00
|
|
|
auto xValues = RiuQwtPlotCurve::fromQDateTime( dateTimes );
|
2016-05-24 03:30:50 -05:00
|
|
|
|
2019-11-25 02:43:38 -06:00
|
|
|
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
|
2018-05-25 04:10:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2018-05-25 04:10:03 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuQwtPlotCurve::setSamplesFromTimeTAndYValues( const std::vector<time_t>& dateTimes,
|
|
|
|
const std::vector<double>& yValues,
|
|
|
|
bool keepOnlyPositiveValues )
|
2018-05-25 04:10:03 -05:00
|
|
|
{
|
2019-11-25 02:43:38 -06:00
|
|
|
auto xValues = RiuQwtPlotCurve::fromTime_t( dateTimes );
|
|
|
|
|
|
|
|
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
|
2016-11-22 04:13:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2015-09-17 11:42:35 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-11-04 07:35:41 -06:00
|
|
|
void RiuQwtPlotCurve::drawCurve( QPainter* p,
|
|
|
|
int style,
|
|
|
|
const QwtScaleMap& xMap,
|
|
|
|
const QwtScaleMap& yMap,
|
|
|
|
const QRectF& canvasRect,
|
|
|
|
int from,
|
|
|
|
int to ) const
|
2015-09-17 11:42:35 -05:00
|
|
|
{
|
2015-10-15 16:12:18 -05:00
|
|
|
size_t intervalCount = m_polyLineStartStopIndices.size();
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( intervalCount > 0 )
|
2015-09-17 11:42:35 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
for ( size_t intIdx = 0; intIdx < intervalCount; intIdx++ )
|
2015-09-17 11:42:35 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( m_polyLineStartStopIndices[intIdx].first == m_polyLineStartStopIndices[intIdx].second )
|
2015-11-06 03:08:35 -06:00
|
|
|
{
|
|
|
|
// Use a symbol to draw a single value, as a single value will not be visible
|
|
|
|
// when using QwtPlotCurve::drawCurve without symbols activated
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
QwtSymbol symbol( QwtSymbol::XCross );
|
|
|
|
symbol.setSize( 10, 10 );
|
2015-11-06 03:08:35 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
QwtPlotCurve::drawSymbols( p,
|
|
|
|
symbol,
|
|
|
|
xMap,
|
|
|
|
yMap,
|
|
|
|
canvasRect,
|
|
|
|
(int)m_polyLineStartStopIndices[intIdx].first,
|
|
|
|
(int)m_polyLineStartStopIndices[intIdx].second );
|
2015-11-06 03:08:35 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
QwtPlotCurve::drawCurve( p,
|
|
|
|
style,
|
|
|
|
xMap,
|
|
|
|
yMap,
|
|
|
|
canvasRect,
|
|
|
|
(int)m_polyLineStartStopIndices[intIdx].first,
|
|
|
|
(int)m_polyLineStartStopIndices[intIdx].second );
|
2015-11-06 03:08:35 -06:00
|
|
|
}
|
2015-09-17 11:42:35 -05:00
|
|
|
}
|
|
|
|
}
|
2015-11-06 03:08:35 -06:00
|
|
|
else
|
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
QwtPlotCurve::drawCurve( p, style, xMap, yMap, canvasRect, from, to );
|
2015-11-06 03:08:35 -06:00
|
|
|
}
|
2015-09-17 11:42:35 -05:00
|
|
|
};
|
2015-10-15 04:27:12 -05:00
|
|
|
|
2016-06-22 03:38:04 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
/// Drawing symbols but skipping if they are to close to the previous one
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuQwtPlotCurve::drawSymbols( QPainter* painter,
|
|
|
|
const QwtSymbol& symbol,
|
|
|
|
const QwtScaleMap& xMap,
|
|
|
|
const QwtScaleMap& yMap,
|
|
|
|
const QRectF& canvasRect,
|
|
|
|
int from,
|
|
|
|
int to ) const
|
2016-06-22 03:38:04 -05:00
|
|
|
{
|
2018-06-14 07:10:37 -05:00
|
|
|
QwtPointMapper mapper;
|
2019-09-06 03:40:57 -05:00
|
|
|
bool filterSymbols = m_symbolSkipPixelDistance > 0;
|
2018-06-14 07:10:37 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( filterSymbols )
|
2016-06-22 03:38:04 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
mapper.setFlag( QwtPointMapper::RoundPoints, QwtPainter::roundingAlignment( painter ) );
|
|
|
|
mapper.setFlag( QwtPointMapper::WeedOutPoints, testPaintAttribute( QwtPlotCurve::FilterPoints ) );
|
|
|
|
mapper.setBoundingRect( canvasRect );
|
2016-06-22 03:38:04 -05:00
|
|
|
}
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
const QPolygonF points = mapper.toPointsF( xMap, yMap, data(), from, to );
|
|
|
|
int pointCount = points.size();
|
|
|
|
QPolygonF pointsToDisplay;
|
2016-06-22 03:38:04 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( filterSymbols )
|
2016-06-22 03:38:04 -05:00
|
|
|
{
|
2018-06-14 07:10:37 -05:00
|
|
|
QPointF lastDrawnSymbolPos;
|
2016-06-22 03:38:04 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( pointCount > 0 )
|
2018-06-14 07:10:37 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
pointsToDisplay.push_back( points[0] );
|
2018-06-14 07:10:37 -05:00
|
|
|
lastDrawnSymbolPos = points[0];
|
|
|
|
}
|
2016-06-22 03:38:04 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
float sqSkipDist = m_symbolSkipPixelDistance * m_symbolSkipPixelDistance;
|
2019-07-25 00:38:46 -05:00
|
|
|
float sqSkipToLastDiff = m_symbolSkipPixelDistance / 10 * m_symbolSkipPixelDistance / 10;
|
2019-09-06 03:40:57 -05:00
|
|
|
for ( int pIdx = 1; pIdx < pointCount - 1; ++pIdx )
|
2016-06-22 03:38:04 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
QPointF diff = points[pIdx] - lastDrawnSymbolPos;
|
|
|
|
float sqDistBetweenSymbols = diff.x() * diff.x() + diff.y() * diff.y();
|
2018-06-14 07:10:37 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( sqDistBetweenSymbols > sqSkipDist )
|
2018-06-14 07:10:37 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( pIdx == pointCount - 2 )
|
|
|
|
{
|
|
|
|
QPointF diffToBack = points.back() - points[pIdx];
|
2019-07-25 00:38:46 -05:00
|
|
|
float sqDistToBack = diffToBack.x() * diffToBack.x() + diffToBack.y() * diffToBack.y();
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( sqDistToBack < sqSkipToLastDiff ) continue;
|
|
|
|
}
|
|
|
|
pointsToDisplay.push_back( points[pIdx] );
|
2018-06-14 07:10:37 -05:00
|
|
|
lastDrawnSymbolPos = points[pIdx];
|
|
|
|
}
|
2016-06-22 03:38:04 -05:00
|
|
|
}
|
2018-06-14 07:10:37 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( pointCount > 1 ) pointsToDisplay.push_back( points.back() );
|
2018-06-14 07:10:37 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pointsToDisplay = points;
|
2016-06-22 03:38:04 -05:00
|
|
|
}
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( pointsToDisplay.size() > 0 )
|
2018-06-14 07:10:37 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
symbol.drawSymbols( painter, pointsToDisplay );
|
2018-06-14 07:10:37 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
const RiuQwtSymbol* sym = dynamic_cast<const RiuQwtSymbol*>( &symbol );
|
2016-06-22 03:38:04 -05:00
|
|
|
|
2019-09-25 10:48:19 -05:00
|
|
|
if ( sym )
|
2018-06-14 07:10:37 -05:00
|
|
|
{
|
2019-10-08 01:18:09 -05:00
|
|
|
if ( m_perPointLabels.size() == static_cast<size_t>( pointsToDisplay.size() ) )
|
2019-09-25 10:48:19 -05:00
|
|
|
{
|
2019-10-08 01:18:09 -05:00
|
|
|
for ( int i = 0; i < pointsToDisplay.size(); ++i )
|
2019-09-25 10:48:19 -05:00
|
|
|
{
|
|
|
|
sym->renderSymbolLabel( painter, pointsToDisplay[i], m_perPointLabels[i] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( !sym->globalLabel().isEmpty() )
|
2018-06-14 07:10:37 -05:00
|
|
|
{
|
2019-09-25 10:48:19 -05:00
|
|
|
for ( auto& pt : pointsToDisplay )
|
|
|
|
{
|
|
|
|
sym->renderSymbolLabel( painter, pt, sym->globalLabel() );
|
|
|
|
}
|
2018-06-14 07:10:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-22 03:38:04 -05:00
|
|
|
}
|
|
|
|
|
2015-10-15 04:27:12 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2015-10-15 04:27:12 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-12 04:43:15 -06:00
|
|
|
void RiuQwtPlotCurve::setLineSegmentStartStopIndices( const std::vector<std::pair<size_t, size_t>>& lineSegmentStartStopIndices )
|
2015-11-06 01:32:58 -06:00
|
|
|
{
|
|
|
|
m_polyLineStartStopIndices = lineSegmentStartStopIndices;
|
2015-10-15 04:27:12 -05:00
|
|
|
}
|
2016-06-22 03:38:04 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2016-06-22 03:38:04 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuQwtPlotCurve::setSymbolSkipPixelDistance( float distance )
|
2016-06-22 03:38:04 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
m_symbolSkipPixelDistance = distance >= 0.0f ? distance : 0.0f;
|
2016-06-22 03:38:04 -05:00
|
|
|
}
|
2017-11-08 00:38:25 -06:00
|
|
|
|
2019-09-25 10:48:19 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RiuQwtPlotCurve::setPerPointLabels( const std::vector<QString>& labels )
|
|
|
|
{
|
|
|
|
m_perPointLabels = labels;
|
|
|
|
}
|
|
|
|
|
2018-09-04 02:08:29 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2021-01-05 07:01:10 -06:00
|
|
|
void RiuQwtPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
|
|
|
|
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
|
|
|
|
int requestedCurveThickness,
|
|
|
|
const QColor& curveColor,
|
|
|
|
const QBrush& fillBrush /* = QBrush( Qt::NoBrush )*/ )
|
2018-09-04 02:08:29 -05:00
|
|
|
{
|
|
|
|
QwtPlotCurve::CurveStyle curveStyle = QwtPlotCurve::NoCurve;
|
2019-09-06 03:40:57 -05:00
|
|
|
Qt::PenStyle penStyle = Qt::NoPen;
|
2018-09-04 02:08:29 -05:00
|
|
|
|
2019-02-25 01:29:16 -06:00
|
|
|
// Qwt bug workaround (#4135): need to set 0 curve thickness for STYLE_NONE
|
|
|
|
int curveThickness = 0;
|
2021-01-05 07:01:10 -06:00
|
|
|
if ( lineStyle != RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_NONE )
|
2018-09-04 02:08:29 -05:00
|
|
|
{
|
2019-02-25 01:29:16 -06:00
|
|
|
curveThickness = requestedCurveThickness;
|
2019-09-06 03:40:57 -05:00
|
|
|
switch ( interpolationType )
|
2018-09-04 02:08:29 -05:00
|
|
|
{
|
2021-01-05 07:01:10 -06:00
|
|
|
case RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_STEP_LEFT:
|
2019-09-06 03:40:57 -05:00
|
|
|
curveStyle = QwtPlotCurve::Steps;
|
|
|
|
setCurveAttribute( QwtPlotCurve::Inverted, false );
|
|
|
|
break;
|
2021-01-05 07:01:10 -06:00
|
|
|
case RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT: // Fall through
|
2019-09-06 03:40:57 -05:00
|
|
|
default:
|
|
|
|
curveStyle = QwtPlotCurve::Lines;
|
|
|
|
break;
|
2018-09-04 02:08:29 -05:00
|
|
|
}
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
switch ( lineStyle )
|
2018-09-04 02:08:29 -05:00
|
|
|
{
|
2021-01-05 07:01:10 -06:00
|
|
|
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID:
|
2019-09-06 03:40:57 -05:00
|
|
|
penStyle = Qt::SolidLine;
|
|
|
|
break;
|
2021-01-05 07:01:10 -06:00
|
|
|
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DASH:
|
2019-09-06 03:40:57 -05:00
|
|
|
penStyle = Qt::DashLine;
|
|
|
|
break;
|
2021-01-05 07:01:10 -06:00
|
|
|
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DOT:
|
2019-09-06 03:40:57 -05:00
|
|
|
penStyle = Qt::DotLine;
|
|
|
|
break;
|
2021-01-05 07:01:10 -06:00
|
|
|
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DASH_DOT:
|
2019-09-06 03:40:57 -05:00
|
|
|
penStyle = Qt::DashDotLine;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2018-09-04 02:08:29 -05:00
|
|
|
}
|
|
|
|
}
|
2019-09-06 03:40:57 -05:00
|
|
|
QPen curvePen( curveColor );
|
|
|
|
curvePen.setWidth( curveThickness );
|
|
|
|
curvePen.setStyle( penStyle );
|
2018-09-04 02:08:29 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
setPen( curvePen );
|
|
|
|
setStyle( curveStyle );
|
2020-06-10 04:28:20 -05:00
|
|
|
setBrush( fillBrush );
|
2018-09-04 02:08:29 -05:00
|
|
|
}
|
|
|
|
|
2019-03-28 14:09:25 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuQwtPlotCurve::setBlackAndWhiteLegendIcon( bool blackAndWhite )
|
2019-03-28 14:09:25 -05:00
|
|
|
{
|
|
|
|
m_blackAndWhiteLegendIcon = blackAndWhite;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
QwtGraphic RiuQwtPlotCurve::legendIcon( int index, const QSizeF& size ) const
|
2019-03-28 14:09:25 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
QwtGraphic icon = QwtPlotCurve::legendIcon( index, size );
|
|
|
|
if ( m_blackAndWhiteLegendIcon )
|
2019-03-28 14:09:25 -05:00
|
|
|
{
|
|
|
|
QImage image = icon.toImage();
|
2019-09-06 03:40:57 -05:00
|
|
|
RiaImageTools::makeGrayScale( image );
|
|
|
|
|
|
|
|
QPainter painter( &icon );
|
|
|
|
painter.drawImage( QPoint( 0, 0 ), image );
|
2019-03-28 14:09:25 -05:00
|
|
|
}
|
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
2019-11-25 02:43:38 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RiuQwtPlotCurve::computeValidIntervalsAndSetCurveData( const std::vector<double>& xValues,
|
|
|
|
const std::vector<double>& yValues,
|
|
|
|
bool keepOnlyPositiveValues )
|
|
|
|
{
|
|
|
|
auto intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues( yValues, keepOnlyPositiveValues );
|
|
|
|
|
|
|
|
std::vector<double> validYValues;
|
|
|
|
std::vector<double> validXValues;
|
|
|
|
|
|
|
|
RiaCurveDataTools::getValuesByIntervals( yValues, intervalsOfValidValues, &validYValues );
|
|
|
|
RiaCurveDataTools::getValuesByIntervals( xValues, intervalsOfValidValues, &validXValues );
|
|
|
|
|
|
|
|
setSamples( validXValues.data(), validYValues.data(), static_cast<int>( validXValues.size() ) );
|
|
|
|
|
2019-11-29 09:00:38 -06:00
|
|
|
setLineSegmentStartStopIndices( RiaCurveDataTools::computePolyLineStartStopIndices( intervalsOfValidValues ) );
|
2019-11-25 02:43:38 -06:00
|
|
|
}
|
|
|
|
|
2017-11-08 00:38:25 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-08 00:38:25 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
std::vector<double> RiuQwtPlotCurve::fromQDateTime( const std::vector<QDateTime>& dateTimes )
|
2017-11-08 00:38:25 -06:00
|
|
|
{
|
|
|
|
std::vector<double> doubleValues;
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( !dateTimes.empty() )
|
2017-11-08 00:38:25 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
doubleValues.reserve( dateTimes.size() );
|
2017-11-08 00:38:25 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
for ( const auto& dt : dateTimes )
|
2017-11-08 00:38:25 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
doubleValues.push_back( QwtDate::toDouble( dt ) );
|
2017-11-08 00:38:25 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return doubleValues;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-08 00:38:25 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
std::vector<double> RiuQwtPlotCurve::fromTime_t( const std::vector<time_t>& timeSteps )
|
2017-11-08 00:38:25 -06:00
|
|
|
{
|
|
|
|
std::vector<double> doubleValues;
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( !timeSteps.empty() )
|
2017-11-08 00:38:25 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
doubleValues.reserve( timeSteps.size() );
|
|
|
|
for ( const auto& time : timeSteps )
|
2017-11-08 00:38:25 -06:00
|
|
|
{
|
2020-12-07 09:33:55 -06:00
|
|
|
doubleValues.push_back( RiaTimeTTools::toDouble( time ) );
|
2017-11-08 00:38:25 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return doubleValues;
|
|
|
|
}
|