Grid Cross Plot: Add regression curves.

This commit is contained in:
Kristian Bendiksen
2023-06-16 11:15:56 +02:00
parent e1dacf7617
commit fdf4309d82
23 changed files with 1634 additions and 143 deletions

View File

@@ -108,6 +108,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuQwtDateScaleWrapper.h
${CMAKE_CURRENT_LIST_DIR}/RiuMatrixPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuMenuBarBuildTools.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotRectAnnotation.h
)
set(SOURCE_GROUP_SOURCE_FILES
@@ -217,6 +218,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuQwtDateScaleWrapper.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMatrixPlotWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMenuBarBuildTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotRectAnnotation.cpp
)
if(RESINSIGHT_USE_QT_CHARTS)

View File

@@ -19,9 +19,14 @@
#include "RiuQwtPlotCurve.h"
#include "RiaColorTools.h"
#include "RiaCurveDataTools.h"
#include "RiaImageTools.h"
#include "RimPlotCurve.h"
#include "RimPlotRectAnnotation.h"
#include "RiuQwtPlotRectAnnotation.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWidget.h"
#include "RiuQwtSymbol.h"
@@ -32,9 +37,11 @@
#include "qwt_painter.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_intervalcurve.h"
#include "qwt_plot_marker.h"
#include "qwt_point_mapper.h"
#include "qwt_scale_map.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include "qwt_weeding_curve_fitter.h"
#include <cmath>
@@ -59,6 +66,8 @@ RiuQwtPlotCurve::RiuQwtPlotCurve( RimPlotCurve* ownerRimCurve, const QString& ti
m_qwtCurveErrorBars->setSymbol( new QwtIntervalSymbol( QwtIntervalSymbol::Bar ) );
m_qwtCurveErrorBars->setItemAttribute( QwtPlotItem::Legend, false );
m_qwtCurveErrorBars->setZ( RiuQwtPlotCurveDefines::zDepthForIndex( RiuQwtPlotCurveDefines::ZIndex::Z_ERROR_BARS ) );
m_qwtPlotRectAnnotation = new RiuQwtPlotRectAnnotation;
}
//--------------------------------------------------------------------------------------------------
@@ -70,6 +79,9 @@ RiuQwtPlotCurve::~RiuQwtPlotCurve()
delete m_qwtCurveErrorBars;
m_qwtCurveErrorBars = nullptr;
delete m_qwtPlotRectAnnotation;
m_qwtPlotRectAnnotation = nullptr;
}
//--------------------------------------------------------------------------------------------------
@@ -322,6 +334,30 @@ void RiuQwtPlotCurve::attachToPlot( RiuPlotWidget* plotWidget )
{
m_qwtCurveErrorBars->attach( m_plotWidget->qwtPlot() );
}
if ( m_ownerRimCurve )
{
auto rectAnnotations = m_ownerRimCurve->rectAnnotations();
if ( !rectAnnotations.empty() )
{
auto [minX, maxX] = rectAnnotations[0]->rangeX();
auto [minY, maxY] = rectAnnotations[0]->rangeY();
m_qwtPlotRectAnnotation->setInterval( minX, maxX, minY, maxY );
QColor brushColor( RiaColorTools::toQColor( rectAnnotations[0]->color() ) );
brushColor.setAlphaF( rectAnnotations[0]->transparency() );
QBrush brush( brushColor );
m_qwtPlotRectAnnotation->setBrush( brush );
QColor penColor( RiaColorTools::toQColor( rectAnnotations[0]->color() ) );
QPen pen( penColor );
m_qwtPlotRectAnnotation->setPen( pen );
m_qwtPlotRectAnnotation->setText( rectAnnotations[0]->text() );
m_qwtPlotRectAnnotation->attach( m_plotWidget->qwtPlot() );
m_qwtPlotRectAnnotation->setVisible( rectAnnotations[0]->isChecked() );
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -331,6 +367,7 @@ void RiuQwtPlotCurve::detach()
{
QwtPlotCurve::detach();
m_qwtCurveErrorBars->detach();
m_qwtPlotRectAnnotation->detach();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -26,6 +26,7 @@
class QwtPlotIntervalCurve;
class RiuQwtPlotWidget;
class RiuQwtPlotRectAnnotation;
//==================================================================================================
//
@@ -99,5 +100,7 @@ protected:
QwtPlotIntervalCurve* m_qwtCurveErrorBars;
bool m_showErrorBars;
RiuQwtPlotRectAnnotation* m_qwtPlotRectAnnotation;
QPointer<RiuQwtPlotWidget> m_plotWidget;
};

View File

@@ -67,6 +67,13 @@ int RiuQwtPlotCurveDefines::zDepthForIndex( ZIndex index )
case RiuQwtPlotCurveDefines::ZIndex::Z_SINGLE_CURVE_OBSERVED:
return 500;
break;
case RiuQwtPlotCurveDefines::ZIndex::Z_PLOT_RECT_ANNOTATION:
return 600;
break;
case RiuQwtPlotCurveDefines::ZIndex::Z_REGRESSION_CURVE:
return 700;
break;
default:
break;
}

View File

@@ -45,7 +45,9 @@ enum class ZIndex
Z_ENSEMBLE_STAT_CURVE,
Z_SINGLE_CURVE_NON_OBSERVED,
Z_ERROR_BARS,
Z_SINGLE_CURVE_OBSERVED
Z_SINGLE_CURVE_OBSERVED,
Z_PLOT_RECT_ANNOTATION,
Z_REGRESSION_CURVE
};
int zDepthForIndex( ZIndex index );

View File

@@ -0,0 +1,214 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// 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.
//
// 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.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQwtPlotRectAnnotation.h"
#include "RiuGuiTheme.h"
#include "RiuQwtPlotCurveDefines.h"
#include "qwt_painter.h"
#include "qwt_plot_marker.h"
#include "qwt_scale_map.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include <QPainter>
#include <QRect>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotRectAnnotation::RiuQwtPlotRectAnnotation()
: QwtPlotItem( QwtText( "PlotRectAnnotation" ) )
{
setItemAttribute( QwtPlotItem::AutoScale, false );
setItemAttribute( QwtPlotItem::Legend, false );
QColor c( Qt::darkGray );
c.setAlpha( 50 );
m_brush = QBrush( c );
m_pen = QPen();
m_pen.setColor( Qt::black );
m_pen.setWidth( 2 );
setZ( RiuQwtPlotCurveDefines::zDepthForIndex( RiuQwtPlotCurveDefines::ZIndex::Z_PLOT_RECT_ANNOTATION ) );
m_textLabel = std::make_unique<QwtPlotMarker>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::setPen( const QPen& pen )
{
m_pen = pen;
itemChanged();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QPen& RiuQwtPlotRectAnnotation::pen() const
{
return m_pen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::setBrush( const QBrush& brush )
{
m_brush = brush;
itemChanged();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QBrush& RiuQwtPlotRectAnnotation::brush() const
{
return m_brush;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::setInterval( double minX, double maxX, double minY, double maxY )
{
m_intervalX.setMinValue( minX );
m_intervalX.setMaxValue( maxX );
m_intervalY.setMinValue( minY );
m_intervalY.setMaxValue( maxY );
itemChanged();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::draw( QPainter* painter, const QwtScaleMap& xMap, const QwtScaleMap& yMap, const QRectF& canvasRect ) const
{
if ( !m_intervalX.isValid() || !m_intervalY.isValid() ) return;
QPen pen = m_pen;
pen.setCapStyle( Qt::FlatCap );
double x1 = xMap.transform( m_intervalX.minValue() );
double x2 = xMap.transform( m_intervalX.maxValue() );
double y1 = yMap.transform( m_intervalY.minValue() );
double y2 = yMap.transform( m_intervalY.maxValue() );
const bool doAlign = QwtPainter::roundingAlignment( painter );
if ( doAlign )
{
x1 = qRound( x1 );
x2 = qRound( x2 );
y1 = qRound( y1 );
y2 = qRound( y2 );
}
QRectF r( x1, y1, x2 - x1, y2 - y1 );
r = r.normalized();
if ( m_brush.style() != Qt::NoBrush && x1 != x2 && y1 != y2 )
{
QwtPainter::fillRect( painter, r, m_brush );
}
if ( m_pen.style() != Qt::NoPen )
{
painter->setPen( m_pen );
QwtPainter::drawRect( painter, r );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRectF RiuQwtPlotRectAnnotation::boundingRect() const
{
QRectF br = QwtPlotItem::boundingRect();
if ( m_intervalX.isValid() && m_intervalY.isValid() )
{
br.setTop( m_intervalY.minValue() );
br.setBottom( m_intervalY.maxValue() );
br.setLeft( m_intervalX.minValue() );
br.setRight( m_intervalX.maxValue() );
}
return br;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotRectAnnotation::rtti() const
{
return 5001;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::setText( const QString& text )
{
QwtText label( text );
auto textColor = RiuGuiTheme::getColorByVariableName( "textColor" );
label.setColor( textColor );
label.setRenderFlags( Qt::AlignLeft );
m_textLabel->setLabel( label );
m_textLabel->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom );
m_textLabel->setLineStyle( QwtPlotMarker::NoLine );
m_textLabel->setSymbol( new QwtSymbol( QwtSymbol::NoSymbol ) );
m_textLabel->setValue( m_intervalX.minValue(), m_intervalY.maxValue() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::attach( QwtPlot* plot )
{
QwtPlotItem::attach( plot );
m_textLabel->attach( plot );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::detach()
{
QwtPlotItem::detach();
m_textLabel->detach();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotRectAnnotation::setVisible( bool isVisible )
{
QwtPlotItem::setVisible( isVisible );
m_textLabel->setVisible( isVisible );
}

View File

@@ -0,0 +1,69 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// 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.
//
// 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.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "qwt_interval.h"
#include "qwt_plot_item.h"
#include <QBrush>
#include <QPen>
#include <memory>
class QRectF;
class QPainter;
class QwtPlotMarker;
//==================================================================================================
/// Rectangular plot item for annotation areas of a plot.
///
//==================================================================================================
class RiuQwtPlotRectAnnotation : public QwtPlotItem
{
public:
RiuQwtPlotRectAnnotation();
~RiuQwtPlotRectAnnotation() override = default;
void setInterval( double minX, double maxX, double minY, double maxY );
void setPen( const QPen& );
const QPen& pen() const;
void setBrush( const QBrush& );
const QBrush& brush() const;
void setText( const QString& text );
int rtti() const override;
void draw( QPainter* painter, const QwtScaleMap& xMap, const QwtScaleMap& yMap, const QRectF& canvasRect ) const override;
QRectF boundingRect() const override;
void attach( QwtPlot* plot );
void detach();
void setVisible( bool isVisible ) override;
protected:
QwtInterval m_intervalX;
QwtInterval m_intervalY;
QPen m_pen;
QBrush m_brush;
QString m_text;
std::unique_ptr<QwtPlotMarker> m_textLabel;
};