Merge pull request #8387 from OPM/qtcharts-summary-plots

Closes #8228 

Major refactoring of summary plotting. Now possible to create plots both with Qwt and QtChart as plotting tool.
This commit is contained in:
Kristian Bendiksen
2022-01-17 13:14:21 +01:00
committed by GitHub
parent d9bb82de91
commit 258fbddc10
145 changed files with 7245 additions and 2932 deletions

View File

@@ -5,10 +5,13 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuFemResultTextBuilder.h
${CMAKE_CURRENT_LIST_DIR}/RiuGeoQuestNavigation.h
${CMAKE_CURRENT_LIST_DIR}/RiuInterfaceToViewWindow.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotCurveSymbol.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtSymbol.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotCurve.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotCurve.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotCurveDefines.h
${CMAKE_CURRENT_LIST_DIR}/RiuRimQwtPlotCurve.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotItem.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItem.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindow.h
${CMAKE_CURRENT_LIST_DIR}/RiuMainWindow.h
${CMAKE_CURRENT_LIST_DIR}/RiuMainWindowBase.h
@@ -38,6 +41,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuDockedQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuGridCrossQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuTextDialog.h
${CMAKE_CURRENT_LIST_DIR}/RiuTimeStepChangedHandler.h
${CMAKE_CURRENT_LIST_DIR}/RiuTofAccumulatedPhaseFractionsPlot.h
@@ -52,6 +56,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotPage.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotBook.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotLegend.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotAnnotationTool.h
@@ -102,10 +107,12 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuFemResultTextBuilder.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuGeoQuestNavigation.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuInterfaceToViewWindow.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotCurveSymbol.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtSymbol.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotCurveDefines.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuRimQwtPlotCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItem.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindow.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMainWindow.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMainWindowBase.cpp
@@ -134,6 +141,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuDockedQwtPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuGridCrossQwtPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuTextDialog.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuTimeStepChangedHandler.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuTofAccumulatedPhaseFractionsPlot.cpp
@@ -147,6 +155,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotPage.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotBook.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotLegend.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotAnnotationTool.cpp
@@ -190,12 +199,32 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuTextContentFrame.cpp
)
if(Qt5Charts_FOUND)
list(APPEND CODE_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.h)
if(RESINSIGHT_USE_QT_CHARTS)
list(
APPEND
CODE_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurve.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotTools.h
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurveSymbol.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQtChartsPlot.h
)
list(APPEND CODE_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.cpp)
list(
APPEND
CODE_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotCurveSymbol.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQtChartsPlot.cpp
)
# list(APPEND QT_MOC_HEADERS ${CMAKE_CURRENT_LIST_DIR}/RiuQtChartView.h)
list(APPEND QT_MOC_HEADERS ${CMAKE_CURRENT_LIST_DIR}/RiuQtChartsPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQtChartsPlot.h
)
endif()
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
@@ -224,11 +253,13 @@ list(
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotPage.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotBook.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotLegend.h
${CMAKE_CURRENT_LIST_DIR}/RiuRecentFileActionProvider.h
${CMAKE_CURRENT_LIST_DIR}/RiuDockedQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuGridCrossQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuTofAccumulatedPhaseFractionsPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.h

View File

@@ -25,10 +25,12 @@
#include "RimFlowCharacteristicsPlot.h"
#include "RiuPlotCurveSymbol.h"
#include "RiuQwtPlotCurve.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuQwtPlotZoomer.h"
#include "RiuQwtSymbol.h"
#include "RiuResultQwtPlot.h"
#include "cvfColor3.h"
@@ -39,7 +41,6 @@
#include "qwt_legend.h"
#include "qwt_plot.h"
#include "qwt_plot_zoomer.h"
#include "qwt_symbol.h"
#include <QBoxLayout>
#include <QContextMenuEvent>
@@ -194,9 +195,7 @@ void RiuFlowCharacteristicsPlot::addCurveWithLargeSymbol( QwtPlot* plot,
{
auto curve = createEmptyCurve( plot, curveName, color );
QwtSymbol::Style style = QwtSymbol::Diamond;
QwtSymbol* symbol = new QwtSymbol( style );
RiuPlotCurveSymbol* symbol = new RiuQwtSymbol( RiuPlotCurveSymbol::PointSymbolEnum::SYMBOL_DIAMOND );
symbol->setSize( 15, 15 );
symbol->setColor( color );
@@ -221,7 +220,7 @@ void RiuFlowCharacteristicsPlot::addCurveWithLargeSymbol( QwtPlot* plot,
RiuQwtPlotCurve*
RiuFlowCharacteristicsPlot::createEmptyCurve( QwtPlot* plot, const QString& curveName, const QColor& curveColor )
{
RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve( curveName );
RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve( nullptr, curveName );
plotCurve->setTitle( curveName );
plotCurve->setPen( QPen( curveColor ) );

View File

@@ -22,8 +22,6 @@
#include "cafPdmPointer.h"
#include "qwt_plot.h"
#include <QFrame>
#include <QPointer>
@@ -33,6 +31,7 @@ class RiuResultQwtPlot;
class RiuQwtPlotCurve;
class QLabel;
class QwtPlot;
namespace cvf
{

View File

@@ -30,11 +30,12 @@
#include "RiuContextMenuLauncher.h"
#include "RiuGuiTheme.h"
#include "RiuPlotAnnotationTool.h"
#include "RiuPlotCurve.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotItem.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuQwtPlotZoomer.h"
#include "RiuRimQwtPlotCurve.h"
#include "RiuWidgetDragger.h"
#include "cafCmdFeatureMenuBuilder.h"
@@ -44,6 +45,7 @@
#include "qwt_legend.h"
#include "qwt_legend_label.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_panner.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_widget.h"
@@ -62,29 +64,29 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimGridCrossPlot* plot, QWidget* paren
: RiuQwtPlotWidget( plot, parent )
{
// LeftButton for the zooming
m_zoomerLeft = new RiuQwtPlotZoomer( canvas() );
m_zoomerLeft = new RiuQwtPlotZoomer( qwtPlot()->canvas() );
m_zoomerLeft->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerLeft->initMousePattern( 1 );
// Attach a zoomer for the right axis
m_zoomerRight = new RiuQwtPlotZoomer( canvas() );
m_zoomerRight->setAxis( xTop, yRight );
m_zoomerRight = new RiuQwtPlotZoomer( qwtPlot()->canvas() );
m_zoomerRight->setAxis( QwtPlot::xTop, QwtPlot::yRight );
m_zoomerRight->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerRight->initMousePattern( 1 );
// MidButton for the panning
QwtPlotPanner* panner = new QwtPlotPanner( canvas() );
QwtPlotPanner* panner = new QwtPlotPanner( qwtPlot()->canvas() );
panner->setMouseButton( Qt::MidButton );
auto wheelZoomer = new RiuQwtPlotWheelZoomer( this );
auto wheelZoomer = new RiuQwtPlotWheelZoomer( qwtPlot() );
connect( wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) );
connect( m_zoomerLeft, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( m_zoomerRight, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) );
connect( this,
SIGNAL( plotItemSelected( QwtPlotItem*, bool, int ) ),
SLOT( onPlotItemSelected( QwtPlotItem*, bool, int ) ) );
SIGNAL( plotItemSelected( std::shared_ptr<RiuPlotItem>, bool, int ) ),
SLOT( onPlotItemSelected( std::shared_ptr<RiuPlotItem>, bool, int ) ) );
m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>( new RiuPlotAnnotationTool() );
m_selectedPointMarker = new QwtPlotMarker;
@@ -99,11 +101,11 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimGridCrossPlot* plot, QWidget* paren
m_selectedPointMarker->setSpacing( 3 );
m_selectedPointMarker->setZ( 1000.0 ); // Make sure it ends up in front of highlighted curves.
RiuQwtPlotTools::setCommonPlotBehaviour( this );
RiuQwtPlotTools::setDefaultAxes( this );
RiuQwtPlotTools::setCommonPlotBehaviour( qwtPlot() );
RiuQwtPlotTools::setDefaultAxes( qwtPlot() );
this->installEventFilter( this );
this->canvas()->installEventFilter( this );
this->qwtPlot()->canvas()->installEventFilter( this );
setInternalQwtLegendVisible( true );
@@ -139,7 +141,7 @@ void RiuGridCrossQwtPlot::updateAnnotationObjects( RimPlotAxisPropertiesInterfac
for ( auto annotation : axisProperties->annotations() )
{
m_annotationTool->attachAnnotationLine( this,
m_annotationTool->attachAnnotationLine( qwtPlot(),
annotation->color(),
annotation->name(),
annotation->value(),
@@ -152,13 +154,13 @@ void RiuGridCrossQwtPlot::updateAnnotationObjects( RimPlotAxisPropertiesInterfac
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::setLegendFontSize( int fontSize )
{
if ( legend() )
if ( qwtPlot()->legend() )
{
QFont font = legend()->font();
QFont font = qwtPlot()->legend()->font();
font.setPixelSize( caf::FontTools::pointSizeToPixelSize( fontSize ) );
legend()->setFont( font );
qwtPlot()->legend()->setFont( font );
// Set font size for all existing labels
QList<QwtLegendLabel*> labels = legend()->findChildren<QwtLegendLabel*>();
QList<QwtLegendLabel*> labels = qwtPlot()->legend()->findChildren<QwtLegendLabel*>();
for ( QwtLegendLabel* label : labels )
{
label->setFont( font );
@@ -174,29 +176,32 @@ void RiuGridCrossQwtPlot::setInternalQwtLegendVisible( bool visible )
if ( visible )
{
QwtLegend* legend = new QwtLegend( this );
this->insertLegend( legend, BottomLegend );
this->qwtPlot()->insertLegend( legend, QwtPlot::BottomLegend );
}
else
{
this->insertLegend( nullptr );
this->qwtPlot()->insertLegend( nullptr );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int pointNumber )
void RiuGridCrossQwtPlot::onPlotItemSelected( std::shared_ptr<RiuPlotItem> plotItem, bool toggle, int pointNumber )
{
if ( pointNumber == -1 )
m_selectedPointMarker->detach();
else
{
QwtPlotCurve* curve = dynamic_cast<QwtPlotCurve*>( plotItem );
RiuQwtPlotItem* qwtPlotItem = dynamic_cast<RiuQwtPlotItem*>( plotItem.get() );
if ( !qwtPlotItem ) return;
QwtPlotCurve* curve = dynamic_cast<QwtPlotCurve*>( qwtPlotItem->qwtPlotItem() );
if ( curve )
{
QPointF sample = curve->sample( pointNumber );
m_selectedPointMarker->setValue( sample );
m_selectedPointMarker->setAxes( QwtPlot::xBottom, QwtPlot::yLeft );
m_selectedPointMarker->attach( this );
m_selectedPointMarker->attach( qwtPlot() );
QString curveName, xAxisName, yAxisName;
if ( curveText( curve, &curveName, &xAxisName, &yAxisName ) )
{
@@ -224,7 +229,7 @@ bool RiuGridCrossQwtPlot::curveText( const QwtPlotCurve* curve, QString* curveTi
{
CVF_ASSERT( curveTitle && xParamName && yParamName );
auto riuCurve = dynamic_cast<const RiuRimQwtPlotCurve*>( curve );
auto riuCurve = dynamic_cast<const RiuPlotCurve*>( curve );
if ( riuCurve )
{
auto crossPlotCurve = dynamic_cast<const RimGridCrossPlotCurve*>( riuCurve->ownerRimCurve() );

View File

@@ -17,7 +17,6 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "RiuPlotAnnotationTool.h"
#include "RiuQwtPlotWidget.h"
@@ -58,7 +57,7 @@ public:
void updateAnnotationObjects( RimPlotAxisPropertiesInterface* axisProperties );
void setLegendFontSize( int fontSize );
void setLegendFontSize( int fontSize ) override;
void setInternalQwtLegendVisible( bool visible );
protected:
@@ -68,7 +67,7 @@ protected:
private slots:
void onZoomedSlot();
void onPlotItemSelected( QwtPlotItem* selectedItem, bool toggleItem, int sampleIndex );
void onPlotItemSelected( std::shared_ptr<RiuPlotItem> selectedItem, bool toggleItem, int sampleIndex );
private:
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;

View File

@@ -20,9 +20,6 @@
#include "RiaColorTables.h"
#include "Riu3dSelectionManager.h"
#include "RiuQwtPlotTools.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
@@ -37,12 +34,14 @@
#include "RimGeoMechResultDefinition.h"
#include "RimGeoMechView.h"
#include "Riu3dSelectionManager.h"
#include "RiuQwtPlotTools.h"
#include "cvfAssert.h"
#include <QPainterPath>
#include <QTimer>
#include <QWidget>
#include <qevent.h>
#include "qwt_legend.h"
#include "qwt_plot_curve.h"

View File

@@ -20,12 +20,7 @@
#include "RiuDockedQwtPlot.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_item.h"
#include "cafTensor3.h"
#include "cvfColor3.h"
#include <array>
@@ -38,6 +33,7 @@ class RiuSelectionItem;
class RimGeoMechCase;
class RimGeoMechResultDefinition;
class RiuGeoMechSelectionItem;
class QwtPlotCurve;
//==================================================================================================
//

View File

@@ -29,19 +29,13 @@
#include "RiuMultiPlotPage.h"
#include "RiuPlotMainWindow.h"
#include "RiuPlotObjectPicker.h"
#include "RiuQwtPlotLegend.h"
#include "RiuQwtPlotWidget.h"
#include "RiuPlotWidget.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include "qwt_legend.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_renderer.h"
#include "qwt_scale_draw.h"
#include <QDebug>
#include <QFocusEvent>
#include <QFontMetrics>
@@ -156,7 +150,7 @@ RimViewWindow* RiuMultiPlotBook::ownerViewWindow() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotBook::addPlot( RiuQwtPlotWidget* plotWidget )
void RiuMultiPlotBook::addPlot( RiuPlotWidget* plotWidget )
{
// Push the plot to the back of the list
insertPlot( plotWidget, m_plotWidgets.size() );
@@ -165,7 +159,7 @@ void RiuMultiPlotBook::addPlot( RiuQwtPlotWidget* plotWidget )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotBook::insertPlot( RiuQwtPlotWidget* plotWidget, size_t index )
void RiuMultiPlotBook::insertPlot( RiuPlotWidget* plotWidget, size_t index )
{
m_plotWidgets.insert( static_cast<int>( index ), plotWidget );
scheduleUpdate();
@@ -174,7 +168,7 @@ void RiuMultiPlotBook::insertPlot( RiuQwtPlotWidget* plotWidget, size_t index )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotBook::removePlot( RiuQwtPlotWidget* plotWidget )
void RiuMultiPlotBook::removePlot( RiuPlotWidget* plotWidget )
{
if ( !plotWidget ) return;
@@ -277,7 +271,7 @@ void RiuMultiPlotBook::setAxisFontSizes( int axisTitleFontSize, int axisValueFon
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuMultiPlotBook::indexOfPlotWidget( RiuQwtPlotWidget* plotWidget )
int RiuMultiPlotBook::indexOfPlotWidget( RiuPlotWidget* plotWidget )
{
return m_plotWidgets.indexOf( plotWidget );
}
@@ -316,7 +310,7 @@ void RiuMultiPlotBook::scheduleUpdate()
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotBook::scheduleReplotOfAllPlots()
{
for ( RiuQwtPlotWidget* plotWidget : visiblePlotWidgets() )
for ( RiuPlotWidget* plotWidget : visiblePlotWidgets() )
{
plotWidget->scheduleReplot();
}
@@ -466,10 +460,10 @@ void RiuMultiPlotBook::performUpdate()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<QPointer<RiuQwtPlotWidget>> RiuMultiPlotBook::visiblePlotWidgets() const
QList<QPointer<RiuPlotWidget>> RiuMultiPlotBook::visiblePlotWidgets() const
{
QList<QPointer<RiuQwtPlotWidget>> plotWidgets;
for ( QPointer<RiuQwtPlotWidget> plotWidget : m_plotWidgets )
QList<QPointer<RiuPlotWidget>> plotWidgets;
for ( QPointer<RiuPlotWidget> plotWidget : m_plotWidgets )
{
CAF_ASSERT( plotWidget );
if ( plotWidget->isChecked() )
@@ -501,8 +495,8 @@ void RiuMultiPlotBook::createPages()
{
CAF_ASSERT( m_plotDefinition );
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = this->visiblePlotWidgets();
auto rowAndColumnCount = this->rowAndColumnCount( plotWidgets.size() );
QList<QPointer<RiuPlotWidget>> plotWidgets = this->visiblePlotWidgets();
auto rowAndColumnCount = this->rowAndColumnCount( plotWidgets.size() );
int rowsPerPage = m_plotDefinition->rowsPerPage();
int row = 0;

View File

@@ -17,7 +17,6 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "RiuMultiPlotPage.h"
#include "cafPdmPointer.h"
@@ -35,7 +34,7 @@
class RiaPlotWindowRedrawScheduler;
class RimMultiPlot;
class RiuMultiPlotPage;
class RiuQwtPlotWidget;
class RiuPlotWidget;
class BookFrame;
class QFocusEvent;
@@ -63,9 +62,9 @@ public:
RimViewWindow* ownerViewWindow() const override;
void addPlot( RiuQwtPlotWidget* plotWidget );
void insertPlot( RiuQwtPlotWidget* plotWidget, size_t index );
void removePlot( RiuQwtPlotWidget* plotWidget );
void addPlot( RiuPlotWidget* plotWidget );
void insertPlot( RiuPlotWidget* plotWidget, size_t index );
void removePlot( RiuPlotWidget* plotWidget );
void removeAllPlots();
void setPlotTitle( const QString& plotTitle );
@@ -77,7 +76,7 @@ public:
void setLegendFontSize( int legendFontSize );
void setAxisFontSizes( int axisTitleFontSize, int axisValueFontSize );
int indexOfPlotWidget( RiuQwtPlotWidget* plotWidget );
int indexOfPlotWidget( RiuPlotWidget* plotWidget );
bool pagePreviewModeEnabled() const;
void setPagePreviewModeEnabled( bool previewMode );
@@ -100,7 +99,7 @@ protected:
virtual bool showYAxis( int row, int column ) const;
QList<QPointer<RiuQwtPlotWidget>> visiblePlotWidgets() const;
QList<QPointer<RiuPlotWidget>> visiblePlotWidgets() const;
private:
void deleteAllPages();
@@ -120,7 +119,7 @@ protected:
QPointer<QVBoxLayout> m_bookLayout;
QList<QPointer<RiuMultiPlotPage>> m_pages;
QList<QPointer<RiuQwtPlotWidget>> m_plotWidgets;
QList<QPointer<RiuPlotWidget>> m_plotWidgets;
caf::PdmPointer<RimMultiPlot> m_plotDefinition;
QString m_plotTitle;
bool m_titleVisible;

View File

@@ -34,6 +34,7 @@
#include "RiuMainWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuPlotObjectPicker.h"
#include "RiuPlotWidget.h"
#include "RiuQwtPlotLegend.h"
#include "RiuQwtPlotWidget.h"
@@ -133,7 +134,7 @@ RimPlotWindow* RiuMultiPlotPage::ownerPlotDefinition()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotPage::addPlot( RiuQwtPlotWidget* plotWidget )
void RiuMultiPlotPage::addPlot( RiuPlotWidget* plotWidget )
{
// Insert the plot to the left of the scroll bar
insertPlot( plotWidget, m_plotWidgets.size() );
@@ -142,7 +143,7 @@ void RiuMultiPlotPage::addPlot( RiuQwtPlotWidget* plotWidget )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotPage::insertPlot( RiuQwtPlotWidget* plotWidget, size_t index )
void RiuMultiPlotPage::insertPlot( RiuPlotWidget* plotWidget, size_t index )
{
m_plotWidgets.insert( static_cast<int>( index ), plotWidget );
plotWidget->setVisible( false );
@@ -166,9 +167,13 @@ void RiuMultiPlotPage::insertPlot( RiuQwtPlotWidget* plotWidget, size_t index )
legend->setMaxColumns( legendColumns );
legend->horizontalScrollBar()->setVisible( false );
legend->verticalScrollBar()->setVisible( false );
legend->connect( plotWidget,
SIGNAL( legendDataChanged( const QVariant&, const QList<QwtLegendData>& ) ),
SLOT( updateLegend( const QVariant&, const QList<QwtLegendData>& ) ) );
RiuQwtPlotWidget* qwtPlotWidget = dynamic_cast<RiuQwtPlotWidget*>( plotWidget );
if ( qwtPlotWidget )
{
legend->connect( qwtPlotWidget->qwtPlot(),
SIGNAL( legendDataChanged( const QVariant&, const QList<QwtLegendData>& ) ),
SLOT( updateLegend( const QVariant&, const QList<QwtLegendData>& ) ) );
}
QObject::connect( legend, SIGNAL( legendUpdated() ), this, SLOT( onLegendUpdated() ) );
legend->contentsWidget()->layout()->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
@@ -183,7 +188,7 @@ void RiuMultiPlotPage::insertPlot( RiuQwtPlotWidget* plotWidget, size_t index )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotPage::removePlot( RiuQwtPlotWidget* plotWidget )
void RiuMultiPlotPage::removePlot( RiuPlotWidget* plotWidget )
{
if ( !plotWidget ) return;
@@ -215,7 +220,7 @@ void RiuMultiPlotPage::removePlot( RiuQwtPlotWidget* plotWidget )
void RiuMultiPlotPage::removeAllPlots()
{
auto plotWidgets = m_plotWidgets;
for ( RiuQwtPlotWidget* plotWidget : plotWidgets )
for ( RiuPlotWidget* plotWidget : plotWidgets )
{
removePlot( plotWidget );
}
@@ -296,7 +301,7 @@ void RiuMultiPlotPage::setPagePreviewModeEnabled( bool previewMode )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuMultiPlotPage::indexOfPlotWidget( RiuQwtPlotWidget* plotWidget )
int RiuMultiPlotPage::indexOfPlotWidget( RiuPlotWidget* plotWidget )
{
return m_plotWidgets.indexOf( plotWidget );
}
@@ -315,7 +320,7 @@ void RiuMultiPlotPage::scheduleUpdate()
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotPage::scheduleReplotOfAllPlots()
{
for ( RiuQwtPlotWidget* plotWidget : visiblePlotWidgets() )
for ( RiuPlotWidget* plotWidget : visiblePlotWidgets() )
{
plotWidget->scheduleReplot();
}
@@ -517,7 +522,7 @@ void RiuMultiPlotPage::onSelectionManagerSelectionChanged( const std::set<int>&
{
if ( !m_plotDefinition ) return;
for ( RiuQwtPlotWidget* plotWidget : m_plotWidgets )
for ( RiuPlotWidget* plotWidget : m_plotWidgets )
{
CAF_ASSERT( plotWidget );
RimPlot* plot = plotWidget->plotDefinition();
@@ -587,7 +592,7 @@ void RiuMultiPlotPage::reinsertPlotWidgets()
QList<QPointer<QLabel>> subTitles = this->subTitlesForVisiblePlots();
QList<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = this->visiblePlotWidgets();
QList<QPointer<RiuPlotWidget>> plotWidgets = this->visiblePlotWidgets();
if ( !plotWidgets.empty() )
{
@@ -615,10 +620,10 @@ void RiuMultiPlotPage::reinsertPlotWidgets()
subTitleFont.setPixelSize( m_subTitleFontPixelSize );
subTitles[visibleIndex]->setFont( subTitleFont );
plotWidgets[visibleIndex]->setAxisLabelsAndTicksEnabled( QwtPlot::yLeft,
plotWidgets[visibleIndex]->setAxisLabelsAndTicksEnabled( RiaDefines::PlotAxis::PLOT_AXIS_LEFT,
showYAxis( row, column ),
showYAxis( row, column ) );
plotWidgets[visibleIndex]->setAxisTitleEnabled( QwtPlot::yLeft, showYAxis( row, column ) );
plotWidgets[visibleIndex]->setAxisTitleEnabled( RiaDefines::PlotAxis::PLOT_AXIS_LEFT, showYAxis( row, column ) );
plotWidgets[visibleIndex]->setAxesFontsAndAlignment( m_axisTitleFontSize, m_axisValueFontSize );
{
@@ -679,7 +684,7 @@ int RiuMultiPlotPage::alignCanvasTops()
{
CVF_ASSERT( m_legends.size() == m_plotWidgets.size() );
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = visiblePlotWidgets();
QList<QPointer<RiuPlotWidget>> plotWidgets = visiblePlotWidgets();
QList<QPointer<RiuQwtPlotLegend>> legends = legendsForVisiblePlots();
if ( plotWidgets.empty() ) return 0;
@@ -689,22 +694,30 @@ int RiuMultiPlotPage::alignCanvasTops()
for ( int visibleIndex = 0; visibleIndex < plotWidgets.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
if ( plotWidgets[visibleIndex]->axisEnabled( QwtPlot::xTop ) )
RiuQwtPlotWidget* qwtPlotWidget = dynamic_cast<RiuQwtPlotWidget*>( plotWidgets[visibleIndex].data() );
if ( qwtPlotWidget )
{
QFont font = m_plotWidgets[visibleIndex]->axisFont( QwtPlot::xTop );
maxExtents[row] =
std::max( maxExtents[row], plotWidgets[visibleIndex]->axisScaleDraw( QwtPlot::xTop )->extent( font ) );
int row = visibleIndex / rowAndColumnCount.second;
if ( plotWidgets[visibleIndex]->axisEnabled( RiaDefines::PlotAxis::PLOT_AXIS_TOP ) )
{
QFont font = qwtPlotWidget->qwtPlot()->axisFont( QwtPlot::xTop );
maxExtents[row] = std::max( maxExtents[row],
qwtPlotWidget->qwtPlot()->axisScaleDraw( QwtPlot::xTop )->extent( font ) );
}
}
}
for ( int visibleIndex = 0; visibleIndex < plotWidgets.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
plotWidgets[visibleIndex]->axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( maxExtents[row] );
if ( legends[visibleIndex] )
RiuQwtPlotWidget* qwtPlotWidget = dynamic_cast<RiuQwtPlotWidget*>( plotWidgets[visibleIndex].data() );
if ( qwtPlotWidget )
{
legends[visibleIndex]->adjustSize();
int row = visibleIndex / rowAndColumnCount.second;
qwtPlotWidget->qwtPlot()->axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( maxExtents[row] );
if ( legends[visibleIndex] )
{
legends[visibleIndex]->adjustSize();
}
}
}
return maxExtents[0];
@@ -740,10 +753,10 @@ void RiuMultiPlotPage::clearGridLayout()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<QPointer<RiuQwtPlotWidget>> RiuMultiPlotPage::visiblePlotWidgets() const
QList<QPointer<RiuPlotWidget>> RiuMultiPlotPage::visiblePlotWidgets() const
{
QList<QPointer<RiuQwtPlotWidget>> plotWidgets;
for ( QPointer<RiuQwtPlotWidget> plotWidget : m_plotWidgets )
QList<QPointer<RiuPlotWidget>> plotWidgets;
for ( QPointer<RiuPlotWidget> plotWidget : m_plotWidgets )
{
if ( plotWidget->isChecked() )
{

View File

@@ -34,7 +34,7 @@
class RiaPlotWindowRedrawScheduler;
class RimPlotWindow;
class RiuQwtPlotLegend;
class RiuQwtPlotWidget;
class RiuPlotWidget;
class QFocusEvent;
class QLabel;
@@ -70,11 +70,11 @@ public:
RimViewWindow* ownerViewWindow() const override;
RimPlotWindow* ownerPlotDefinition();
void addPlot( RiuQwtPlotWidget* plotWidget );
void insertPlot( RiuQwtPlotWidget* plotWidget, size_t index );
void removePlot( RiuQwtPlotWidget* plotWidget );
void addPlot( RiuPlotWidget* plotWidget );
void insertPlot( RiuPlotWidget* plotWidget, size_t index );
void removePlot( RiuPlotWidget* plotWidget );
void removeAllPlots();
int indexOfPlotWidget( RiuQwtPlotWidget* plotWidget );
int indexOfPlotWidget( RiuPlotWidget* plotWidget );
void setPlotTitle( const QString& plotTitle );
void setTitleVisible( bool visible );
@@ -117,7 +117,7 @@ protected:
void clearGridLayout();
QList<QPointer<RiuQwtPlotWidget>> visiblePlotWidgets() const;
QList<QPointer<RiuPlotWidget>> visiblePlotWidgets() const;
QList<QPointer<RiuQwtPlotLegend>> legendsForVisiblePlots() const;
QList<QPointer<QLabel>> subTitlesForVisiblePlots() const;
@@ -138,7 +138,7 @@ protected:
QPointer<QLabel> m_plotTitle;
QList<QPointer<QLabel>> m_subTitles;
QList<QPointer<RiuQwtPlotLegend>> m_legends;
QList<QPointer<RiuQwtPlotWidget>> m_plotWidgets;
QList<QPointer<RiuPlotWidget>> m_plotWidgets;
caf::PdmPointer<RimPlotWindow> m_plotDefinition;
int m_titleFontPixelSize;

View File

@@ -0,0 +1,206 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- 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 "RiuPlotCurve.h"
#include "RiaCurveDataTools.h"
#include "RiaTimeTTools.h"
#include "RimPlotCurve.h"
#include "qwt_date.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurve::RiuPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title )
{
m_ownerRimCurve = ownerRimCurve;
m_symbolSkipPixelDistance = 10.0f;
m_blackAndWhiteLegendIcon = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurve::~RiuPlotCurve()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setSamplesValues( const std::vector<double>& xValues, const std::vector<double>& yValues )
{
setSamplesInPlot( xValues, yValues, static_cast<int>( xValues.size() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setSamplesFromXValuesAndYValues( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
{
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setSamplesFromDatesAndYValues( const std::vector<QDateTime>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
{
auto xValues = RiuPlotCurve::fromQDateTime( dateTimes );
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setSamplesFromTimeTAndYValues( const std::vector<time_t>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
{
auto xValues = RiuPlotCurve::fromTime_t( dateTimes );
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setLineSegmentStartStopIndices( const std::vector<std::pair<size_t, size_t>>& lineSegmentStartStopIndices )
{
m_polyLineStartStopIndices = lineSegmentStartStopIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setSymbolSkipPixelDistance( float distance )
{
m_symbolSkipPixelDistance = distance >= 0.0f ? distance : 0.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setPerPointLabels( const std::vector<QString>& labels )
{
m_perPointLabels = labels;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setBlackAndWhiteLegendIcon( bool blackAndWhite )
{
m_blackAndWhiteLegendIcon = blackAndWhite;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::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 );
setSamplesInPlot( validXValues, validYValues, static_cast<int>( validXValues.size() ) );
setLineSegmentStartStopIndices( RiaCurveDataTools::computePolyLineStartStopIndices( intervalsOfValidValues ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RiuPlotCurve::fromQDateTime( const std::vector<QDateTime>& dateTimes )
{
std::vector<double> doubleValues;
if ( !dateTimes.empty() )
{
doubleValues.reserve( dateTimes.size() );
for ( const auto& dt : dateTimes )
{
// TODO: remove Qwt usage here..
doubleValues.push_back( QwtDate::toDouble( dt ) );
}
}
return doubleValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RiuPlotCurve::fromTime_t( const std::vector<time_t>& timeSteps )
{
std::vector<double> doubleValues;
if ( !timeSteps.empty() )
{
doubleValues.reserve( timeSteps.size() );
for ( const auto& time : timeSteps )
{
doubleValues.push_back( RiaTimeTTools::toDouble( time ) );
}
}
return doubleValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurve::setSamplesFromXYErrorValues( const std::vector<double>& xValues,
const std::vector<double>& yValues,
const std::vector<double>& errorValues,
bool keepOnlyPositiveValues,
RiaCurveDataTools::ErrorAxis errorAxis )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotCurve* RiuPlotCurve::ownerRimCurve()
{
return m_ownerRimCurve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimPlotCurve* RiuPlotCurve::ownerRimCurve() const
{
return m_ownerRimCurve;
}

View File

@@ -0,0 +1,150 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- 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 "RiaCurveDataTools.h"
#include "RiuPlotCurveSymbol.h"
#include "RiuPlotWidget.h"
#include "RiuQwtPlotCurveDefines.h"
#include <QBrush>
#include <QColor>
#include <QDateTime>
#include <QString>
class RimPlotCurve;
//==================================================================================================
//
// If infinite data is present in the curve data, Qwt is not able to draw a nice curve.
// This class assumes that inf data is removed, and segments to be draw are indicated by start/stop indices into curve
// data.
//
// Single values in the curve are drawn using a CrossX symbol
//
// Here you can see the curve segments visualized. Curve segments are drawn between vector indices.
//
// 0 - 1
// 5 - 7
// 9 -10
//
// * *
// * * *
// Curve * * * ----- X
//
// Values 1.0|2.0|inf|inf|inf|1.0|2.0|1.0|inf|1.0|1.0|inf|1.0|inf
// Vec index 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13
//==================================================================================================
class RiuPlotCurve
{
public:
explicit RiuPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title = QString() );
explicit RiuPlotCurve();
virtual ~RiuPlotCurve();
virtual void setTitle( const QString& title ) = 0;
virtual void setSamplesValues( const std::vector<double>& xValues, const std::vector<double>& yValues );
void setSamplesFromXValuesAndYValues( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
void setSamplesFromDatesAndYValues( const std::vector<QDateTime>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
void setSamplesFromTimeTAndYValues( const std::vector<time_t>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
virtual void setSamplesFromXYErrorValues(
const std::vector<double>& xValues,
const std::vector<double>& yValues,
const std::vector<double>& errorValues,
bool keepOnlyPositiveValues,
RiaCurveDataTools::ErrorAxis errorAxis = RiaCurveDataTools::ErrorAxis::ERROR_ALONG_Y_AXIS );
void setLineSegmentStartStopIndices( const std::vector<std::pair<size_t, size_t>>& lineSegmentStartStopIndices );
void setSymbolSkipPixelDistance( float distance );
void setPerPointLabels( const std::vector<QString>& labels );
virtual void setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
int curveThickness,
const QColor& curveColor,
const QBrush& fillBrush = QBrush( Qt::NoBrush ) ) = 0;
virtual void setBrush( const QBrush& brush ) = 0;
void setBlackAndWhiteLegendIcon( bool blackAndWhite );
virtual void setVisibleInLegend( bool isVisibleInLegend ) = 0;
virtual void setLegendIconSize( const QSize& iconSize ) = 0;
virtual QSize legendIconSize() const = 0;
virtual QPixmap legendIcon( const QSizeF& size ) const = 0;
virtual void attachToPlot( RiuPlotWidget* plotWidget ) = 0;
virtual void showInPlot() = 0;
virtual void detach() = 0;
static std::vector<double> fromQDateTime( const std::vector<QDateTime>& dateTimes );
static std::vector<double> fromTime_t( const std::vector<time_t>& timeSteps );
virtual void setZ( int z ) = 0;
virtual void updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor ) = 0;
virtual void clearErrorBars() = 0;
virtual int numSamples() const = 0;
virtual std::pair<double, double> sample( int index ) const = 0;
RimPlotCurve* ownerRimCurve();
const RimPlotCurve* ownerRimCurve() const;
virtual std::pair<double, double> xDataRange() const = 0;
virtual std::pair<double, double> yDataRange() const = 0;
virtual void setXAxis( RiaDefines::PlotAxis axis ) = 0;
virtual void setYAxis( RiaDefines::PlotAxis axis ) = 0;
virtual void setSymbol( RiuPlotCurveSymbol* symbol ) = 0;
virtual RiuPlotCurveSymbol* createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const = 0;
protected:
virtual void
setSamplesInPlot( const std::vector<double>& xValues, const std::vector<double>& yValues, int numSamples ) = 0;
private:
void computeValidIntervalsAndSetCurveData( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
protected:
float m_symbolSkipPixelDistance;
bool m_blackAndWhiteLegendIcon;
std::vector<QString> m_perPointLabels;
std::vector<std::pair<size_t, size_t>> m_polyLineStartStopIndices;
caf::PdmPointer<RimPlotCurve> m_ownerRimCurve;
};

View File

@@ -0,0 +1,153 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Equinor ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RiuPlotCurveSymbol.h"
#include "cafFontTools.h"
#include "cvfAssert.h"
#include <QPainter>
#include <QRect>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol::RiuPlotCurveSymbol( PointSymbolEnum riuStyle,
const QString& label,
LabelPosition labelPosition,
int labelFontSizePt )
: m_style( riuStyle )
, m_globalLabel( label )
, m_labelPosition( labelPosition )
, m_labelFontSizePx( caf::FontTools::pointSizeToPixelSize( labelFontSizePt ) )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuPlotCurveSymbol::globalLabel() const
{
return m_globalLabel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurveSymbol::setGlobalLabel( const QString& label )
{
m_globalLabel = label;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurveSymbol::setLabelPosition( LabelPosition labelPosition )
{
m_labelPosition = labelPosition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotCurveSymbol::setLabelFontSize( int labelFontSizePt )
{
m_labelFontSizePx = caf::FontTools::pointSizeToPixelSize( labelFontSizePt );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol::PointSymbolEnum RiuPlotCurveSymbol::cycledSymbolStyle( int indexLevel1, int indexLevel2 )
{
std::vector<std::vector<PointSymbolEnum>> categorisedStyles = {
{ SYMBOL_ELLIPSE, SYMBOL_RECT, SYMBOL_DIAMOND },
{ SYMBOL_DOWN_TRIANGLE, SYMBOL_UP_TRIANGLE },
{ SYMBOL_LEFT_TRIANGLE, SYMBOL_RIGHT_TRIANGLE },
{ SYMBOL_CROSS, SYMBOL_XCROSS },
{ SYMBOL_STAR1, SYMBOL_STAR2 },
};
int level1Category = indexLevel1 % int( categorisedStyles.size() );
int level2Category = indexLevel2 % int( categorisedStyles[level1Category].size() );
return categorisedStyles[level1Category][level2Category];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol::PointSymbolEnum RiuPlotCurveSymbol::cycledSymbolStyle( int indexLevel )
{
std::vector<PointSymbolEnum> contrastingSymbols = { SYMBOL_ELLIPSE,
SYMBOL_CROSS,
SYMBOL_RECT,
SYMBOL_DOWN_TRIANGLE,
SYMBOL_UP_TRIANGLE,
SYMBOL_LEFT_TRIANGLE,
SYMBOL_RIGHT_TRIANGLE,
SYMBOL_STAR2,
SYMBOL_DIAMOND,
SYMBOL_STAR1 };
return contrastingSymbols[indexLevel % (int)contrastingSymbols.size()];
}
//--------------------------------------------------------------------------------------------------
/// Is this a symbol with an interior and a border? If false, it is just lines.
//--------------------------------------------------------------------------------------------------
bool RiuPlotCurveSymbol::isFilledSymbol( PointSymbolEnum symbol )
{
return symbol != SYMBOL_NONE && symbol != SYMBOL_CROSS && symbol != SYMBOL_XCROSS && symbol != SYMBOL_STAR1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRect RiuPlotCurveSymbol::labelBoundingRect( const QPainter* painter, const QRect& symbolRect, const QString& label ) const
{
CVF_ASSERT( painter );
QPoint symbolPosition = symbolRect.topLeft();
int symbolWidth = symbolRect.width();
int symbolHeight = symbolRect.height();
int labelWidth = painter->fontMetrics().width( label );
int labelHeight = painter->fontMetrics().height();
QPoint labelPosition;
if ( m_labelPosition == LabelAboveSymbol )
{
labelPosition = QPoint( symbolPosition.x() - labelWidth / 2, symbolPosition.y() - 5 );
}
else if ( m_labelPosition == LabelBelowSymbol )
{
labelPosition = QPoint( symbolPosition.x() - labelWidth / 2, symbolPosition.y() + symbolHeight + 5 );
}
else if ( m_labelPosition == LabelLeftOfSymbol )
{
labelPosition = QPoint( symbolPosition.x() - labelWidth - symbolWidth, symbolPosition.y() );
}
else if ( m_labelPosition == LabelRightOfSymbol )
{
labelPosition = QPoint( symbolPosition.x() + symbolWidth + 3, symbolPosition.y() );
}
return QRect( labelPosition.x(), labelPosition.y(), labelWidth, labelHeight );
}

View File

@@ -0,0 +1,101 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Equinor ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 <QString>
class QColor;
class QPen;
class QPainter;
class QRect;
class QPixmap;
//--------------------------------------------------------------------------------------------------
/// Interface for plot curve symbol
//--------------------------------------------------------------------------------------------------
class RiuPlotCurveSymbol
{
public:
enum LabelPosition
{
LabelAboveSymbol,
LabelBelowSymbol,
LabelLeftOfSymbol,
LabelRightOfSymbol
};
enum PointSymbolEnum
{
SYMBOL_NONE,
SYMBOL_ELLIPSE,
SYMBOL_RECT,
SYMBOL_DIAMOND,
SYMBOL_TRIANGLE,
SYMBOL_DOWN_TRIANGLE,
SYMBOL_CROSS,
SYMBOL_XCROSS,
SYMBOL_LEFT_ALIGNED_TRIANGLE, // Aligned so pin point is at lower right corner
SYMBOL_RIGHT_ALIGNED_TRIANGLE, // Aligned so pin point is at lower left corner
SYMBOL_LEFT_ANGLED_TRIANGLE,
SYMBOL_RIGHT_ANGLED_TRIANGLE,
SYMBOL_UP_TRIANGLE,
SYMBOL_STAR1,
SYMBOL_STAR2,
SYMBOL_HEXAGON,
SYMBOL_LEFT_TRIANGLE,
SYMBOL_RIGHT_TRIANGLE
};
RiuPlotCurveSymbol( PointSymbolEnum riuStyle,
const QString& label,
LabelPosition labelPosition = LabelAboveSymbol,
int labelFontSizePt = 8 );
QString globalLabel() const;
void setGlobalLabel( const QString& label );
void setLabelPosition( LabelPosition labelPosition );
void setLabelFontSize( int labelFontSizePt );
virtual void setPixmap( const QPixmap& pixmap ) = 0;
virtual void setSize( int width, int height ) = 0;
virtual void setColor( const QColor& color ) = 0;
virtual void setPen( const QPen& pen ) = 0;
virtual QRect boundingRect() const = 0;
static PointSymbolEnum cycledSymbolStyle( int indexLevel1, int indexLevel2 );
static PointSymbolEnum cycledSymbolStyle( int indexLevel );
static bool isFilledSymbol( PointSymbolEnum symbol );
QRect labelBoundingRect( const QPainter* painter, const QRect& symbolRect, const QString& label ) const;
protected:
PointSymbolEnum m_style;
QString m_globalLabel;
int m_labelFontSizePx;
LabelPosition m_labelPosition;
};

View File

@@ -0,0 +1,26 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- 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
class RiuPlotItem
{
public:
explicit RiuPlotItem(){};
virtual ~RiuPlotItem(){};
};

View File

@@ -0,0 +1,242 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RiuQwtPlotWidget.h"
#include "RiaPlotDefines.h"
#include "RiaPlotWindowRedrawScheduler.h"
#include "RimPlot.h"
#include "RiuDraggableOverlayFrame.h"
#include "cafAssert.h"
#include <algorithm>
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotWidget::RiuPlotWidget( RimPlot* plotDefinition, QWidget* parent )
: QWidget( parent )
, m_plotDefinition( plotDefinition )
, m_overlayMargins( 5 )
, m_plotTitle( "" )
, m_plotTitleEnabled( true )
{
CAF_ASSERT( m_plotDefinition );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotWidget::~RiuPlotWidget()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlot* RiuPlotWidget::plotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuPlotWidget::isChecked() const
{
if ( m_plotDefinition )
{
return m_plotDefinition->showWindow();
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuPlotWidget::colSpan() const
{
if ( m_plotDefinition )
{
return m_plotDefinition->colSpan();
}
return 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuPlotWidget::rowSpan() const
{
if ( m_plotDefinition )
{
return m_plotDefinition->rowSpan();
}
return 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString& RiuPlotWidget::plotTitle() const
{
return m_plotTitle;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotWidget::setPlotTitleEnabled( bool enabled )
{
m_plotTitleEnabled = enabled;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuPlotWidget::plotTitleEnabled() const
{
return m_plotTitleEnabled;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPoint RiuPlotWidget::dragStartPosition() const
{
return m_clickPosition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotWidget::scheduleReplot()
{
RiaPlotWindowRedrawScheduler::instance()->schedulePlotWidgetReplot( this );
}
//--------------------------------------------------------------------------------------------------
/// Adds an overlay frame. The overlay frame becomes the responsibility of the plot widget
//--------------------------------------------------------------------------------------------------
void RiuPlotWidget::addOverlayFrame( RiuDraggableOverlayFrame* overlayFrame )
{
if ( std::find( m_overlayFrames.begin(), m_overlayFrames.end(), overlayFrame ) == m_overlayFrames.end() )
{
overlayFrame->setParent( getParentForOverlay() );
m_overlayFrames.push_back( overlayFrame );
updateLayout();
}
}
//--------------------------------------------------------------------------------------------------
/// Remove the overlay widget. The frame becomes the responsibility of the caller
//--------------------------------------------------------------------------------------------------
void RiuPlotWidget::removeOverlayFrame( RiuDraggableOverlayFrame* overlayFrame )
{
CAF_ASSERT( overlayFrame );
overlayFrame->hide();
overlayFrame->setParent( nullptr );
m_overlayFrames.removeOne( overlayFrame );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotWidget::removeEventFilter()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotWidget::updateOverlayFrameLayout()
{
const int spacing = 5;
int xpos = spacing;
int ypos = spacing;
int widthOfCurrentColumn = 0;
QSize canvasSize = getParentForOverlay()->size();
QSize maxFrameSize( canvasSize.width() - 2 * m_overlayMargins, canvasSize.height() - 2 * m_overlayMargins );
for ( RiuDraggableOverlayFrame* frame : m_overlayFrames )
{
if ( frame )
{
QSize minFrameSize = frame->minimumSizeHint();
QSize desiredFrameSize = frame->sizeHint();
int width = std::min( std::max( minFrameSize.width(), desiredFrameSize.width() ), maxFrameSize.width() );
int height = std::min( std::max( minFrameSize.height(), desiredFrameSize.height() ), maxFrameSize.height() );
frame->resize( width, height );
if ( frame->anchorCorner() == RiuDraggableOverlayFrame::AnchorCorner::TopLeft )
{
if ( ypos + frame->height() + spacing > getParentForOverlay()->height() && widthOfCurrentColumn > 0 )
{
xpos += spacing + widthOfCurrentColumn;
ypos = spacing;
widthOfCurrentColumn = 0;
}
frame->move( xpos, ypos );
ypos += frame->height() + spacing;
widthOfCurrentColumn = std::max( widthOfCurrentColumn, frame->width() );
}
else if ( frame->anchorCorner() == RiuDraggableOverlayFrame::AnchorCorner::TopRight )
{
QRect frameRect = frame->frameGeometry();
QRect canvasRect = getParentForOverlay()->rect();
QPoint canvasTopRight = canvasRect.topRight();
frameRect.moveTopRight( QPoint( canvasTopRight.x() - spacing, canvasTopRight.y() + spacing ) );
frame->move( frameRect.topLeft() );
}
frame->show();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuPlotWidget::overlayMargins() const
{
return m_overlayMargins;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuPlotWidget::ownerViewWindow() const
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuPlotWidget::defaultMinimumWidth()
{
return 80;
}

View File

@@ -0,0 +1,194 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RiaPlotDefines.h"
#include "RiuInterfaceToViewWindow.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include <QPointer>
#include <QWidget>
class RiaPlotWindowRedrawScheduler;
class RimPlot;
class RimPlotCurve;
class RiuDraggableOverlayFrame;
class RiuPlotCurve;
class QPainter;
class QPaintDevice;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuPlotWidget : public QWidget, public RiuInterfaceToViewWindow
{
Q_OBJECT
public:
enum class AxisScaleType
{
LINEAR,
LOGARITHMIC,
DATE
};
enum class Legend
{
BOTTOM,
TOP,
LEFT,
RIGHT
};
enum class PlotItemType
{
CURVE,
LEGEND
};
RiuPlotWidget( RimPlot* plotDefinition, QWidget* parent = nullptr );
~RiuPlotWidget() override;
RimPlot* plotDefinition();
bool isChecked() const;
int colSpan() const;
int rowSpan() const;
virtual int axisTitleFontSize( RiaDefines::PlotAxis axis ) const = 0;
virtual int axisValueFontSize( RiaDefines::PlotAxis axis ) const = 0;
virtual void setAxisFontsAndAlignment( RiaDefines::PlotAxis,
int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter ) = 0;
virtual void setAxesFontsAndAlignment( int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter ) = 0;
virtual void enableAxis( RiaDefines::PlotAxis axis, bool isEnabled ) = 0;
virtual bool axisEnabled( RiaDefines::PlotAxis axis ) const = 0;
virtual void setAxisScale( RiaDefines::PlotAxis axis, double min, double max ) = 0;
virtual void setAxisAutoScale( RiaDefines::PlotAxis axis, bool enable ) = 0;
virtual void setAxisMaxMinor( RiaDefines::PlotAxis axis, int maxMinor ) = 0;
virtual void setAxisMaxMajor( RiaDefines::PlotAxis axis, int maxMajor ) = 0;
virtual RiuPlotWidget::AxisScaleType axisScaleType( RiaDefines::PlotAxis axis ) const = 0;
virtual void setAxisScaleType( RiaDefines::PlotAxis axis, RiuPlotWidget::AxisScaleType axisScaleType ) = 0;
virtual void setAxisTitleText( RiaDefines::PlotAxis axis, const QString& title ) = 0;
virtual void setAxisTitleEnabled( RiaDefines::PlotAxis axis, bool enable ) = 0;
virtual void setPlotTitle( const QString& plotTitle ) = 0;
const QString& plotTitle() const;
void setPlotTitleEnabled( bool enabled );
bool plotTitleEnabled() const;
virtual void setPlotTitleFontSize( int titleFontSize ) = 0;
virtual void setLegendFontSize( int fontSize ) = 0;
virtual void setInternalLegendVisible( bool visible ) = 0;
virtual void insertLegend( RiuPlotWidget::Legend ) = 0;
virtual void clearLegend() = 0;
virtual void updateLegend() = 0;
virtual void detachItems( RiuPlotWidget::PlotItemType plotItemType ) = 0;
virtual std::pair<double, double> axisRange( RiaDefines::PlotAxis axis ) const = 0;
virtual void setAxisRange( RiaDefines::PlotAxis axis, double min, double max ) = 0;
virtual void setAxisInverted( RiaDefines::PlotAxis axis, bool isInverted ) = 0;
virtual void setAxisLabelsAndTicksEnabled( RiaDefines::PlotAxis axis, bool enableLabels, bool enableTicks ) = 0;
virtual void enableGridLines( RiaDefines::PlotAxis axis, bool majorGridLines, bool minorGridLines ) = 0;
virtual void setMajorAndMinorTickIntervals( RiaDefines::PlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minValue,
double maxValue ) = 0;
virtual void setMajorAndMinorTickIntervalsAndRange( RiaDefines::PlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minTickValue,
double maxTickValue,
double rangeMin,
double rangeMax ) = 0;
virtual void setAutoTickIntervalCounts( RiaDefines::PlotAxis axis,
int maxMajorTickIntervalCount,
int maxMinorTickIntervalCount ) = 0;
virtual double majorTickInterval( RiaDefines::PlotAxis axis ) const = 0;
virtual double minorTickInterval( RiaDefines::PlotAxis axis ) const = 0;
virtual int axisExtent( RiaDefines::PlotAxis axis ) const = 0;
QPoint dragStartPosition() const;
void scheduleReplot();
virtual void replot() = 0;
void addOverlayFrame( RiuDraggableOverlayFrame* overlayWidget );
void removeOverlayFrame( RiuDraggableOverlayFrame* overlayWidget );
virtual void updateLayout() = 0;
virtual void renderTo( QPainter* painter, const QRect& targetRect, double scaling ) = 0;
virtual void renderTo( QPaintDevice* painter, const QRect& targetRect ) = 0;
int overlayMargins() const;
RimViewWindow* ownerViewWindow() const override;
virtual void removeEventFilter();
virtual void updateAxes() = 0;
virtual RiuPlotCurve* createPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title, const QColor& color ) = 0;
virtual const QColor& backgroundColor() const = 0;
virtual QWidget* getParentForOverlay() const = 0;
virtual std::pair<RiuPlotCurve*, int> findClosestCurve( const QPoint& pos, double& distanceToClick ) const = 0;
protected:
void updateOverlayFrameLayout();
static int defaultMinimumWidth();
caf::PdmPointer<RimPlot> m_plotDefinition;
QPoint m_clickPosition;
std::map<RiaDefines::PlotAxis, QString> m_axisTitles;
std::map<RiaDefines::PlotAxis, bool> m_axisTitlesEnabled;
const int m_overlayMargins;
QString m_plotTitle;
bool m_plotTitleEnabled;
QList<QPointer<RiuDraggableOverlayFrame>> m_overlayFrames;
};

View File

@@ -27,7 +27,7 @@ RiuQtChartView::RiuQtChartView( RimPlotWindow* plotWindow, QWidget* parent )
: QtCharts::QChartView( parent )
, m_plotWindow( plotWindow )
{
CAF_ASSERT( m_plotWindow );
setMouseTracking( true );
}
//--------------------------------------------------------------------------------------------------
@@ -44,3 +44,57 @@ RimViewWindow* RiuQtChartView::ownerViewWindow() const
{
return m_plotWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartView::mousePressEvent( QMouseEvent* event )
{
if ( event->buttons() & Qt::MiddleButton )
{
m_isPanning = true;
m_panStartPosition = event->pos();
setCursor( Qt::ClosedHandCursor );
event->accept();
}
else
{
event->ignore();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartView::mouseReleaseEvent( QMouseEvent* event )
{
if ( event->buttons() & Qt::MiddleButton )
{
m_isPanning = false;
setCursor( Qt::ArrowCursor );
event->accept();
}
else
{
event->ignore();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartView::mouseMoveEvent( QMouseEvent* event )
{
if ( event->buttons() & Qt::MiddleButton && m_isPanning )
{
QPoint newPosition = event->pos();
QPointF delta = mapToScene( newPosition ) - mapToScene( m_panStartPosition );
chart()->scroll( -delta.x(), delta.y() );
m_panStartPosition = newPosition;
event->accept();
}
else
{
event->ignore();
}
}

View File

@@ -37,6 +37,14 @@ public:
RimViewWindow* ownerViewWindow() const override;
protected:
void mouseReleaseEvent( QMouseEvent* event ) override;
void mousePressEvent( QMouseEvent* event ) override;
void mouseMoveEvent( QMouseEvent* event ) override;
private:
caf::PdmPointer<RimPlotWindow> m_plotWindow;
bool m_isPanning;
QPoint m_panStartPosition;
};

View File

@@ -0,0 +1,390 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- 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 "RiuQtChartsPlotCurve.h"
#include "RiaPlotDefines.h"
#include "RiuQtChartsPlotCurveSymbol.h"
#include "RiuQtChartsPlotWidget.h"
#include "cvfBoundingBox.h"
#include <QLegend>
#include <QLegendMarker>
#include <QtCharts/QChartView>
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsPlotCurve::RiuQtChartsPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title )
: RiuPlotCurve( ownerRimCurve, title )
{
m_plotWidget = nullptr;
m_lineSeries = new QtCharts::QLineSeries();
m_lineSeries->setName( title );
m_scatterSeries = new QtCharts::QScatterSeries();
m_scatterSeries->setName( title );
m_axisX = RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM;
m_axisY = RiaDefines::PlotAxis::PLOT_AXIS_LEFT;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsPlotCurve::~RiuQtChartsPlotCurve()
{
detach();
// Delete if it is still owned by by plot curve
delete m_lineSeries;
m_lineSeries = nullptr;
delete m_scatterSeries;
m_scatterSeries = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setTitle( const QString& title )
{
lineSeries()->setName( title );
scatterSeries()->setName( title );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
int requestedCurveThickness,
const QColor& curveColor,
const QBrush& fillBrush /* = QBrush( Qt::NoBrush )*/ )
{
Qt::PenStyle penStyle = RiuQwtPlotCurveDefines::convertToPenStyle( lineStyle );
QPen curvePen( curveColor );
curvePen.setWidth( requestedCurveThickness );
curvePen.setStyle( penStyle );
lineSeries()->setPen( curvePen );
lineSeries()->setBrush( fillBrush );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setBrush( const QBrush& brush )
{
lineSeries()->setBrush( brush );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::attachToPlot( RiuPlotWidget* plotWidget )
{
m_plotWidget = dynamic_cast<RiuQtChartsPlotWidget*>( plotWidget );
CAF_ASSERT( m_plotWidget );
if ( m_plotWidget->getLineSeries( this ) && m_plotWidget->getScatterSeries( this ) )
{
m_plotWidget->qtChart()->legend()->setMarkerShape( QtCharts::QLegend::MarkerShape::MarkerShapeFromSeries );
setVisibleInLegend( true );
lineSeries()->show();
}
else
{
m_plotWidget->attach( this, lineSeries(), scatterSeries(), m_axisX, m_axisY );
// Plot widget takes ownership.
m_lineSeries = nullptr;
m_scatterSeries = nullptr;
}
if ( scatterSeries() )
{
if ( m_symbol )
{
scatterSeries()->show();
auto qtChartsSymbol = dynamic_cast<RiuQtChartsPlotCurveSymbol*>( m_symbol.get() );
CAF_ASSERT( qtChartsSymbol );
qtChartsSymbol->applyToScatterSeries( scatterSeries() );
}
else
{
scatterSeries()->hide();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::detach()
{
QtCharts::QLineSeries* line = lineSeries();
if ( line )
{
line->hide();
}
QtCharts::QScatterSeries* scatter = scatterSeries();
if ( scatter )
{
scatter->hide();
}
if ( m_plotWidget ) setVisibleInLegend( false );
m_plotWidget = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::showInPlot()
{
// show();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setSamplesInPlot( const std::vector<double>& xValues,
const std::vector<double>& yValues,
int numValues )
{
CAF_ASSERT( xValues.size() == yValues.size() );
CAF_ASSERT( numValues <= static_cast<int>( xValues.size() ) );
CAF_ASSERT( numValues >= 0 );
QtCharts::QLineSeries* line = lineSeries();
QtCharts::QScatterSeries* scatter = scatterSeries();
line->clear();
scatter->clear();
for ( int i = 0; i < numValues; i++ )
{
line->append( xValues[i], yValues[i] );
scatter->append( xValues[i], yValues[i] );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setZ( int z )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::clearErrorBars()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setXAxis( RiaDefines::PlotAxis axis )
{
m_axisX = axis;
if ( m_plotWidget )
{
m_plotWidget->setXAxis( axis, lineSeries() );
m_plotWidget->setXAxis( axis, scatterSeries() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setYAxis( RiaDefines::PlotAxis axis )
{
m_axisY = axis;
if ( m_plotWidget )
{
m_plotWidget->setYAxis( axis, lineSeries() );
m_plotWidget->setYAxis( axis, scatterSeries() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQtChartsPlotCurve::numSamples() const
{
return lineSeries()->count();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQtChartsPlotCurve::sample( int index ) const
{
CAF_ASSERT( index >= 0 && index <= numSamples() );
auto p = lineSeries()->at( index );
return std::make_pair( p.x(), p.y() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQtChartsPlotCurve::xDataRange() const
{
cvf::BoundingBox bb = computeBoundingBox();
return std::make_pair( bb.min().x(), bb.max().x() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQtChartsPlotCurve::yDataRange() const
{
cvf::BoundingBox bb = computeBoundingBox();
return std::make_pair( bb.min().y(), bb.max().y() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox RiuQtChartsPlotCurve::computeBoundingBox() const
{
auto points = lineSeries()->pointsVector();
cvf::BoundingBox bb;
for ( auto p : points )
bb.add( cvf::Vec3d( p.x(), p.y(), 0.0 ) );
return bb;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setVisibleInLegend( bool isVisibleInLegend )
{
if ( !m_plotWidget ) return;
CAF_ASSERT( m_plotWidget->qtChart() );
CAF_ASSERT( m_plotWidget->qtChart()->legend() );
if ( scatterSeries() )
{
auto markers = m_plotWidget->qtChart()->legend()->markers( scatterSeries() );
if ( !markers.isEmpty() ) markers[0]->setVisible( isVisibleInLegend );
auto lineSeriesMarkers = m_plotWidget->qtChart()->legend()->markers( lineSeries() );
if ( !lineSeriesMarkers.isEmpty() ) lineSeriesMarkers[0]->setVisible( false );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QtCharts::QLineSeries* RiuQtChartsPlotCurve::lineSeries() const
{
if ( m_lineSeries )
return m_lineSeries;
else if ( m_plotWidget )
return dynamic_cast<QtCharts::QLineSeries*>( m_plotWidget->getLineSeries( this ) );
else
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QtCharts::QScatterSeries* RiuQtChartsPlotCurve::scatterSeries() const
{
if ( m_scatterSeries )
return m_scatterSeries;
else if ( m_plotWidget )
return dynamic_cast<QtCharts::QScatterSeries*>( m_plotWidget->getScatterSeries( this ) );
else
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setSymbol( RiuPlotCurveSymbol* symbol )
{
if ( symbol )
{
auto qtChartsSymbol = dynamic_cast<RiuQtChartsPlotCurveSymbol*>( symbol );
CAF_ASSERT( qtChartsSymbol );
m_symbol.reset( symbol );
if ( scatterSeries() )
{
qtChartsSymbol->applyToScatterSeries( scatterSeries() );
}
}
else
{
m_symbol.reset();
if ( scatterSeries() ) scatterSeries()->hide();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol* RiuQtChartsPlotCurve::createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const
{
return new RiuQtChartsPlotCurveSymbol( symbol );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurve::setLegendIconSize( const QSize& iconSize )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQtChartsPlotCurve::legendIconSize() const
{
// Default from Qwt
return QSize( 8, 8 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPixmap RiuQtChartsPlotCurve::legendIcon( const QSizeF& iconSize ) const
{
return QPixmap();
}

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- 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 "RiuPlotCurve.h"
#include "RiuQwtPlotCurveDefines.h"
#include "cvfBoundingBox.h"
#include <QLineSeries>
#include <QScatterSeries>
class RiuQtChartsPlotWidget;
class RiuPlotCurveSymbol;
//==================================================================================================
//
//==================================================================================================
class RiuQtChartsPlotCurve : public RiuPlotCurve
{
public:
explicit RiuQtChartsPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title = QString() );
~RiuQtChartsPlotCurve() override;
void setTitle( const QString& title ) override;
void setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
int curveThickness,
const QColor& curveColor,
const QBrush& fillBrush = QBrush( Qt::NoBrush ) ) override;
void setBrush( const QBrush& brush ) override;
void setLegendIconSize( const QSize& iconSize ) override;
QSize legendIconSize() const override;
QPixmap legendIcon( const QSizeF& size ) const override;
void attachToPlot( RiuPlotWidget* plotWidget ) override;
void showInPlot() override;
void setZ( int z ) override;
void updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor ) override;
void clearErrorBars() override;
int numSamples() const override;
std::pair<double, double> sample( int index ) const override;
std::pair<double, double> xDataRange() const override;
std::pair<double, double> yDataRange() const override;
void detach() override;
void setXAxis( RiaDefines::PlotAxis axis ) override;
void setYAxis( RiaDefines::PlotAxis axis ) override;
void setVisibleInLegend( bool isVisibleInLegend ) override;
void setSymbol( RiuPlotCurveSymbol* symbol ) override;
RiuPlotCurveSymbol* createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const override;
protected:
void setSamplesInPlot( const std::vector<double>&, const std::vector<double>&, int ) override;
QtCharts::QLineSeries* lineSeries() const;
QtCharts::QScatterSeries* scatterSeries() const;
cvf::BoundingBox computeBoundingBox() const;
QtCharts::QLineSeries* m_lineSeries;
QtCharts::QScatterSeries* m_scatterSeries;
std::shared_ptr<RiuPlotCurveSymbol> m_symbol;
RiuQtChartsPlotWidget* m_plotWidget;
RiaDefines::PlotAxis m_axisX;
RiaDefines::PlotAxis m_axisY;
};

View File

@@ -0,0 +1,618 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Equinor ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RiuQtChartsPlotCurveSymbol.h"
#include "RiaColorTools.h"
#include "RiaFontCache.h"
#include "RiaLogging.h"
#include "RiuPlotCurveSymbol.h"
#include "cvfAssert.h"
#include <QPainter>
#include <QPainterPath>
#include <QScatterSeries>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQtChartsPlotCurveSymbol::RiuQtChartsPlotCurveSymbol( PointSymbolEnum riuStyle,
const QString& label,
LabelPosition labelPosition,
int labelFontSizePt )
: RiuPlotCurveSymbol( riuStyle, label, labelPosition, labelFontSizePt )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setSize( int width, int height )
{
m_size = std::min( width, height );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setColor( const QColor& color )
{
m_color = color;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setPen( const QPen& pen )
{
m_pen = pen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setPixmap( const QPixmap& pixmap )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::applyToScatterSeries( QtCharts::QScatterSeries* series ) const
{
if ( m_style == PointSymbolEnum::SYMBOL_NONE )
{
series->hide();
return;
}
series->show();
if ( m_style == PointSymbolEnum::SYMBOL_RECT )
{
setImageBrush( series, createRectImage() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_ELLIPSE )
{
setImageBrush( series, createEllipseImage() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_CROSS )
{
setImageBrush( series, createCrossImage() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_XCROSS )
{
setImageBrush( series, createXCrossImage() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_DIAMOND )
{
setImageBrush( series, createDiamondImage() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_HEXAGON )
{
setImageBrush( series, createHexagonImage() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_STAR1 )
{
setImageBrush( series, createStar1Image() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_STAR1 )
{
setImageBrush( series, createStar1Image() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_STAR2 )
{
setImageBrush( series, createStar2Image() );
}
else if ( m_style == PointSymbolEnum::SYMBOL_TRIANGLE || m_style == PointSymbolEnum::SYMBOL_UP_TRIANGLE ||
m_style == PointSymbolEnum::SYMBOL_DOWN_TRIANGLE || m_style == PointSymbolEnum::SYMBOL_LEFT_TRIANGLE ||
m_style == PointSymbolEnum::SYMBOL_RIGHT_TRIANGLE )
{
setImageBrush( series, createTriangleImage( m_style ) );
}
else
{
RiaLogging::warning( "Missing symbol style." );
}
series->setMarkerSize( m_size );
series->setColor( m_color );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotCurveSymbol::setImageBrush( QtCharts::QScatterSeries* series, const QImage& image ) const
{
series->setMarkerShape( QtCharts::QScatterSeries::MarkerShapeRectangle );
series->setBrush( image );
series->setPen( QColor( Qt::transparent ) );
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawTriangleSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createTriangleImage( RiuPlotCurveSymbol::PointSymbolEnum symbolStyle ) const
{
QSize size( m_size, m_size );
QImage star( size.width(), size.height(), QImage::Format_ARGB32 );
star.fill( Qt::transparent );
QPainter painter( &star );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
double sw2 = 0.5 * size.width();
double sh2 = 0.5 * size.height();
QPolygonF triangle( 3 );
QPointF* trianglePoints = triangle.data();
double x = size.width() * 0.5;
double y = size.width() * 0.5;
const double x1 = x - sw2;
const double x2 = x1 + size.width();
const double y1 = y - sh2;
const double y2 = y1 + size.height();
if ( symbolStyle == PointSymbolEnum::SYMBOL_LEFT_TRIANGLE )
{
trianglePoints[0].rx() = x2;
trianglePoints[0].ry() = y1;
trianglePoints[1].rx() = x1;
trianglePoints[1].ry() = y;
trianglePoints[2].rx() = x2;
trianglePoints[2].ry() = y2;
}
if ( symbolStyle == PointSymbolEnum::SYMBOL_RIGHT_TRIANGLE )
{
trianglePoints[0].rx() = x1;
trianglePoints[0].ry() = y1;
trianglePoints[1].rx() = x2;
trianglePoints[1].ry() = y;
trianglePoints[2].rx() = x1;
trianglePoints[2].ry() = y2;
}
if ( symbolStyle == PointSymbolEnum::SYMBOL_UP_TRIANGLE || symbolStyle == PointSymbolEnum::SYMBOL_TRIANGLE )
{
trianglePoints[0].rx() = x1;
trianglePoints[0].ry() = y2;
trianglePoints[1].rx() = x;
trianglePoints[1].ry() = y1;
trianglePoints[2].rx() = x2;
trianglePoints[2].ry() = y2;
}
if ( symbolStyle == PointSymbolEnum::SYMBOL_DOWN_TRIANGLE )
{
trianglePoints[0].rx() = x1;
trianglePoints[0].ry() = y1;
trianglePoints[1].rx() = x;
trianglePoints[1].ry() = y2;
trianglePoints[2].rx() = x2;
trianglePoints[2].ry() = y1;
}
painter.drawPolygon( triangle );
return star;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawLineSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createCrossImage() const
{
const QSize size( m_size, m_size );
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
const double sw = size.width();
const double sh = size.height();
const double sw2 = 0.5 * size.width();
const double sh2 = 0.5 * size.height();
double midX = size.width() * 0.5;
double midY = size.height() * 0.5;
{
const double x = midX - sw2;
const double y = midY;
painter.drawLine( x, y, x + sw, y );
}
{
const double y = midY - sh2;
const double x = midX;
painter.drawLine( x, y, x, y + sh );
}
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawXCrossSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createXCrossImage() const
{
const QSize size( m_size, m_size );
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
const double sw = size.width();
const double sh = size.height();
const double sw2 = 0.5 * size.width();
const double sh2 = 0.5 * size.height();
double midX = size.width() * 0.5;
double midY = size.height() * 0.5;
const double x1 = midX - sw2;
const double x2 = x1 + sw;
const double y1 = midY - sh2;
const double y2 = y1 + sh;
painter.drawLine( x1, y1, x2, y2 );
painter.drawLine( x1, y2, x2, y1 );
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawRectSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createRectImage() const
{
const QSize size( m_size, m_size );
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
const double sw = size.width();
const double sh = size.height();
const double sw2 = 0.5 * size.width();
const double sh2 = 0.5 * size.height();
// Mid point
const double x = sw * 0.5;
const double y = sw * 0.5;
const QRectF r( x - sw2, y - sh2, sw, sh );
painter.drawRect( r );
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawEllipseSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createEllipseImage() const
{
const QSize size( m_size, m_size );
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
const double sw = size.width();
const double sh = size.height();
const double sw2 = 0.5 * size.width();
const double sh2 = 0.5 * size.height();
// Mid point
const double x = sw * 0.5;
const double y = sw * 0.5;
const QRectF r( x - sw2, y - sh2, sw, sh );
painter.drawEllipse( r );
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawStar1Symbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createStar1Image() const
{
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
QRectF r( 0, 0, m_size, m_size );
const double sqrt1_2 = 1.0 / sqrt( 2 );
const QPointF c = r.center();
const double d1 = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
painter.drawLine( r.left() + d1, r.top() + d1, r.right() - d1, r.bottom() - d1 );
painter.drawLine( r.left() + d1, r.bottom() - d1, r.right() - d1, r.top() + d1 );
painter.drawLine( c.x(), r.top(), c.x(), r.bottom() );
painter.drawLine( r.left(), c.y(), r.right(), c.y() );
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawStar2Symbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createStar2Image() const
{
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
QRectF r( 0, 0, m_size, m_size );
const double cos30 = 0.866025; // cos(30°)
const double dy = 0.25 * m_size;
const double dx = 0.5 * m_size * cos30 / 3.0;
QPolygonF star( 12 );
QPointF* starPoints = star.data();
double x = m_size * 0.5;
double y = m_size * 0.5;
double x1 = x - 3 * dx;
double y1 = y - 2 * dy;
const double x2 = x1 + 1 * dx;
const double x3 = x1 + 2 * dx;
const double x4 = x1 + 3 * dx;
const double x5 = x1 + 4 * dx;
const double x6 = x1 + 5 * dx;
const double x7 = x1 + 6 * dx;
const double y2 = y1 + 1 * dy;
const double y3 = y1 + 2 * dy;
const double y4 = y1 + 3 * dy;
const double y5 = y1 + 4 * dy;
starPoints[0].rx() = x4;
starPoints[0].ry() = y1;
starPoints[1].rx() = x5;
starPoints[1].ry() = y2;
starPoints[2].rx() = x7;
starPoints[2].ry() = y2;
starPoints[3].rx() = x6;
starPoints[3].ry() = y3;
starPoints[4].rx() = x7;
starPoints[4].ry() = y4;
starPoints[5].rx() = x5;
starPoints[5].ry() = y4;
starPoints[6].rx() = x4;
starPoints[6].ry() = y5;
starPoints[7].rx() = x3;
starPoints[7].ry() = y4;
starPoints[8].rx() = x1;
starPoints[8].ry() = y4;
starPoints[9].rx() = x2;
starPoints[9].ry() = y3;
starPoints[10].rx() = x1;
starPoints[10].ry() = y2;
starPoints[11].rx() = x3;
starPoints[11].ry() = y2;
painter.drawPolygon( star );
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawHexagonSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createHexagonImage() const
{
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
QRectF r( 0, 0, m_size, m_size );
const double cos30 = 0.866025; // cos(30°)
const double dx = 0.5 * ( m_size - cos30 );
const double dy = 0.25 * m_size;
QPolygonF hexaPolygon( 6 );
QPointF* hexaPoints = hexaPolygon.data();
double x = m_size * 0.5;
double y = m_size * 0.5;
double x1 = x - dx;
double y1 = y - 2 * dy;
const double x2 = x1 + 1 * dx;
const double x3 = x1 + 2 * dx;
const double y2 = y1 + 1 * dy;
const double y3 = y1 + 3 * dy;
const double y4 = y1 + 4 * dy;
hexaPoints[0].rx() = x2;
hexaPoints[0].ry() = y1;
hexaPoints[1].rx() = x3;
hexaPoints[1].ry() = y2;
hexaPoints[2].rx() = x3;
hexaPoints[2].ry() = y3;
hexaPoints[3].rx() = x2;
hexaPoints[3].ry() = y4;
hexaPoints[4].rx() = x1;
hexaPoints[4].ry() = y3;
hexaPoints[5].rx() = x1;
hexaPoints[5].ry() = y2;
painter.drawPolygon( hexaPolygon );
return image;
}
//--------------------------------------------------------------------------------------------------
/// Adapted from QwtSymbol::qwtDrawDiamondSymbols
//--------------------------------------------------------------------------------------------------
QImage RiuQtChartsPlotCurveSymbol::createDiamondImage() const
{
QImage image( m_size, m_size, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing );
QPen pen( m_pen );
pen.setWidth( 1.0 );
pen.setJoinStyle( Qt::MiterJoin );
painter.setPen( pen );
painter.setBrush( m_color );
QSize size( m_size, m_size );
double x = size.width() * 0.5;
double y = size.height() * 0.5;
const double x1 = x - 0.5 * size.width();
const double y1 = y - 0.5 * size.height();
const double x2 = x1 + size.width();
const double y2 = y1 + size.height();
QPolygonF polygon;
polygon += QPointF( x, y1 );
polygon += QPointF( x2, y );
polygon += QPointF( x, y2 );
polygon += QPointF( x1, y );
painter.drawPolygon( polygon );
return image;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRect RiuQtChartsPlotCurveSymbol::boundingRect() const
{
return QRect( 0, 0, m_size, m_size );
}

View File

@@ -0,0 +1,79 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Equinor ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RiuPlotCurveSymbol.h"
#include <QColor>
#include <QImage>
#include <QPen>
#include <QString>
class QPainter;
class QPointF;
class QRect;
namespace QtCharts
{
class QScatterSeries;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiuQtChartsPlotCurveSymbol : public RiuPlotCurveSymbol
{
public:
RiuQtChartsPlotCurveSymbol( RiuPlotCurveSymbol::PointSymbolEnum riuStyle,
const QString& label = QString(),
LabelPosition labelPosition = RiuPlotCurveSymbol::LabelAboveSymbol,
int labelFontSizePt = 8 );
void renderSymbolLabel( QPainter* painter, const QPointF& position, const QString& label ) const;
void setSize( int width, int height ) override;
void setColor( const QColor& color ) override;
void setPen( const QPen& pen ) override;
void setPixmap( const QPixmap& pixmap ) override;
QRect boundingRect() const override;
void applyToScatterSeries( QtCharts::QScatterSeries* series ) const;
private:
QImage createTriangleImage( RiuPlotCurveSymbol::PointSymbolEnum symbolStyle ) const;
QImage createRectImage() const;
QImage createStar1Image() const;
QImage createStar2Image() const;
QImage createHexagonImage() const;
QImage createEllipseImage() const;
QImage createCrossImage() const;
QImage createXCrossImage() const;
QImage createDiamondImage() const;
void setImageBrush( QtCharts::QScatterSeries* series, const QImage& image ) const;
QColor m_color;
QPen m_pen;
int m_size;
};

View File

@@ -0,0 +1,105 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- 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 "RiuQtChartsPlotTools.h"
#include "RiaPlotDefines.h"
#include "RiuGuiTheme.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiuQtChartsPlotWidget.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotTools::setCommonPlotBehaviour( RiuQtChartsPlotWidget* plot )
{
// Plot background and frame look
QPalette newPalette( plot->palette() );
newPalette.setColor( QPalette::Window, Qt::white );
plot->setPalette( newPalette );
plot->setAutoFillBackground( true );
// Axis number font
int axisFontSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(),
caf::FontTools::RelativeSize::Medium );
// Axis title font
int titleFontSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(),
caf::FontTools::RelativeSize::Medium );
bool titleBold = false;
plot->setAxesFontsAndAlignment( titleFontSize, axisFontSize, titleBold, Qt::AlignRight );
// Store the pointer address as an object name. This way
// each plot can be identified uniquely for CSS-stylesheets
QString objectName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( plot ) );
plot->setObjectName( objectName );
QString canvasName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( plot->getParentForOverlay() ) );
plot->getParentForOverlay()->setObjectName( canvasName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotTools::setDefaultAxes( RiuQtChartsPlotWidget* plot )
{
plot->enableAxis( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, true );
plot->enableAxis( RiaDefines::PlotAxis::PLOT_AXIS_LEFT, true );
plot->enableAxis( RiaDefines::PlotAxis::PLOT_AXIS_TOP, false );
plot->enableAxis( RiaDefines::PlotAxis::PLOT_AXIS_RIGHT, false );
plot->setAxisMaxMinor( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, 2 );
plot->setAxisMaxMinor( RiaDefines::PlotAxis::PLOT_AXIS_LEFT, 3 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQtChartsPlotTools::enableDateBasedBottomXAxis( RiuQtChartsPlotWidget* plot,
const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents,
RiaQDateTimeTools::TimeFormatComponents timeComponents )
{
QString format = dateTimeFormatForInterval( dateFormat, timeFormat, dateComponents, timeComponents );
plot->setAxisFormat( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, format );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuQtChartsPlotTools::dateTimeFormatForInterval( const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents,
RiaQDateTimeTools::TimeFormatComponents timeComponents )
{
if ( dateComponents != RiaQDateTimeTools::DATE_FORMAT_UNSPECIFIED &&
timeComponents != RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED )
{
return RiaQDateTimeTools::timeFormatString( timeFormat, timeComponents ) + "\n" +
RiaQDateTimeTools::dateFormatString( dateFormat, dateComponents );
}
// Default:
return RiaQDateTimeTools::timeFormatString( timeFormat, RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_NONE ) +
"\n" +
RiaQDateTimeTools::dateFormatString( dateFormat,
RiaQDateTimeTools::DateFormatComponents::DATE_FORMAT_YEAR_MONTH_DAY );
}

View File

@@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- 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 "RiaQDateTimeTools.h"
class RiuQtChartsPlotWidget;
class RiuQtChartsPlotTools
{
public:
static void setCommonPlotBehaviour( RiuQtChartsPlotWidget* plot );
static void setDefaultAxes( RiuQtChartsPlotWidget* plot );
static void enableDateBasedBottomXAxis(
RiuQtChartsPlotWidget* plot,
const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents = RiaQDateTimeTools::DATE_FORMAT_UNSPECIFIED,
RiaQDateTimeTools::TimeFormatComponents timeComponents = RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED );
static QString dateTimeFormatForInterval( const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents,
RiaQDateTimeTools::TimeFormatComponents timeComponents );
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,211 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RiaDefines.h"
#include "RiaPlotDefines.h"
#include "RiuPlotWidget.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include <QPointer>
#include <set>
class RiaPlotWindowRedrawScheduler;
class RimPlot;
class RiuPlotCurve;
class QEvent;
class QLabel;
class QPainter;
class QPaintDevice;
class QWheelEvent;
namespace QtCharts
{
class QValueAxis;
class QChart;
class QAbstractSeries;
class QAbstractAxis;
class QChartView;
}; // namespace QtCharts
//==================================================================================================
//
//
//
//==================================================================================================
class RiuQtChartsPlotWidget : public RiuPlotWidget
{
Q_OBJECT
public:
RiuQtChartsPlotWidget( RimPlot* plotDefinition, QWidget* parent = nullptr );
~RiuQtChartsPlotWidget() override;
int axisTitleFontSize( RiaDefines::PlotAxis axis ) const override;
int axisValueFontSize( RiaDefines::PlotAxis axis ) const override;
void setAxisFontsAndAlignment( RiaDefines::PlotAxis,
int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter ) override;
void setAxesFontsAndAlignment( int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter ) override;
void enableAxis( RiaDefines::PlotAxis axis, bool isEnabled ) override;
bool axisEnabled( RiaDefines::PlotAxis axis ) const override;
void setAxisScale( RiaDefines::PlotAxis axis, double min, double max ) override;
void setAxisAutoScale( RiaDefines::PlotAxis axis, bool enable ) override;
void setAxisMaxMinor( RiaDefines::PlotAxis axis, int maxMinor ) override;
void setAxisMaxMajor( RiaDefines::PlotAxis axis, int maxMajor ) override;
RiuPlotWidget::AxisScaleType axisScaleType( RiaDefines::PlotAxis axis ) const override;
void setAxisScaleType( RiaDefines::PlotAxis axis, RiuPlotWidget::AxisScaleType axisScaleType ) override;
void setAxisTitleText( RiaDefines::PlotAxis axis, const QString& title ) override;
void setAxisTitleEnabled( RiaDefines::PlotAxis axis, bool enable ) override;
void setAxisFormat( RiaDefines::PlotAxis axis, const QString& format );
void setPlotTitle( const QString& plotTitle ) override;
const QString& plotTitle() const;
void setPlotTitleEnabled( bool enabled );
bool plotTitleEnabled() const;
void setPlotTitleFontSize( int titleFontSize ) override;
void setLegendFontSize( int fontSize ) override;
void setInternalLegendVisible( bool visible ) override;
void insertLegend( RiuPlotWidget::Legend ) override;
void clearLegend() override;
std::pair<double, double> axisRange( RiaDefines::PlotAxis axis ) const override;
void setAxisRange( RiaDefines::PlotAxis axis, double min, double max ) override;
void setAxisInverted( RiaDefines::PlotAxis axis, bool isInverted ) override;
void setAxisLabelsAndTicksEnabled( RiaDefines::PlotAxis axis, bool enableLabels, bool enableTicks ) override;
void enableGridLines( RiaDefines::PlotAxis axis, bool majorGridLines, bool minorGridLines ) override;
void setMajorAndMinorTickIntervals( RiaDefines::PlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minValue,
double maxValue ) override;
void setMajorAndMinorTickIntervalsAndRange( RiaDefines::PlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minTickValue,
double maxTickValue,
double rangeMin,
double rangeMax ) override;
void setAutoTickIntervalCounts( RiaDefines::PlotAxis axis,
int maxMajorTickIntervalCount,
int maxMinorTickIntervalCount ) override;
double majorTickInterval( RiaDefines::PlotAxis axis ) const override;
double minorTickInterval( RiaDefines::PlotAxis axis ) const override;
void detachItems( RiuPlotWidget::PlotItemType plotItemType ) override;
int axisExtent( RiaDefines::PlotAxis axis ) const override;
QPoint dragStartPosition() const;
void scheduleReplot();
void updateLayout() override;
void renderTo( QPainter* painter, const QRect& targetRect, double scaling ) override;
void renderTo( QPaintDevice* painter, const QRect& targetRect ) override;
int overlayMargins() const;
RimViewWindow* ownerViewWindow() const override;
void updateLegend() override;
void updateAxes() override;
RiuPlotCurve* createPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title, const QColor& color ) override;
QtCharts::QChart* qtChart();
void attach( RiuPlotCurve* plotCurve,
QtCharts::QAbstractSeries* lineseries,
QtCharts::QAbstractSeries* scatterSeries,
RiaDefines::PlotAxis xAxis,
RiaDefines::PlotAxis yAxis );
QtCharts::QAbstractSeries* getLineSeries( const RiuPlotCurve* plotCurve ) const;
QtCharts::QAbstractSeries* getScatterSeries( const RiuPlotCurve* plotCurve ) const;
void setXAxis( RiaDefines::PlotAxis axis, QtCharts::QAbstractSeries* series );
void setYAxis( RiaDefines::PlotAxis axis, QtCharts::QAbstractSeries* series );
const QColor& backgroundColor() const override;
QWidget* getParentForOverlay() const override;
std::pair<RiuPlotCurve*, int> findClosestCurve( const QPoint& pos, double& distanceToClick ) const override;
protected:
void setAxis( RiaDefines::PlotAxis axis, QtCharts::QAbstractSeries* series );
void resizeEvent( QResizeEvent* event ) override;
void keyPressEvent( QKeyEvent* event ) override;
void wheelEvent( QWheelEvent* event ) override;
void applyPlotTitleToPlot();
void applyAxisTitleToPlot( RiaDefines::PlotAxis axis );
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
virtual bool isZoomerActive() const;
virtual void endZoomOperations();
void rescaleAxis( RiaDefines::PlotAxis axis );
QtCharts::QAbstractAxis* plotAxis( RiaDefines::PlotAxis axis ) const;
Qt::Orientation orientation( RiaDefines::PlotAxis axis ) const;
signals:
void plotZoomed();
private slots:
void axisRangeChanged();
private:
static int defaultMinimumWidth();
void replot() override;
QPointer<QtCharts::QChartView> m_viewer;
std::map<RiaDefines::PlotAxis, QtCharts::QAbstractAxis*> m_axes;
std::map<RiaDefines::PlotAxis, bool> m_axesEnabled;
std::map<RiaDefines::PlotAxis, bool> m_axesAutoScale;
std::map<const RiuPlotCurve*, QtCharts::QAbstractSeries*> m_lineSeriesMap;
std::map<const RiuPlotCurve*, QtCharts::QAbstractSeries*> m_scatterSeriesMap;
};

View File

@@ -21,29 +21,29 @@
#include "RiaCurveDataTools.h"
#include "RiaImageTools.h"
#include "RiaTimeTTools.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWidget.h"
#include "RiuQwtSymbol.h"
#include "qwt_date.h"
#include "qwt_interval_symbol.h"
#include "qwt_painter.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_intervalcurve.h"
#include "qwt_point_mapper.h"
#include "qwt_scale_map.h"
#include "qwt_symbol.h"
#include <limits>
//--------------------------------------------------------------------------------------------------
/// Internal constants
//--------------------------------------------------------------------------------------------------
#define DOUBLE_INF std::numeric_limits<double>::infinity()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotCurve::RiuQwtPlotCurve( const QString& title )
: QwtPlotCurve( title )
RiuQwtPlotCurve::RiuQwtPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title )
: RiuPlotCurve( ownerRimCurve, title )
, QwtPlotCurve( title )
, m_showErrorBars( false )
{
this->setLegendAttribute( QwtPlotCurve::LegendShowLine, true );
this->setLegendAttribute( QwtPlotCurve::LegendShowSymbol, true );
@@ -51,9 +51,11 @@ RiuQwtPlotCurve::RiuQwtPlotCurve( const QString& title )
this->setRenderHint( QwtPlotItem::RenderAntialiased, true );
m_symbolSkipPixelDistance = 10.0f;
m_blackAndWhiteLegendIcon = false;
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( RiuQwtPlotCurveDefines::zDepthForIndex( RiuQwtPlotCurveDefines::ZIndex::Z_ERROR_BARS ) );
}
//--------------------------------------------------------------------------------------------------
@@ -61,40 +63,20 @@ RiuQwtPlotCurve::RiuQwtPlotCurve( const QString& title )
//--------------------------------------------------------------------------------------------------
RiuQwtPlotCurve::~RiuQwtPlotCurve()
{
if ( m_qwtCurveErrorBars )
{
m_qwtCurveErrorBars->detach();
delete m_qwtCurveErrorBars;
m_qwtCurveErrorBars = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSamplesFromXValuesAndYValues( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
void RiuQwtPlotCurve::setTitle( const QString& title )
{
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSamplesFromDatesAndYValues( const std::vector<QDateTime>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
{
auto xValues = RiuQwtPlotCurve::fromQDateTime( dateTimes );
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSamplesFromTimeTAndYValues( const std::vector<time_t>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
{
auto xValues = RiuQwtPlotCurve::fromTime_t( dateTimes );
computeValidIntervalsAndSetCurveData( xValues, yValues, keepOnlyPositiveValues );
QwtPlotCurve::setTitle( title );
}
//--------------------------------------------------------------------------------------------------
@@ -235,30 +217,6 @@ void RiuQwtPlotCurve::drawSymbols( QPainter* painter,
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setLineSegmentStartStopIndices( const std::vector<std::pair<size_t, size_t>>& lineSegmentStartStopIndices )
{
m_polyLineStartStopIndices = lineSegmentStartStopIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSymbolSkipPixelDistance( float distance )
{
m_symbolSkipPixelDistance = distance >= 0.0f ? distance : 0.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setPerPointLabels( const std::vector<QString>& labels )
{
m_perPointLabels = labels;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -269,7 +227,7 @@ void RiuQwtPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum
const QBrush& fillBrush /* = QBrush( Qt::NoBrush )*/ )
{
QwtPlotCurve::CurveStyle curveStyle = QwtPlotCurve::NoCurve;
Qt::PenStyle penStyle = Qt::NoPen;
Qt::PenStyle penStyle = RiuQwtPlotCurveDefines::convertToPenStyle( lineStyle );
// Qwt bug workaround (#4135): need to set 0 curve thickness for STYLE_NONE
int curveThickness = 0;
@@ -287,25 +245,6 @@ void RiuQwtPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum
curveStyle = QwtPlotCurve::Lines;
break;
}
switch ( lineStyle )
{
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID:
penStyle = Qt::SolidLine;
break;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DASH:
penStyle = Qt::DashLine;
break;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DOT:
penStyle = Qt::DotLine;
break;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DASH_DOT:
penStyle = Qt::DashDotLine;
break;
default:
break;
}
}
QPen curvePen( curveColor );
curvePen.setWidth( curveThickness );
@@ -319,9 +258,9 @@ void RiuQwtPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setBlackAndWhiteLegendIcon( bool blackAndWhite )
void RiuQwtPlotCurve::setBrush( const QBrush& brush )
{
m_blackAndWhiteLegendIcon = blackAndWhite;
QwtPlotCurve::setBrush( brush );
}
//--------------------------------------------------------------------------------------------------
@@ -344,58 +283,237 @@ QwtGraphic RiuQwtPlotCurve::legendIcon( int index, const QSizeF& size ) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::computeValidIntervalsAndSetCurveData( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues )
QPixmap RiuQwtPlotCurve::legendIcon( const QSizeF& size ) const
{
return legendIcon( 0, size ).toPixmap();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setLegendIconSize( const QSize& iconSize )
{
QwtPlotCurve::setLegendIconSize( iconSize );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQwtPlotCurve::legendIconSize() const
{
return QwtPlotCurve::legendIconSize();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::attachToPlot( RiuPlotWidget* plotWidget )
{
RiuQwtPlotWidget* qwtPlotWidget = dynamic_cast<RiuQwtPlotWidget*>( plotWidget );
attach( qwtPlotWidget->qwtPlot() );
if ( m_showErrorBars )
{
m_qwtCurveErrorBars->attach( qwtPlotWidget->qwtPlot() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::detach()
{
QwtPlotCurve::detach();
m_qwtCurveErrorBars->detach();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::showInPlot()
{
show();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSamplesInPlot( const std::vector<double>& xValues, const std::vector<double>& yValues, int numValues )
{
setSamples( xValues.data(), yValues.data(), numValues );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setZ( int z )
{
QwtPlotCurve::setZ( z );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor )
{
m_showErrorBars = showErrorBars;
if ( m_qwtCurveErrorBars )
{
QwtIntervalSymbol* newSymbol = new QwtIntervalSymbol( QwtIntervalSymbol::Bar );
newSymbol->setPen( QPen( curveColor ) );
m_qwtCurveErrorBars->setSymbol( newSymbol );
m_qwtCurveErrorBars->setVisible( showErrorBars );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::clearErrorBars()
{
m_showErrorBars = false;
m_qwtCurveErrorBars->setSamples( nullptr );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotCurve::numSamples() const
{
return dataSize();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQwtPlotCurve::sample( int index ) const
{
CAF_ASSERT( index >= 0 && index <= numSamples() );
auto p = QwtPlotCurve::sample( index );
return std::make_pair( p.x(), p.y() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQwtPlotCurve::xDataRange() const
{
return std::make_pair( minXValue(), maxXValue() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RiuQwtPlotCurve::yDataRange() const
{
return std::make_pair( minYValue(), maxYValue() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSamplesFromXYErrorValues( const std::vector<double>& xValues,
const std::vector<double>& yValues,
const std::vector<double>& errorValues,
bool keepOnlyPositiveValues,
RiaCurveDataTools::ErrorAxis errorAxis )
{
CVF_ASSERT( xValues.size() == yValues.size() );
CVF_ASSERT( xValues.size() == errorValues.size() );
auto intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues( yValues, keepOnlyPositiveValues );
std::vector<double> filteredYValues;
std::vector<double> filteredXValues;
std::vector<double> validYValues;
std::vector<double> validXValues;
RiaCurveDataTools::getValuesByIntervals( yValues, intervalsOfValidValues, &filteredYValues );
RiaCurveDataTools::getValuesByIntervals( xValues, intervalsOfValidValues, &filteredXValues );
RiaCurveDataTools::getValuesByIntervals( yValues, intervalsOfValidValues, &validYValues );
RiaCurveDataTools::getValuesByIntervals( xValues, intervalsOfValidValues, &validXValues );
std::vector<double> filteredErrorValues;
RiaCurveDataTools::getValuesByIntervals( errorValues, intervalsOfValidValues, &filteredErrorValues );
setSamples( validXValues.data(), validYValues.data(), static_cast<int>( validXValues.size() ) );
QVector<QwtIntervalSample> errorIntervals;
setLineSegmentStartStopIndices( RiaCurveDataTools::computePolyLineStartStopIndices( intervalsOfValidValues ) );
errorIntervals.reserve( static_cast<int>( filteredXValues.size() ) );
for ( size_t i = 0; i < filteredXValues.size(); i++ )
{
if ( !std::isinf( filteredYValues[i] ) && !std::isinf( filteredErrorValues[i] ) )
{
if ( errorAxis == RiaCurveDataTools::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] );
}
}
}
setSamplesInPlot( filteredXValues, filteredYValues, static_cast<int>( filteredXValues.size() ) );
setLineSegmentStartStopIndices( intervalsOfValidValues );
if ( m_qwtCurveErrorBars )
{
m_qwtCurveErrorBars->setSamples( errorIntervals );
if ( errorAxis == RiaCurveDataTools::ErrorAxis::ERROR_ALONG_Y_AXIS )
{
m_qwtCurveErrorBars->setOrientation( Qt::Vertical );
}
else
{
m_qwtCurveErrorBars->setOrientation( Qt::Horizontal );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RiuQwtPlotCurve::fromQDateTime( const std::vector<QDateTime>& dateTimes )
void RiuQwtPlotCurve::setXAxis( RiaDefines::PlotAxis axis )
{
std::vector<double> doubleValues;
if ( !dateTimes.empty() )
{
doubleValues.reserve( dateTimes.size() );
for ( const auto& dt : dateTimes )
{
doubleValues.push_back( QwtDate::toDouble( dt ) );
}
}
return doubleValues;
QwtPlotCurve::setXAxis( RiuQwtPlotTools::toQwtPlotAxis( axis ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RiuQwtPlotCurve::fromTime_t( const std::vector<time_t>& timeSteps )
void RiuQwtPlotCurve::setYAxis( RiaDefines::PlotAxis axis )
{
std::vector<double> doubleValues;
if ( !timeSteps.empty() )
{
doubleValues.reserve( timeSteps.size() );
for ( const auto& time : timeSteps )
{
doubleValues.push_back( RiaTimeTTools::toDouble( time ) );
}
}
return doubleValues;
QwtPlotCurve::setYAxis( RiuQwtPlotTools::toQwtPlotAxis( axis ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setVisibleInLegend( bool isVisibleInLegend )
{
setItemAttribute( QwtPlotItem::Legend, isVisibleInLegend );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotCurve::setSymbol( RiuPlotCurveSymbol* symbol )
{
if ( symbol )
{
auto qwtSymbol = dynamic_cast<RiuQwtSymbol*>( symbol );
CAF_ASSERT( qwtSymbol );
QwtPlotCurve::setSymbol( qwtSymbol );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol* RiuQwtPlotCurve::createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const
{
return new RiuQwtSymbol( symbol );
}

View File

@@ -19,67 +19,66 @@
#pragma once
#include "RiuPlotCurve.h"
#include "RiuQwtPlotCurveDefines.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_intervalcurve.h"
#include "qwt_symbol.h"
class QwtPlotIntervalCurve;
//==================================================================================================
//
// If infinite data is present in the curve data, Qwt is not able to draw a nice curve.
// This class assumes that inf data is removed, and segments to be draw are indicated by start/stop indices into curve
// data.
//
// Single values in the curve are drawn using a CrossX symbol
//
// Here you can see the curve segments visualized. Curve segments are drawn between vector indices.
//
// 0 - 1
// 5 - 7
// 9 -10
//
// * *
// * * *
// Curve * * * ----- X
//
// Values 1.0|2.0|inf|inf|inf|1.0|2.0|1.0|inf|1.0|1.0|inf|1.0|inf
// Vec index 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13
//==================================================================================================
class RiuQwtPlotCurve : public QwtPlotCurve
class RiuQwtPlotCurve : public RiuPlotCurve, public QwtPlotCurve
{
public:
explicit RiuQwtPlotCurve( const QString& title = QString() );
explicit RiuQwtPlotCurve( RimPlotCurve* ownerRimCurve = nullptr, const QString& title = QString() );
~RiuQwtPlotCurve() override;
void setSamplesFromXValuesAndYValues( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
void setSamplesFromDatesAndYValues( const std::vector<QDateTime>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
void setSamplesFromTimeTAndYValues( const std::vector<time_t>& dateTimes,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
void setLineSegmentStartStopIndices( const std::vector<std::pair<size_t, size_t>>& lineSegmentStartStopIndices );
void setSymbolSkipPixelDistance( float distance );
void setPerPointLabels( const std::vector<QString>& labels );
void setTitle( const QString& title ) override;
void setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle,
RiuQwtPlotCurveDefines::CurveInterpolationEnum interpolationType,
int curveThickness,
const QColor& curveColor,
const QBrush& fillBrush = QBrush( Qt::NoBrush ) );
const QBrush& fillBrush = QBrush( Qt::NoBrush ) ) override;
void setBrush( const QBrush& brush ) override;
void setLegendIconSize( const QSize& iconSize ) override;
QSize legendIconSize() const override;
QPixmap legendIcon( const QSizeF& size ) const override;
void setBlackAndWhiteLegendIcon( bool blackAndWhite );
QwtGraphic legendIcon( int index, const QSizeF& size ) const override;
void setVisibleInLegend( bool isVisibleInLegend ) override;
static std::vector<double> fromQDateTime( const std::vector<QDateTime>& dateTimes );
static std::vector<double> fromTime_t( const std::vector<time_t>& timeSteps );
void attachToPlot( RiuPlotWidget* plotWidget ) override;
void detach() override;
void showInPlot() override;
void setZ( int z ) override;
void updateErrorBarsAppearance( bool showErrorBars, const QColor& curveColor ) override;
void clearErrorBars() override;
int numSamples() const override;
std::pair<double, double> sample( int index ) const override;
std::pair<double, double> xDataRange() const override;
std::pair<double, double> yDataRange() const override;
void setSamplesFromXYErrorValues(
const std::vector<double>& xValues,
const std::vector<double>& yValues,
const std::vector<double>& errorValues,
bool keepOnlyPositiveValues,
RiaCurveDataTools::ErrorAxis errorAxis = RiaCurveDataTools::ErrorAxis::ERROR_ALONG_Y_AXIS ) override;
void setXAxis( RiaDefines::PlotAxis axis ) override;
void setYAxis( RiaDefines::PlotAxis axis ) override;
void setSymbol( RiuPlotCurveSymbol* symbol ) override;
RiuPlotCurveSymbol* createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const override;
protected:
void drawCurve( QPainter* p,
@@ -98,16 +97,8 @@ protected:
int from,
int to ) const override;
private:
void computeValidIntervalsAndSetCurveData( const std::vector<double>& xValues,
const std::vector<double>& yValues,
bool keepOnlyPositiveValues );
void setSamplesInPlot( const std::vector<double>&, const std::vector<double>&, int ) override;
private:
float m_symbolSkipPixelDistance;
bool m_blackAndWhiteLegendIcon;
std::vector<QString> m_perPointLabels;
std::vector<std::pair<size_t, size_t>> m_polyLineStartStopIndices;
QwtPlotIntervalCurve* m_qwtCurveErrorBars;
bool m_showErrorBars;
};

View File

@@ -75,3 +75,22 @@ int RiuQwtPlotCurveDefines::zDepthForIndex( ZIndex index )
return 0;
}
Qt::PenStyle RiuQwtPlotCurveDefines::convertToPenStyle( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle )
{
switch ( lineStyle )
{
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_NONE:
return Qt::NoPen;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID:
return Qt::SolidLine;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DASH:
return Qt::DashLine;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DOT:
return Qt::DotLine;
case RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_DASH_DOT:
return Qt::DashDotLine;
default:
return Qt::NoPen;
}
}

View File

@@ -19,6 +19,8 @@
#pragma once
#include <Qt>
namespace RiuQwtPlotCurveDefines
{
enum class CurveInterpolationEnum
@@ -48,4 +50,6 @@ enum class ZIndex
int zDepthForIndex( ZIndex index );
Qt::PenStyle convertToPenStyle( RiuQwtPlotCurveDefines::LineStyleEnum lineStyle );
}; // namespace RiuQwtPlotCurveDefines

View File

@@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- 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 "RiuQwtPlotItem.h"
RiuQwtPlotItem::RiuQwtPlotItem( QwtPlotItem* qwtPlotItem )
: RiuPlotItem()
, m_qwtPlotItem( qwtPlotItem )
{
}
RiuQwtPlotItem::~RiuQwtPlotItem()
{
}
QwtPlotItem* RiuQwtPlotItem::qwtPlotItem() const
{
return m_qwtPlotItem;
};

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Equinor ASA
// Copyright (C) 2022- 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
@@ -15,22 +15,21 @@
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuQwtPlotCurve.h"
#include "RiuPlotItem.h"
#include "cafPdmPointer.h"
class QwtPlotItem;
class RimPlotCurve;
class RiuRimQwtPlotCurve : public RiuQwtPlotCurve
class RiuQwtPlotItem : public RiuPlotItem
{
public:
explicit RiuRimQwtPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title = QString() );
RiuQwtPlotItem( QwtPlotItem* qwtPlotItem );
~RiuQwtPlotItem() override;
RimPlotCurve* ownerRimCurve();
const RimPlotCurve* ownerRimCurve() const;
QwtPlotItem* qwtPlotItem() const;
private:
caf::PdmPointer<RimPlotCurve> m_ownerRimCurve;
QwtPlotItem* m_qwtPlotItem;
};

View File

@@ -230,3 +230,33 @@ QwtPlotShapeItem* RiuQwtPlotTools::createBoxShape( const QString& label,
{
return createBoxShapeT<QwtPlotShapeItem>( label, startX, endX, startY, endY, color, brushStyle );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QwtPlot::Axis RiuQwtPlotTools::toQwtPlotAxis( RiaDefines::PlotAxis axis )
{
if ( axis == RiaDefines::PlotAxis::PLOT_AXIS_LEFT )
return QwtPlot::yLeft;
else if ( axis == RiaDefines::PlotAxis::PLOT_AXIS_RIGHT )
return QwtPlot::yRight;
else if ( axis == RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM )
return QwtPlot::xBottom;
return QwtPlot::xTop;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::PlotAxis RiuQwtPlotTools::fromQwtPlotAxis( QwtPlot::Axis axis )
{
if ( axis == QwtPlot::yLeft )
return RiaDefines::PlotAxis::PLOT_AXIS_LEFT;
else if ( axis == QwtPlot::yRight )
return RiaDefines::PlotAxis::PLOT_AXIS_RIGHT;
else if ( axis == QwtPlot::xBottom )
return RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM;
return RiaDefines::PlotAxis::PLOT_AXIS_TOP;
}

View File

@@ -17,6 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaPlotDefines.h"
#include "RiaQDateTimeTools.h"
#include <qwt_date.h>
#include <qwt_plot.h>
@@ -56,6 +57,9 @@ public:
double endY,
QColor color,
Qt::BrushStyle brushStyle = Qt::SolidPattern );
static QwtPlot::Axis toQwtPlotAxis( RiaDefines::PlotAxis );
static RiaDefines::PlotAxis fromQwtPlotAxis( QwtPlot::Axis );
};
//--------------------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -19,27 +19,31 @@
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "RiaDefines.h"
#include "RiaPlotDefines.h"
#include "RiuPlotWidget.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "qwt_plot.h"
#include <QPointer>
#include <set>
class RiaPlotWindowRedrawScheduler;
class RimPlot;
class RiuDraggableOverlayFrame;
class RimPlotCurve;
class RiuPlotCurve;
class RiuPlotItem;
class QwtPlot;
class QwtLegend;
class QwtPicker;
class QwtPlotCurve;
class QwtPlotGrid;
class QwtPlotItem;
class QwtPlotMarker;
class QwtScaleWidget;
class QEvent;
class QLabel;
@@ -52,7 +56,7 @@ class QWheelEvent;
//
//
//==================================================================================================
class RiuQwtPlotWidget : public QwtPlot, public RiuInterfaceToViewWindow
class RiuQwtPlotWidget : public RiuPlotWidget
{
Q_OBJECT
@@ -60,82 +64,110 @@ public:
RiuQwtPlotWidget( RimPlot* plotDefinition, QWidget* parent = nullptr );
~RiuQwtPlotWidget() override;
RimPlot* plotDefinition();
bool isChecked() const;
int colSpan() const;
int rowSpan() const;
int axisTitleFontSize( QwtPlot::Axis axis ) const;
int axisValueFontSize( QwtPlot::Axis axis ) const;
void setAxisFontsAndAlignment( QwtPlot::Axis,
int axisTitleFontSize( RiaDefines::PlotAxis axis ) const override;
int axisValueFontSize( RiaDefines::PlotAxis axis ) const override;
void setAxisFontsAndAlignment( RiaDefines::PlotAxis,
int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter );
int alignment = (int)Qt::AlignCenter ) override;
void setAxesFontsAndAlignment( int titleFontSize,
int valueFontSize,
bool titleBold = false,
int alignment = (int)Qt::AlignCenter );
int alignment = (int)Qt::AlignCenter ) override;
void setAxisTitleText( QwtPlot::Axis axis, const QString& title );
void setAxisTitleEnabled( QwtPlot::Axis axis, bool enable );
void enableAxis( RiaDefines::PlotAxis axis, bool isEnabled ) override;
bool axisEnabled( RiaDefines::PlotAxis axis ) const override;
void setPlotTitle( const QString& plotTitle );
void setAxisScale( RiaDefines::PlotAxis axis, double min, double max ) override;
void setAxisAutoScale( RiaDefines::PlotAxis axis, bool enable ) override;
void setAxisMaxMinor( RiaDefines::PlotAxis axis, int maxMinor ) override;
void setAxisMaxMajor( RiaDefines::PlotAxis axis, int maxMajor ) override;
RiuPlotWidget::AxisScaleType axisScaleType( RiaDefines::PlotAxis axis ) const override;
void setAxisScaleType( RiaDefines::PlotAxis axis, RiuPlotWidget::AxisScaleType axisScaleType ) override;
void setAxisTitleText( RiaDefines::PlotAxis axis, const QString& title ) override;
void setAxisTitleEnabled( RiaDefines::PlotAxis axis, bool enable ) override;
void setPlotTitle( const QString& plotTitle ) override;
const QString& plotTitle() const;
void setPlotTitleEnabled( bool enabled );
bool plotTitleEnabled() const;
void setPlotTitleFontSize( int titleFontSize );
void setPlotTitleFontSize( int titleFontSize ) override;
void setLegendFontSize( int fontSize );
void setInternalLegendVisible( bool visible );
void setLegendFontSize( int fontSize ) override;
void setInternalLegendVisible( bool visible ) override;
void insertLegend( RiuPlotWidget::Legend ) override;
void clearLegend() override;
QwtInterval axisRange( QwtPlot::Axis axis ) const;
void setAxisRange( QwtPlot::Axis axis, double min, double max );
std::pair<double, double> axisRange( RiaDefines::PlotAxis axis ) const override;
void setAxisRange( RiaDefines::PlotAxis axis, double min, double max ) override;
void setAxisInverted( QwtPlot::Axis axis );
void setAxisLabelsAndTicksEnabled( QwtPlot::Axis axis, bool enableLabels, bool enableTicks );
void setAxisInverted( RiaDefines::PlotAxis axis, bool isInverted ) override;
void setAxisLabelsAndTicksEnabled( RiaDefines::PlotAxis axis, bool enableLabels, bool enableTicks ) override;
void enableGridLines( QwtPlot::Axis axis, bool majorGridLines, bool minorGridLines );
void enableGridLines( RiaDefines::PlotAxis axis, bool majorGridLines, bool minorGridLines ) override;
void setMajorAndMinorTickIntervals( QwtPlot::Axis axis,
double majorTickInterval,
double minorTickInterval,
double minValue,
double maxValue );
void setMajorAndMinorTickIntervalsAndRange( QwtPlot::Axis axis,
double majorTickInterval,
double minorTickInterval,
double minTickValue,
double maxTickValue,
double rangeMin,
double rangeMax );
void setAutoTickIntervalCounts( QwtPlot::Axis axis, int maxMajorTickIntervalCount, int maxMinorTickIntervalCount );
double majorTickInterval( QwtPlot::Axis axis ) const;
double minorTickInterval( QwtPlot::Axis axis ) const;
void setMajorAndMinorTickIntervals( RiaDefines::PlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minValue,
double maxValue ) override;
void setMajorAndMinorTickIntervalsAndRange( RiaDefines::PlotAxis axis,
double majorTickInterval,
double minorTickInterval,
double minTickValue,
double maxTickValue,
double rangeMin,
double rangeMax ) override;
void setAutoTickIntervalCounts( RiaDefines::PlotAxis axis,
int maxMajorTickIntervalCount,
int maxMinorTickIntervalCount ) override;
double majorTickInterval( RiaDefines::PlotAxis axis ) const override;
double minorTickInterval( RiaDefines::PlotAxis axis ) const override;
int axisExtent( QwtPlot::Axis axis ) const;
int axisExtent( RiaDefines::PlotAxis axis ) const override;
bool frameIsInFrontOfThis( const QRect& frameGeometry );
QPoint dragStartPosition() const;
void scheduleReplot();
void addOverlayFrame( RiuDraggableOverlayFrame* overlayWidget );
void removeOverlayFrame( RiuDraggableOverlayFrame* overlayWidget );
void updateLayout() override;
void renderTo( QPainter* painter, const QRect& targetRect, double scaling );
void renderTo( QPaintDevice* painter, const QRect& targetRect );
void renderTo( QPainter* painter, const QRect& targetRect, double scaling ) override;
void renderTo( QPaintDevice* painter, const QRect& targetRect ) override;
int overlayMargins() const;
RimViewWindow* ownerViewWindow() const override;
QwtPlot* qwtPlot() const;
void removeEventFilter() override;
void updateLegend() override;
void updateAxes() override;
RiuPlotCurve* createPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title, const QColor& color ) override;
void detachItems( RiuPlotWidget::PlotItemType plotItemType ) override;
void findClosestPlotItem( const QPoint& pos,
QwtPlotItem** closestItem,
int* closestCurvePoint,
double* distanceFromClick ) const;
const QColor& backgroundColor() const override;
QWidget* getParentForOverlay() const override;
std::pair<RiuPlotCurve*, int> findClosestCurve( const QPoint& pos, double& distanceToClick ) const override;
signals:
void plotSelected( bool toggleSelection );
void axisSelected( int axisId, bool toggleSelection );
void plotItemSelected( QwtPlotItem* plotItem, bool toggleSelection, int sampleIndex );
void plotItemSelected( std::shared_ptr<RiuPlotItem> plotItem, bool toggleSelection, int sampleIndex );
void onKeyPressEvent( QKeyEvent* event );
void onWheelEvent( QWheelEvent* event );
void plotZoomed();
@@ -148,7 +180,7 @@ protected:
void keyPressEvent( QKeyEvent* event ) override;
void applyPlotTitleToQwt();
void applyAxisTitleToQwt( QwtPlot::Axis axis );
void applyAxisTitleToQwt( RiaDefines::PlotAxis axis );
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
@@ -156,11 +188,6 @@ protected:
virtual bool isZoomerActive() const;
virtual void endZoomOperations();
void findClosestPlotItem( const QPoint& pos,
QwtPlotItem** closestItem,
int* closestCurvePoint,
double* distanceFromClick ) const;
private:
void selectClosestPlotItem( const QPoint& pos, bool toggleItemInSelection = false );
static int defaultMinimumWidth();
@@ -169,21 +196,9 @@ private:
void highlightPlotItem( const QwtPlotItem* closestItem );
void resetPlotItemHighlighting();
void onAxisSelected( QwtScaleWidget* scale, bool toggleItemInSelection );
void recalculateAxisExtents( QwtPlot::Axis axis );
void updateOverlayFrameLayout();
void recalculateAxisExtents( RiaDefines::PlotAxis axis );
private:
caf::PdmPointer<RimPlot> m_plotDefinition;
QPoint m_clickPosition;
std::map<QwtPlot::Axis, QString> m_axisTitles;
std::map<QwtPlot::Axis, bool> m_axisTitlesEnabled;
const int m_overlayMargins;
QString m_plotTitle;
bool m_plotTitleEnabled;
QList<QPointer<RiuDraggableOverlayFrame>> m_overlayFrames;
struct CurveColors
{
QColor lineColor;
@@ -194,5 +209,5 @@ private:
std::map<QwtPlotCurve*, CurveColors> m_originalCurveColors;
std::map<QwtPlotCurve*, double> m_originalZValues;
friend class RiaPlotWindowRedrawScheduler;
QPointer<QwtPlot> m_plot;
};

View File

@@ -22,7 +22,9 @@
#include "RiaColorTools.h"
#include "RiaFontCache.h"
#include "RiuPlotCurveSymbol.h"
#include "cvfAssert.h"
#include "qwt_symbol.h"
#include <QPainter>
#include <QPainterPath>
@@ -31,10 +33,8 @@
/// Internal class to support labels on symbols
//--------------------------------------------------------------------------------------------------
RiuQwtSymbol::RiuQwtSymbol( PointSymbolEnum riuStyle, const QString& label, LabelPosition labelPosition, int labelFontSizePt )
: QwtSymbol( QwtSymbol::NoSymbol )
, m_globalLabel( label )
, m_labelPosition( labelPosition )
, m_labelFontSizePx( caf::FontTools::pointSizeToPixelSize( labelFontSizePt ) )
: RiuPlotCurveSymbol( riuStyle, label, labelPosition, labelFontSizePt )
, QwtSymbol( QwtSymbol::NoSymbol )
{
QwtSymbol::Style style = QwtSymbol::NoSymbol;
@@ -132,6 +132,30 @@ RiuQwtSymbol::RiuQwtSymbol( PointSymbolEnum riuStyle, const QString& label, Labe
setStyle( style );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtSymbol::setSize( int width, int height )
{
QwtSymbol::setSize( width, height );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtSymbol::setColor( const QColor& color )
{
QwtSymbol::setColor( color );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtSymbol::setPen( const QPen& pen )
{
QwtSymbol::setPen( pen );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -170,104 +194,15 @@ void RiuQwtSymbol::renderSymbolLabel( QPainter* painter, const QPointF& position
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuQwtSymbol::globalLabel() const
void RiuQwtSymbol::setPixmap( const QPixmap& pixmap )
{
return m_globalLabel;
QwtSymbol::setPixmap( pixmap );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtSymbol::setGlobalLabel( const QString& label )
QRect RiuQwtSymbol::boundingRect() const
{
m_globalLabel = label;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtSymbol::setLabelPosition( LabelPosition labelPosition )
{
m_labelPosition = labelPosition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtSymbol::PointSymbolEnum RiuQwtSymbol::cycledSymbolStyle( int indexLevel1, int indexLevel2 )
{
std::vector<std::vector<PointSymbolEnum>> categorisedStyles = {
{ SYMBOL_ELLIPSE, SYMBOL_RECT, SYMBOL_DIAMOND },
{ SYMBOL_DOWN_TRIANGLE, SYMBOL_UP_TRIANGLE },
{ SYMBOL_LEFT_TRIANGLE, SYMBOL_RIGHT_TRIANGLE },
{ SYMBOL_CROSS, SYMBOL_XCROSS },
{ SYMBOL_STAR1, SYMBOL_STAR2 },
};
int level1Category = indexLevel1 % int( categorisedStyles.size() );
int level2Category = indexLevel2 % int( categorisedStyles[level1Category].size() );
return categorisedStyles[level1Category][level2Category];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtSymbol::PointSymbolEnum RiuQwtSymbol::cycledSymbolStyle( int indexLevel )
{
std::vector<PointSymbolEnum> contrastingSymbols = { SYMBOL_ELLIPSE,
SYMBOL_CROSS,
SYMBOL_RECT,
SYMBOL_DOWN_TRIANGLE,
SYMBOL_UP_TRIANGLE,
SYMBOL_LEFT_TRIANGLE,
SYMBOL_RIGHT_TRIANGLE,
SYMBOL_STAR2,
SYMBOL_DIAMOND,
SYMBOL_STAR1 };
return contrastingSymbols[indexLevel % (int)contrastingSymbols.size()];
}
//--------------------------------------------------------------------------------------------------
/// Is this a symbol with an interior and a border? If false, it is just lines.
//--------------------------------------------------------------------------------------------------
bool RiuQwtSymbol::isFilledSymbol( PointSymbolEnum symbol )
{
return symbol != SYMBOL_NONE && symbol != SYMBOL_CROSS && symbol != SYMBOL_XCROSS && symbol != SYMBOL_STAR1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRect RiuQwtSymbol::labelBoundingRect( const QPainter* painter, const QRect& symbolRect, const QString& label ) const
{
CVF_ASSERT( painter );
QPoint symbolPosition = symbolRect.topLeft();
int symbolWidth = symbolRect.width();
int symbolHeight = symbolRect.height();
int labelWidth = painter->fontMetrics().width( label );
int labelHeight = painter->fontMetrics().height();
QPoint labelPosition;
if ( m_labelPosition == LabelAboveSymbol )
{
labelPosition = QPoint( symbolPosition.x() - labelWidth / 2, symbolPosition.y() - 5 );
}
else if ( m_labelPosition == LabelBelowSymbol )
{
labelPosition = QPoint( symbolPosition.x() - labelWidth / 2, symbolPosition.y() + symbolHeight + 5 );
}
else if ( m_labelPosition == LabelLeftOfSymbol )
{
labelPosition = QPoint( symbolPosition.x() - labelWidth - symbolWidth, symbolPosition.y() );
}
else if ( m_labelPosition == LabelRightOfSymbol )
{
labelPosition = QPoint( symbolPosition.x() + symbolWidth + 3, symbolPosition.y() );
}
return QRect( labelPosition.x(), labelPosition.y(), labelWidth, labelHeight );
return QwtSymbol::boundingRect();
}

View File

@@ -18,70 +18,39 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuPlotCurveSymbol.h"
#include "qwt_symbol.h"
#include <QString>
class QPainter;
class QPointF;
class QRect;
//--------------------------------------------------------------------------------------------------
/// This class overrides renderSymbols to draw symbols and labels.
/// The label is only visible in the legend, while it is clipped in the plot.
/// Therefore the method RiuQwtPlotCurve::drawSymbols also draw labels to have labels
/// in the plot as well.
//--------------------------------------------------------------------------------------------------
class RiuQwtSymbol : public QwtSymbol
class RiuQwtSymbol : public RiuPlotCurveSymbol, public QwtSymbol
{
public:
enum LabelPosition
{
LabelAboveSymbol,
LabelBelowSymbol,
LabelLeftOfSymbol,
LabelRightOfSymbol
};
enum PointSymbolEnum
{
SYMBOL_NONE,
SYMBOL_ELLIPSE,
SYMBOL_RECT,
SYMBOL_DIAMOND,
SYMBOL_TRIANGLE,
SYMBOL_DOWN_TRIANGLE,
SYMBOL_CROSS,
SYMBOL_XCROSS,
SYMBOL_LEFT_ALIGNED_TRIANGLE, // Aligned so pin point is at lower right corner
SYMBOL_RIGHT_ALIGNED_TRIANGLE, // Aligned so pin point is at lower left corner
SYMBOL_LEFT_ANGLED_TRIANGLE,
SYMBOL_RIGHT_ANGLED_TRIANGLE,
SYMBOL_UP_TRIANGLE,
SYMBOL_STAR1,
SYMBOL_STAR2,
SYMBOL_HEXAGON,
SYMBOL_LEFT_TRIANGLE,
SYMBOL_RIGHT_TRIANGLE
};
RiuQwtSymbol( RiuPlotCurveSymbol::PointSymbolEnum riuStyle,
const QString& label = QString(),
LabelPosition labelPosition = RiuPlotCurveSymbol::LabelAboveSymbol,
int labelFontSizePt = 8 );
void renderSymbols( QPainter* painter, const QPointF* points, int numPoints ) const override;
void renderSymbolLabel( QPainter* painter, const QPointF& position, const QString& label ) const;
RiuQwtSymbol( PointSymbolEnum riuStyle,
const QString& label,
LabelPosition labelPosition = LabelAboveSymbol,
int labelFontSizePt = 8 );
void renderSymbols( QPainter* painter, const QPointF* points, int numPoints ) const override;
void renderSymbolLabel( QPainter* painter, const QPointF& position, const QString& label ) const;
QString globalLabel() const;
void setSize( int width, int height ) override;
void setGlobalLabel( const QString& label );
void setColor( const QColor& color ) override;
void setLabelPosition( LabelPosition labelPosition );
void setPen( const QPen& pen ) override;
static PointSymbolEnum cycledSymbolStyle( int indexLevel1, int indexLevel2 );
static PointSymbolEnum cycledSymbolStyle( int indexLevel );
void setPixmap( const QPixmap& pixmap ) override;
static bool isFilledSymbol( PointSymbolEnum symbol );
private:
QRect labelBoundingRect( const QPainter* painter, const QRect& symbolRect, const QString& label ) const;
private:
QString m_globalLabel;
int m_labelFontSizePx;
LabelPosition m_labelPosition;
QRect boundingRect() const override;
};

View File

@@ -18,16 +18,18 @@
#include "RiuRelativePermeabilityPlotPanel.h"
#include "RiaCurveDataTools.h"
#include "RiaEclipseUnitTools.h"
#include "RiaResultNames.h"
#include "RigFlowDiagSolverInterface.h"
#include "RiaCurveDataTools.h"
#include "RiaEclipseUnitTools.h"
#include "RiaPlotDefines.h"
#include "RiaResultNames.h"
#include "RiuDockedQwtPlot.h"
#include "RiuGuiTheme.h"
#include "RiuPlotCurveSymbol.h"
#include "RiuQwtPlotCurve.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtSymbol.h"
#include "RiuRelativePermeabilityPlotUpdater.h"
#include "RiuTextDialog.h"
@@ -39,7 +41,6 @@
#include "qwt_plot_curve.h"
#include "qwt_plot_marker.h"
#include "qwt_scale_engine.h"
#include "qwt_symbol.h"
#include <QButtonGroup>
#include <QCheckBox>
@@ -363,11 +364,9 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS
plotOnWhichYAxis = RIGHT_YAXIS;
}
// QwtPlotCurve* qwtCurve = new QwtPlotCurve(curve.name.c_str());
RiuQwtPlotCurve* qwtCurve = new RiuQwtPlotCurve( curve.name.c_str() );
RiuQwtPlotCurve* qwtCurve = new RiuQwtPlotCurve( nullptr, curve.name.c_str() );
CVF_ASSERT( curve.saturationVals.size() == curve.yVals.size() );
// qwtCurve->setSamples(curve.xVals.data(), curve.yVals.data(), static_cast<int>(curve.xVals.size()));
const bool includePositiveValuesOnly = ( logScaleLeftAxis && plotOnWhichYAxis == LEFT_YAXIS );
qwtCurve->setSamplesFromXValuesAndYValues( curve.saturationVals, curve.yVals, includePositiveValuesOnly );
@@ -403,7 +402,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS
const QPen curvePen( QBrush(), 1, penStyle );
qwtCurve->setPen( curvePen );
QwtSymbol* curveSymbol = new QwtSymbol( QwtSymbol::Ellipse );
RiuQwtSymbol* curveSymbol = new RiuQwtSymbol( RiuPlotCurveSymbol::SYMBOL_ELLIPSE );
curveSymbol->setSize( 6, 6 );
curveSymbol->setBrush( Qt::NoBrush );
qwtCurve->setSymbol( curveSymbol );
@@ -416,7 +415,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS
if ( plotOnWhichYAxis == RIGHT_YAXIS )
{
qwtCurve->setYAxis( QwtPlot::yRight );
qwtCurve->setYAxis( RiaDefines::PlotAxis::PLOT_AXIS_RIGHT );
shouldEnableRightYAxis = true;
}

View File

@@ -78,7 +78,7 @@ void RiuResultQwtPlot::addCurve( const RimCase* rimCase,
return;
}
RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve( "Curve 1" );
RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve( nullptr, "Curve 1" );
plotCurve->setSamplesFromDatesAndYValues( dateTimes, timeHistoryValues, false );
plotCurve->setTitle( curveName );

View File

@@ -21,8 +21,6 @@
#include "RiuDockedQwtPlot.h"
#include "qwt_plot.h"
#include <QString>
#include <map>
#include <vector>

View File

@@ -1,45 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "RiuRimQwtPlotCurve.h"
#include "RimPlotCurve.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuRimQwtPlotCurve::RiuRimQwtPlotCurve( RimPlotCurve* ownerRimCurve, const QString& title /*= QString()*/ )
: RiuQwtPlotCurve( title )
, m_ownerRimCurve( ownerRimCurve )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotCurve* RiuRimQwtPlotCurve::ownerRimCurve()
{
return m_ownerRimCurve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimPlotCurve* RiuRimQwtPlotCurve::ownerRimCurve() const
{
return m_ownerRimCurve;
}

View File

@@ -0,0 +1,198 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- 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 "RiuSummaryPlot.h"
#include "Commands/CorrelationPlotCommands/RicNewCorrelationPlotFeature.h"
#include "RimEnsembleCurveSet.h"
#include "RimPlot.h"
#include "RimSummaryCurve.h"
#include "RimSummaryPlot.h"
#include "RiuPlotCurve.h"
#include "RiuPlotWidget.h"
#include "cafCmdFeatureMenuBuilder.h"
#include <QMenu>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryPlot::RiuSummaryPlot( RimSummaryPlot* plot, QWidget* parent )
: QWidget( parent )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryPlot::~RiuSummaryPlot()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryPlot::showContextMenu( QPoint pos )
{
QMenu menu;
caf::CmdFeatureMenuBuilder menuBuilder;
menuBuilder << "RicShowPlotDataFeature";
menuBuilder << "RicSavePlotTemplateFeature";
double distanceFromClick = std::numeric_limits<double>::infinity();
auto [plotCurve, closestCurvePoint] = plotWidget()->findClosestCurve( pos, distanceFromClick );
if ( plotCurve && closestCurvePoint >= 0 )
{
RimSummaryCurve* summaryCurve = dynamic_cast<RimSummaryCurve*>( plotCurve->ownerRimCurve() );
if ( summaryCurve && closestCurvePoint < (int)summaryCurve->timeStepsY().size() )
{
std::time_t timeStep = summaryCurve->timeStepsY()[closestCurvePoint];
RimSummaryCaseCollection* ensemble = nullptr;
QString clickedQuantityName;
QStringList allQuantityNamesInPlot;
RimEnsembleCurveSet* clickedEnsembleCurveSet = nullptr;
summaryCurve->firstAncestorOrThisOfType( clickedEnsembleCurveSet );
bool curveClicked = distanceFromClick < 50;
if ( clickedEnsembleCurveSet )
{
ensemble = clickedEnsembleCurveSet->summaryCaseCollection();
if ( ensemble && ensemble->isEnsemble() )
{
clickedQuantityName = QString::fromStdString( clickedEnsembleCurveSet->summaryAddress().uiText() );
}
}
{
auto summaryCase = summaryCurve->summaryCaseY();
if ( summaryCase )
{
int summaryCaseId = summaryCase->caseId();
QVariant summaryCaseIdVariant( summaryCaseId );
auto modelName = summaryCase->nativeCaseName();
menuBuilder.addCmdFeatureWithUserData( "RicImportGridModelFromSummaryCurveFeature",
QString( "Open Grid Model '%1'" ).arg( modelName ),
summaryCaseIdVariant );
}
}
if ( !curveClicked )
{
RimSummaryPlot* summaryPlot = static_cast<RimSummaryPlot*>( plotWidget()->plotDefinition() );
std::vector<RimEnsembleCurveSet*> allCurveSetsInPlot;
summaryPlot->descendantsOfType( allCurveSetsInPlot );
for ( auto curveSet : allCurveSetsInPlot )
{
allQuantityNamesInPlot.push_back( QString::fromStdString( curveSet->summaryAddress().uiText() ) );
}
}
else
{
allQuantityNamesInPlot.push_back( clickedQuantityName );
}
if ( !clickedQuantityName.isEmpty() || !allQuantityNamesInPlot.isEmpty() )
{
if ( ensemble && ensemble->isEnsemble() )
{
EnsemblePlotParams params( ensemble, allQuantityNamesInPlot, clickedQuantityName, timeStep );
QVariant variant = QVariant::fromValue( params );
menuBuilder.addCmdFeatureWithUserData( "RicNewAnalysisPlotFeature", "New Analysis Plot", variant );
QString subMenuName = "Create Correlation Plot";
if ( curveClicked )
{
subMenuName = "Create Correlation Plot From Curve Point";
}
menuBuilder.subMenuStart( subMenuName, *caf::IconProvider( ":/CorrelationPlots16x16.png" ).icon() );
{
if ( curveClicked )
{
menuBuilder.addCmdFeatureWithUserData( "RicNewCorrelationPlotFeature",
"New Tornado Plot",
variant );
}
menuBuilder.addCmdFeatureWithUserData( "RicNewCorrelationMatrixPlotFeature",
"New Matrix Plot",
variant );
menuBuilder.addCmdFeatureWithUserData( "RicNewCorrelationReportPlotFeature",
"New Report Plot",
variant );
if ( curveClicked )
{
menuBuilder.subMenuStart( "Cross Plots",
*caf::IconProvider( ":/CorrelationCrossPlot16x16.png" ).icon() );
std::vector<std::pair<RigEnsembleParameter, double>> ensembleParameters =
ensemble->parameterCorrelations( clickedEnsembleCurveSet->summaryAddress(), timeStep );
std::sort( ensembleParameters.begin(),
ensembleParameters.end(),
[]( const std::pair<RigEnsembleParameter, double>& lhs,
const std::pair<RigEnsembleParameter, double>& rhs ) {
return std::fabs( lhs.second ) > std::fabs( rhs.second );
} );
for ( const auto& param : ensembleParameters )
{
if ( std::fabs( param.second ) >= 1.0e-6 )
{
params.ensembleParameter = param.first.name;
variant = QVariant::fromValue( params );
menuBuilder.addCmdFeatureWithUserData( "RicNewParameterResultCrossPlotFeature",
QString( "New Cross Plot Against %1 "
"(Correlation: %2)" )
.arg( param.first.name )
.arg( param.second, 5, 'f', 2 ),
variant );
}
}
menuBuilder.subMenuEnd();
}
}
menuBuilder.subMenuEnd();
}
}
}
}
menuBuilder.appendToMenu( &menu );
if ( menu.actions().size() > 0 )
{
menu.exec( mapToGlobal( pos ) );
// Parts of progress dialog GUI can be present after menu has closed related to
// RicImportGridModelFromSummaryCurveFeature. Make sure the plot is updated, and call processEvents() to make
// sure all GUI events are processed
plotWidget()->update();
QApplication::processEvents();
}
}

View File

@@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- 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 "RiaQDateTimeTools.h"
#include "RiuInterfaceToViewWindow.h"
#include <QWidget>
class RimSummaryPlot;
class RimPlotAxisPropertiesInterface;
class RiuPlotWidget;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuSummaryPlot : public QWidget
{
Q_OBJECT
public:
RiuSummaryPlot( RimSummaryPlot* plot, QWidget* parent );
~RiuSummaryPlot() override;
virtual void useDateBasedTimeAxis(
const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents = RiaQDateTimeTools::DATE_FORMAT_UNSPECIFIED,
RiaQDateTimeTools::TimeFormatComponents timeComponents =
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED ) = 0;
virtual void useTimeBasedTimeAxis() = 0;
virtual void updateAnnotationObjects( RimPlotAxisPropertiesInterface* axisProperties ) = 0;
virtual RiuPlotWidget* plotWidget() const = 0;
public slots:
void showContextMenu( QPoint );
};

View File

@@ -0,0 +1,98 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- 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 "RiuSummaryQtChartsPlot.h"
#include "RiaPreferences.h"
#include "RimSummaryPlot.h"
#include "RiuPlotCurve.h"
#include "RiuPlotWidget.h"
#include "RiuQtChartsPlotTools.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryQtChartsPlot::RiuSummaryQtChartsPlot( RimSummaryPlot* plot, QWidget* parent /*= nullptr*/ )
: RiuSummaryPlot( plot, parent )
{
m_plotWidget = new RiuQtChartsPlotWidget( plot );
m_plotWidget->setContextMenuPolicy( Qt::CustomContextMenu );
connect( m_plotWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( showContextMenu( QPoint ) ) );
setDefaults();
RiuQtChartsPlotTools::setCommonPlotBehaviour( m_plotWidget );
RiuQtChartsPlotTools::setDefaultAxes( m_plotWidget );
m_plotWidget->setInternalLegendVisible( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryQtChartsPlot::~RiuSummaryQtChartsPlot()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQtChartsPlot::useDateBasedTimeAxis( const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents,
RiaQDateTimeTools::TimeFormatComponents timeComponents )
{
m_plotWidget->setAxisScaleType( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, RiuPlotWidget::AxisScaleType::DATE );
RiuQtChartsPlotTools::enableDateBasedBottomXAxis( m_plotWidget, dateFormat, timeFormat, dateComponents, timeComponents );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQtChartsPlot::useTimeBasedTimeAxis()
{
m_plotWidget->setAxisScaleType( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, RiuPlotWidget::AxisScaleType::DATE );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQtChartsPlot::updateAnnotationObjects( RimPlotAxisPropertiesInterface* axisProperties )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQtChartsPlot::setDefaults()
{
QString dateFormat = RiaPreferences::current()->dateFormat();
QString timeFormat = RiaPreferences::current()->timeFormat();
useDateBasedTimeAxis( dateFormat, timeFormat );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotWidget* RiuSummaryQtChartsPlot::plotWidget() const
{
return m_plotWidget;
}

View File

@@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- 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 "RiaQDateTimeTools.h"
#include "RiuQtChartsPlotWidget.h"
#include "RiuSummaryPlot.h"
#include <QPointer>
class RimSummaryPlot;
class RimPlotAxisPropertiesInterface;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuSummaryQtChartsPlot : public RiuSummaryPlot
{
Q_OBJECT;
public:
RiuSummaryQtChartsPlot( RimSummaryPlot* plot, QWidget* parent = nullptr );
~RiuSummaryQtChartsPlot() override;
void useDateBasedTimeAxis( const QString& dateFormat,
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents = RiaQDateTimeTools::DATE_FORMAT_UNSPECIFIED,
RiaQDateTimeTools::TimeFormatComponents timeComponents =
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED ) override;
void useTimeBasedTimeAxis() override;
void updateAnnotationObjects( RimPlotAxisPropertiesInterface* axisProperties ) override;
RiuPlotWidget* plotWidget() const override;
protected:
void setDefaults();
private:
QPointer<RiuQtChartsPlotWidget> m_plotWidget;
};

View File

@@ -23,26 +23,18 @@
#include "Commands/CorrelationPlotCommands/RicNewCorrelationPlotFeature.h"
#include "RimEnsembleCurveSet.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimEnsembleStatisticsCase.h"
#include "RimMainPlotCollection.h"
#include "RimPlot.h"
#include "RimPlotAxisAnnotation.h"
#include "RimPlotAxisProperties.h"
#include "RimPlotAxisPropertiesInterface.h"
#include "RimRegularLegendConfig.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCurveCollection.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RiuPlotAnnotationTool.h"
#include "RiuPlotCurve.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuRimQwtPlotCurve.h"
#include "RiuQwtPlotWidget.h"
#include "RiuWidgetDragger.h"
#include "RiuPlotMainWindowTools.h"
@@ -51,8 +43,6 @@
#include "RiuQwtPlotZoomer.h"
#include "RiuQwtScalePicker.h"
#include "RimProject.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafIconProvider.h"
#include "cafSelectionManager.h"
@@ -88,8 +78,8 @@ public:
//--------------------------------------------------------------------------------------------------
QString curveInfoText( QwtPlotCurve* curve ) override
{
RiuRimQwtPlotCurve* riuCurve = dynamic_cast<RiuRimQwtPlotCurve*>( curve );
RimSummaryCurve* sumCurve = nullptr;
RiuPlotCurve* riuCurve = dynamic_cast<RiuPlotCurve*>( curve );
RimSummaryCurve* sumCurve = nullptr;
if ( riuCurve )
{
sumCurve = dynamic_cast<RimSummaryCurve*>( riuCurve->ownerRimCurve() );
@@ -104,24 +94,28 @@ static EnsembleCurveInfoTextProvider ensembleCurveInfoTextProvider;
///
//--------------------------------------------------------------------------------------------------
RiuSummaryQwtPlot::RiuSummaryQwtPlot( RimSummaryPlot* plot, QWidget* parent /*= nullptr*/ )
: RiuQwtPlotWidget( plot, parent )
: RiuSummaryPlot( plot, parent )
{
m_plotWidget = new RiuQwtPlotWidget( plot, parent );
m_plotWidget->setContextMenuPolicy( Qt::CustomContextMenu );
connect( m_plotWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( showContextMenu( QPoint ) ) );
// LeftButton for the zooming
m_zoomerLeft = new RiuQwtPlotZoomer( canvas() );
m_zoomerLeft = new RiuQwtPlotZoomer( m_plotWidget->qwtPlot()->canvas() );
m_zoomerLeft->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerLeft->initMousePattern( 1 );
// Attach a zoomer for the right axis
m_zoomerRight = new RiuQwtPlotZoomer( canvas() );
m_zoomerRight->setAxis( xTop, yRight );
m_zoomerRight = new RiuQwtPlotZoomer( m_plotWidget->qwtPlot()->canvas() );
m_zoomerRight->setAxis( QwtPlot::xTop, QwtPlot::yRight );
m_zoomerRight->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerRight->initMousePattern( 1 );
// MidButton for the panning
QwtPlotPanner* panner = new QwtPlotPanner( canvas() );
QwtPlotPanner* panner = new QwtPlotPanner( m_plotWidget->qwtPlot()->canvas() );
panner->setMouseButton( Qt::MidButton );
m_wheelZoomer = new RiuQwtPlotWheelZoomer( this );
m_wheelZoomer = new RiuQwtPlotWheelZoomer( m_plotWidget->qwtPlot() );
connect( m_wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) );
connect( m_zoomerLeft, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
@@ -129,12 +123,12 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot( RimSummaryPlot* plot, QWidget* parent /*=
connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) );
setDefaults();
new RiuQwtCurvePointTracker( this, true, &ensembleCurveInfoTextProvider );
new RiuQwtCurvePointTracker( m_plotWidget->qwtPlot(), true, &ensembleCurveInfoTextProvider );
RiuQwtPlotTools::setCommonPlotBehaviour( this );
RiuQwtPlotTools::setDefaultAxes( this );
RiuQwtPlotTools::setCommonPlotBehaviour( m_plotWidget->qwtPlot() );
RiuQwtPlotTools::setDefaultAxes( m_plotWidget->qwtPlot() );
setInternalLegendVisible( true );
m_plotWidget->setInternalLegendVisible( true );
m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>( new RiuPlotAnnotationTool() );
}
@@ -154,7 +148,7 @@ void RiuSummaryQwtPlot::useDateBasedTimeAxis( const QString&
RiaQDateTimeTools::DateFormatComponents dateComponents,
RiaQDateTimeTools::TimeFormatComponents timeComponents )
{
RiuQwtPlotTools::enableDateBasedBottomXAxis( this, dateFormat, timeFormat, dateComponents, timeComponents );
RiuQwtPlotTools::enableDateBasedBottomXAxis( m_plotWidget->qwtPlot(), dateFormat, timeFormat, dateComponents, timeComponents );
}
//--------------------------------------------------------------------------------------------------
@@ -162,16 +156,8 @@ void RiuSummaryQwtPlot::useDateBasedTimeAxis( const QString&
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::useTimeBasedTimeAxis()
{
setAxisScaleEngine( QwtPlot::xBottom, new QwtLinearScaleEngine() );
setAxisScaleDraw( QwtPlot::xBottom, new QwtScaleDraw() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic )
{
if ( m_wheelZoomer ) m_wheelZoomer->setAxisIsLogarithmic( axis, logarithmic );
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xBottom, new QwtLinearScaleEngine() );
m_plotWidget->qwtPlot()->setAxisScaleDraw( QwtPlot::xBottom, new QwtScaleDraw() );
}
//--------------------------------------------------------------------------------------------------
@@ -190,7 +176,7 @@ void RiuSummaryQwtPlot::updateAnnotationObjects( RimPlotAxisPropertiesInterface*
{
if ( annotation->annotationType() == RimPlotAxisAnnotation::AnnotationType::LINE )
{
m_annotationTool->attachAnnotationLine( this,
m_annotationTool->attachAnnotationLine( m_plotWidget->qwtPlot(),
annotation->color(),
annotation->name(),
annotation->value(),
@@ -198,7 +184,7 @@ void RiuSummaryQwtPlot::updateAnnotationObjects( RimPlotAxisPropertiesInterface*
}
else if ( annotation->annotationType() == RimPlotAxisAnnotation::AnnotationType::RANGE )
{
m_annotationTool->attachAnnotationRange( this,
m_annotationTool->attachAnnotationRange( m_plotWidget->qwtPlot(),
annotation->color(),
annotation->name(),
annotation->rangeStart(),
@@ -208,163 +194,6 @@ void RiuSummaryQwtPlot::updateAnnotationObjects( RimPlotAxisPropertiesInterface*
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::contextMenuEvent( QContextMenuEvent* event )
{
QMenu menu;
caf::CmdFeatureMenuBuilder menuBuilder;
emit plotSelected( false );
menuBuilder << "RicShowPlotDataFeature";
menuBuilder << "RicSavePlotTemplateFeature";
QwtPlotItem* closestItem = nullptr;
double distanceFromClick = std::numeric_limits<double>::infinity();
int closestCurvePoint = -1;
QPoint globalPos = event->globalPos();
QPoint localPos = this->canvas()->mapFromGlobal( globalPos );
findClosestPlotItem( localPos, &closestItem, &closestCurvePoint, &distanceFromClick );
if ( closestItem && closestCurvePoint >= 0 )
{
RiuRimQwtPlotCurve* plotCurve = dynamic_cast<RiuRimQwtPlotCurve*>( closestItem );
if ( plotCurve )
{
RimSummaryCurve* summaryCurve = dynamic_cast<RimSummaryCurve*>( plotCurve->ownerRimCurve() );
if ( summaryCurve && closestCurvePoint < (int)summaryCurve->timeStepsY().size() )
{
std::time_t timeStep = summaryCurve->timeStepsY()[closestCurvePoint];
RimSummaryCaseCollection* ensemble = nullptr;
QString clickedQuantityName;
QStringList allQuantityNamesInPlot;
RimEnsembleCurveSet* clickedEnsembleCurveSet = nullptr;
summaryCurve->firstAncestorOrThisOfType( clickedEnsembleCurveSet );
bool curveClicked = distanceFromClick < 50;
if ( clickedEnsembleCurveSet )
{
ensemble = clickedEnsembleCurveSet->summaryCaseCollection();
if ( ensemble && ensemble->isEnsemble() )
{
clickedQuantityName = QString::fromStdString( clickedEnsembleCurveSet->summaryAddress().uiText() );
}
}
{
auto summaryCase = summaryCurve->summaryCaseY();
if ( summaryCase )
{
int summaryCaseId = summaryCase->caseId();
QVariant summaryCaseIdVariant( summaryCaseId );
auto modelName = summaryCase->nativeCaseName();
menuBuilder.addCmdFeatureWithUserData( "RicImportGridModelFromSummaryCurveFeature",
QString( "Open Grid Model '%1'" ).arg( modelName ),
summaryCaseIdVariant );
}
}
if ( !curveClicked )
{
RimSummaryPlot* summaryPlot = static_cast<RimSummaryPlot*>( plotDefinition() );
std::vector<RimEnsembleCurveSet*> allCurveSetsInPlot;
summaryPlot->descendantsOfType( allCurveSetsInPlot );
for ( auto curveSet : allCurveSetsInPlot )
{
allQuantityNamesInPlot.push_back( QString::fromStdString( curveSet->summaryAddress().uiText() ) );
}
}
else
{
allQuantityNamesInPlot.push_back( clickedQuantityName );
}
if ( !clickedQuantityName.isEmpty() || !allQuantityNamesInPlot.isEmpty() )
{
if ( ensemble && ensemble->isEnsemble() )
{
EnsemblePlotParams params( ensemble, allQuantityNamesInPlot, clickedQuantityName, timeStep );
QVariant variant = QVariant::fromValue( params );
menuBuilder.addCmdFeatureWithUserData( "RicNewAnalysisPlotFeature", "New Analysis Plot", variant );
QString subMenuName = "Create Correlation Plot";
if ( curveClicked )
{
subMenuName = "Create Correlation Plot From Curve Point";
}
menuBuilder.subMenuStart( subMenuName, *caf::IconProvider( ":/CorrelationPlots16x16.png" ).icon() );
{
if ( curveClicked )
{
menuBuilder.addCmdFeatureWithUserData( "RicNewCorrelationPlotFeature",
"New Tornado Plot",
variant );
}
menuBuilder.addCmdFeatureWithUserData( "RicNewCorrelationMatrixPlotFeature",
"New Matrix Plot",
variant );
menuBuilder.addCmdFeatureWithUserData( "RicNewCorrelationReportPlotFeature",
"New Report Plot",
variant );
if ( curveClicked )
{
menuBuilder.subMenuStart( "Cross Plots",
*caf::IconProvider( ":/CorrelationCrossPlot16x16.png" ).icon() );
std::vector<std::pair<RigEnsembleParameter, double>> ensembleParameters =
ensemble->parameterCorrelations( clickedEnsembleCurveSet->summaryAddress(), timeStep );
std::sort( ensembleParameters.begin(),
ensembleParameters.end(),
[]( const std::pair<RigEnsembleParameter, double>& lhs,
const std::pair<RigEnsembleParameter, double>& rhs ) {
return std::fabs( lhs.second ) > std::fabs( rhs.second );
} );
for ( const auto& param : ensembleParameters )
{
if ( std::fabs( param.second ) >= 1.0e-6 )
{
params.ensembleParameter = param.first.name;
variant = QVariant::fromValue( params );
menuBuilder.addCmdFeatureWithUserData( "RicNewParameterResultCrossPlotFeature",
QString( "New Cross Plot Against %1 "
"(Correlation: %2)" )
.arg( param.first.name )
.arg( param.second, 5, 'f', 2 ),
variant );
}
}
menuBuilder.subMenuEnd();
}
}
menuBuilder.subMenuEnd();
}
}
}
}
}
menuBuilder.appendToMenu( &menu );
if ( menu.actions().size() > 0 )
{
menu.exec( event->globalPos() );
// Parts of progress dialog GUI can be present after menu has closed related to
// RicImportGridModelFromSummaryCurveFeature. Make sure the plot is updated, and call processEvents() to make
// sure all GUI events are processed
update();
QApplication::processEvents();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -398,5 +227,13 @@ void RiuSummaryQwtPlot::endZoomOperations()
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::onZoomedSlot()
{
emit plotZoomed();
emit m_plotWidget->plotZoomed();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotWidget* RiuSummaryQwtPlot::plotWidget() const
{
return m_plotWidget;
}

View File

@@ -19,10 +19,10 @@
#pragma once
#include "RiaQDateTimeTools.h"
#include "RiuInterfaceToViewWindow.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmPointer.h"
#include "RiuSummaryPlot.h"
#include <QPointer>
@@ -39,7 +39,7 @@ class RiuPlotAnnotationTool;
//
//
//==================================================================================================
class RiuSummaryQwtPlot : public RiuQwtPlotWidget
class RiuSummaryQwtPlot : public RiuSummaryPlot
{
Q_OBJECT;
@@ -51,24 +51,25 @@ public:
const QString& timeFormat,
RiaQDateTimeTools::DateFormatComponents dateComponents = RiaQDateTimeTools::DATE_FORMAT_UNSPECIFIED,
RiaQDateTimeTools::TimeFormatComponents timeComponents =
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED );
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_UNSPECIFIED ) override;
void useTimeBasedTimeAxis();
void setAxisIsLogarithmic( QwtPlot::Axis axis, bool logarithmic );
void useTimeBasedTimeAxis() override;
void updateAnnotationObjects( RimPlotAxisPropertiesInterface* axisProperties );
void updateAnnotationObjects( RimPlotAxisPropertiesInterface* axisProperties ) override;
RiuPlotWidget* plotWidget() const override;
protected:
void contextMenuEvent( QContextMenuEvent* ) override;
void setDefaults();
bool isZoomerActive() const override;
void endZoomOperations() override;
bool isZoomerActive() const;
void endZoomOperations();
private slots:
void onZoomedSlot();
private:
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
QPointer<RiuQwtPlotWidget> m_plotWidget;
QPointer<RiuQwtPlotZoomer> m_zoomerLeft;
QPointer<RiuQwtPlotZoomer> m_zoomerRight;

View File

@@ -32,6 +32,7 @@
#include "cvfAssert.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"

View File

@@ -22,7 +22,6 @@
#include "cafPdmPointer.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include <QList>
#include <QPointer>
@@ -31,6 +30,7 @@
#include "RiuInterfaceToViewWindow.h"
class RimTofAccumulatedPhaseFractionsPlot;
class QwtPlotCurve;
//==================================================================================================
//

View File

@@ -18,8 +18,6 @@
#pragma once
#include "qwt_plot.h"
#include "cafPdmPointer.h"
#include <QFrame>

View File

@@ -86,8 +86,8 @@ bool RiuWellLogPlot::showYAxis( int row, int column ) const
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::reinsertScrollbar()
{
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = this->visiblePlotWidgets();
int colCount = this->m_gridLayout->columnCount();
QList<QPointer<RiuPlotWidget>> plotWidgets = this->visiblePlotWidgets();
int colCount = this->m_gridLayout->columnCount();
m_gridLayout->addLayout( m_trackScrollBarLayout, 2, colCount, 1, 1 );
m_trackScrollBar->setVisible( !plotWidgets.empty() );

View File

@@ -19,14 +19,19 @@
#include "RiuWellLogTrack.h"
#include "RiaDefines.h"
#include "RiaPlotDefines.h"
#include "RimWellLogCurve.h"
#include "RimWellLogExtractionCurve.h"
#include "RimWellLogTrack.h"
#include "RiuGuiTheme.h"
#include "RiuPlotCurve.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuRimQwtPlotCurve.h"
#include "RiuQwtPlotTools.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_engine.h"
#include "qwt_scale_widget.h"
@@ -92,8 +97,8 @@ public:
//--------------------------------------------------------------------------------------------------
QString curveInfoText( QwtPlotCurve* curve ) override
{
RiuRimQwtPlotCurve* riuCurve = dynamic_cast<RiuRimQwtPlotCurve*>( curve );
RimWellLogCurve* wlCurve = nullptr;
RiuPlotCurve* riuCurve = dynamic_cast<RiuPlotCurve*>( curve );
RimWellLogCurve* wlCurve = nullptr;
if ( riuCurve )
{
wlCurve = dynamic_cast<RimWellLogCurve*>( riuCurve->ownerRimCurve() );
@@ -119,7 +124,7 @@ RiuWellLogTrack::RiuWellLogTrack( RimWellLogTrack* track, QWidget* parent /*= nu
setAxisEnabled( QwtPlot::xTop, true );
setAxisEnabled( QwtPlot::xBottom, false );
new RiuWellLogCurvePointTracker( this, &wellLogCurveInfoTextProvider );
new RiuWellLogCurvePointTracker( this->qwtPlot(), &wellLogCurveInfoTextProvider );
}
//--------------------------------------------------------------------------------------------------
@@ -134,20 +139,17 @@ RiuWellLogTrack::~RiuWellLogTrack()
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setAxisEnabled( QwtPlot::Axis axis, bool enabled )
{
RiaDefines::PlotAxis plotAxis = RiuQwtPlotTools::fromQwtPlotAxis( axis );
RiuQwtPlotWidget::enableAxis( plotAxis, enabled );
if ( enabled )
{
enableAxis( axis, true );
// Align the canvas with the actual min and max values of the curves
axisScaleEngine( axis )->setAttribute( QwtScaleEngine::Floating, true );
setAxisScale( axis, 0.0, 100.0 );
axisScaleDraw( axis )->setMinimumExtent( axisExtent( axis ) );
qwtPlot()->axisScaleEngine( axis )->setAttribute( QwtScaleEngine::Floating, true );
setAxisScale( plotAxis, 0.0, 100.0 );
qwtPlot()->axisScaleDraw( axis )->setMinimumExtent( axisExtent( plotAxis ) );
axisWidget( axis )->setMargin( 0 );
setAxisTitleEnabled( axis, true );
}
else
{
enableAxis( axis, false );
qwtPlot()->axisWidget( axis )->setMargin( 0 );
setAxisTitleEnabled( plotAxis, true );
}
}

View File

@@ -20,6 +20,8 @@
#include "RiuQwtPlotWidget.h"
#include "qwt_plot.h"
class RimWellLogTrack;
class QWheelEvent;

View File

@@ -180,15 +180,25 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
double posMax = 0.75 + m_columnOffset;
addColumnFeature( -posMax, -posMin, startDepth, endDepth, componentColor() );
addColumnFeature( posMin, posMax, startDepth, endDepth, componentColor() );
addMarker( -posMax, endDepth, 12, RiuQwtSymbol::SYMBOL_LEFT_ANGLED_TRIANGLE, componentColor() );
addMarker( posMax, endDepth, 12, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor() );
addMarker( casingTrackEnd, endDepth, 12, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor( 0.0 ), label() );
addMarker( -posMax, endDepth, 12, RiuPlotCurveSymbol::SYMBOL_LEFT_ANGLED_TRIANGLE, componentColor() );
addMarker( posMax, endDepth, 12, RiuPlotCurveSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor() );
addMarker( casingTrackEnd,
endDepth,
12,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE,
componentColor( 0.0 ),
label() );
}
else if ( m_componentType == RiaDefines::WellPathComponentType::LINER )
{
addColumnFeature( -0.5, -0.25, startDepth, endDepth, componentColor() );
addColumnFeature( 0.25, 0.5, startDepth, endDepth, componentColor() );
addMarker( casingTrackEnd, endDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor( 0.0 ), label() );
addMarker( casingTrackEnd,
endDepth,
10,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE,
componentColor( 0.0 ),
label() );
}
else if ( m_componentType == RiaDefines::WellPathComponentType::PERFORATION_INTERVAL )
{
@@ -200,18 +210,31 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
double markerDepth = startDepth;
while ( markerDepth < endDepth - 5 )
{
addMarker( -casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_LEFT_ALIGNED_TRIANGLE, componentColor() );
addMarker( casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor() );
addMarker( -casingTrackEnd,
markerDepth,
markerSize,
RiuPlotCurveSymbol::SYMBOL_LEFT_ALIGNED_TRIANGLE,
componentColor() );
addMarker( casingTrackEnd,
markerDepth,
markerSize,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE,
componentColor() );
markerDepth += markerSpacing;
}
addMarker( casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor( 0.0 ), label() );
addMarker( casingTrackEnd,
midDepth,
10,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE,
componentColor( 0.0 ),
label() );
QwtPlotItem* legendItem1 =
createMarker( 16.0, 0.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor() );
createMarker( 16.0, 0.0, 6, RiuPlotCurveSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor() );
legendItem1->setLegendIconSize( QSize( 4, 8 ) );
QwtPlotItem* legendItem2 =
createMarker( 16.0, 8.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor() );
createMarker( 16.0, 8.0, 6, RiuPlotCurveSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor() );
legendItem2->setLegendIconSize( QSize( 4, 8 ) );
m_combinedComponentGroup.addLegendItem( legendItem1 );
m_combinedComponentGroup.addLegendItem( legendItem2 );
@@ -220,7 +243,12 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
{
addColumnFeature( -casingTrackEnd, -0.25, startDepth, endDepth, componentColor(), Qt::BDiagPattern );
addColumnFeature( 0.25, casingTrackEnd, startDepth, endDepth, componentColor(), Qt::FDiagPattern );
addMarker( casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor( 0.0 ), label() );
addMarker( casingTrackEnd,
midDepth,
10,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE,
componentColor( 0.0 ),
label() );
}
else if ( m_componentType == RiaDefines::WellPathComponentType::FRACTURE )
{
@@ -229,7 +257,7 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
addMarker( casingTrackEnd,
startDepth,
10,
RiuQwtSymbol::SYMBOL_NONE,
RiuPlotCurveSymbol::SYMBOL_NONE,
componentColor(),
"",
Qt::AlignTop | Qt::AlignRight,
@@ -238,7 +266,7 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
addMarker( casingTrackEnd,
endDepth,
10,
RiuQwtSymbol::SYMBOL_NONE,
RiuPlotCurveSymbol::SYMBOL_NONE,
componentColor(),
"",
Qt::AlignTop | Qt::AlignRight,
@@ -247,7 +275,7 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
addMarker( casingTrackEnd,
startDepth,
1,
RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE,
componentColor( 0.0f ),
label(),
Qt::AlignTop | Qt::AlignRight );
@@ -256,34 +284,66 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate( bool updateParentPlot )
{
for ( double md : m_subMDs )
{
addMarker( 0.0, md, 16, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor(), "", Qt::AlignCenter, Qt::Horizontal, false, true );
addMarker( 0.0,
md,
16,
RiuPlotCurveSymbol::SYMBOL_ELLIPSE,
componentColor(),
"",
Qt::AlignCenter,
Qt::Horizontal,
false,
true );
}
m_combinedComponentGroup.addLegendItem(
createMarker( 0.0, 0.0, 12.0, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor() ) );
createMarker( 0.0, 0.0, 12.0, RiuPlotCurveSymbol::SYMBOL_ELLIPSE, componentColor() ) );
}
else if ( m_componentType == RiaDefines::WellPathComponentType::ICV )
{
for ( double md : m_subMDs )
{
addMarker( 0.0, md, 16, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor(), "", Qt::AlignCenter, Qt::Horizontal, false, true );
addMarker( 0.0,
md,
16,
RiuPlotCurveSymbol::SYMBOL_ELLIPSE,
componentColor(),
"",
Qt::AlignCenter,
Qt::Horizontal,
false,
true );
}
m_combinedComponentGroup.addLegendItem(
createMarker( 0.0, 0.0, 12.0, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor() ) );
createMarker( 0.0, 0.0, 12.0, RiuPlotCurveSymbol::SYMBOL_ELLIPSE, componentColor() ) );
}
else if ( m_componentType == RiaDefines::WellPathComponentType::AICD )
{
for ( double md : m_subMDs )
{
addMarker( 0.0, md, 16, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor(), "", Qt::AlignCenter, Qt::Horizontal, false, true );
addMarker( 0.0,
md,
16,
RiuPlotCurveSymbol::SYMBOL_ELLIPSE,
componentColor(),
"",
Qt::AlignCenter,
Qt::Horizontal,
false,
true );
}
m_combinedComponentGroup.addLegendItem(
createMarker( 0.0, 0.0, 12.0, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor() ) );
createMarker( 0.0, 0.0, 12.0, RiuPlotCurveSymbol::SYMBOL_ELLIPSE, componentColor() ) );
}
else if ( m_componentType == RiaDefines::WellPathComponentType::PACKER )
{
addColumnFeature( -1.1 * casingTrackEnd, -0.25, startDepth, endDepth, componentColor(), Qt::DiagCrossPattern );
addColumnFeature( 0.25, 1.1 * casingTrackEnd, startDepth, endDepth, componentColor(), Qt::DiagCrossPattern );
addMarker( casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor( 0.0 ), label() );
addMarker( casingTrackEnd,
midDepth,
10,
RiuPlotCurveSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE,
componentColor( 0.0 ),
label() );
}
m_combinedComponentGroup.setTitle( legendTitle() );
m_combinedComponentGroup.setLegendIconSize( QSize( 20, 16 ) );
@@ -335,16 +395,16 @@ std::pair<double, double> RiuWellPathComponentPlotItem::depthsOfDepthType() cons
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellPathComponentPlotItem::addMarker( double posX,
double depth,
int size,
RiuQwtSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label /*= QString("")*/,
Qt::Alignment labelAlignment /*= Qt::AlignTop*/,
Qt::Orientation labelOrientation /*= Qt::Vertical*/,
bool drawLine /*= false*/,
bool contrastTextColor /*= true*/ )
void RiuWellPathComponentPlotItem::addMarker( double posX,
double depth,
int size,
RiuPlotCurveSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label /*= QString("")*/,
Qt::Alignment labelAlignment /*= Qt::AlignTop*/,
Qt::Orientation labelOrientation /*= Qt::Vertical*/,
bool drawLine /*= false*/,
bool contrastTextColor /*= true*/ )
{
QwtPlotItem* marker =
createMarker( posX, depth, size, symbolType, baseColor, label, labelAlignment, labelOrientation, drawLine, contrastTextColor );
@@ -354,12 +414,12 @@ void RiuWellPathComponentPlotItem::addMarker( double posX
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QwtPlotItem* RiuWellPathComponentPlotItem::createMarker( double posX,
double depth,
int size,
RiuQwtSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label /*= QString("")*/,
QwtPlotItem* RiuWellPathComponentPlotItem::createMarker( double posX,
double depth,
int size,
RiuPlotCurveSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label /*= QString("")*/,
Qt::Alignment labelAlignment /*= Qt::AlignTop*/,
Qt::Orientation labelOrientation /*= Qt::Vertical*/,
bool drawLine /*= false*/,
@@ -372,8 +432,8 @@ QwtPlotItem* RiuWellPathComponentPlotItem::createMarker( double
textColor = RiaColorTools::toQColor( RiaColorTools::contrastColor( baseColor.toColor3f() ) );
}
QwtPlotMarker* marker = new QwtPlotMarker( label );
RiuQwtSymbol* symbol = new RiuQwtSymbol( symbolType, "", RiuQwtSymbol::LabelRightOfSymbol );
symbol->setSize( size );
RiuQwtSymbol* symbol = new RiuQwtSymbol( symbolType, "", RiuPlotCurveSymbol::LabelRightOfSymbol );
symbol->setSize( size, size );
symbol->setColor( bgColor );
marker->setSymbol( symbol );
marker->setSpacing( 6 );
@@ -512,7 +572,7 @@ void RiuWellPathComponentPlotItem::setContributeToLegend( bool contributeToLegen
//--------------------------------------------------------------------------------------------------
void RiuWellPathComponentPlotItem::setParentQwtPlotAndReplot( QwtPlot* plot )
{
setParentQwtPlotNoReplot( plot );
setParentPlotNoReplot( plot );
if ( m_parentQwtPlot )
{
m_parentQwtPlot->replot();
@@ -522,7 +582,7 @@ void RiuWellPathComponentPlotItem::setParentQwtPlotAndReplot( QwtPlot* plot )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellPathComponentPlotItem::setParentQwtPlotNoReplot( QwtPlot* plot )
void RiuWellPathComponentPlotItem::setParentPlotNoReplot( QwtPlot* plot )
{
m_parentQwtPlot = plot;
attachToQwt();

View File

@@ -68,7 +68,7 @@ public:
void setContributeToLegend( bool contributeToLegend );
void setParentQwtPlotAndReplot( QwtPlot* plot );
void setParentQwtPlotNoReplot( QwtPlot* plot );
void setParentPlotNoReplot( QwtPlot* plot );
void attachToQwt();
void detachFromQwt();
void reattachToQwt();
@@ -80,26 +80,26 @@ private:
std::pair<double, double> depthsOfDepthType() const;
void addMarker( double posX,
double depth,
int size,
RiuQwtSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label = QString( "" ),
Qt::Alignment labelAlignment = Qt::AlignVCenter | Qt::AlignRight,
Qt::Orientation labelOrientation = Qt::Horizontal,
bool drawLine = false,
bool contrastTextColor = false );
QwtPlotItem* createMarker( double posX,
double depth,
int size,
RiuQwtSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label = QString( "" ),
Qt::Alignment labelAlignment = Qt::AlignVCenter | Qt::AlignRight,
Qt::Orientation labelOrientation = Qt::Horizontal,
bool drawLine = false,
bool contrastTextColor = false );
void addMarker( double posX,
double depth,
int size,
RiuPlotCurveSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label = QString( "" ),
Qt::Alignment labelAlignment = Qt::AlignVCenter | Qt::AlignRight,
Qt::Orientation labelOrientation = Qt::Horizontal,
bool drawLine = false,
bool contrastTextColor = false );
QwtPlotItem* createMarker( double posX,
double depth,
int size,
RiuPlotCurveSymbol::PointSymbolEnum symbolType,
cvf::Color4f baseColor,
const QString& label = QString( "" ),
Qt::Alignment labelAlignment = Qt::AlignVCenter | Qt::AlignRight,
Qt::Orientation labelOrientation = Qt::Horizontal,
bool drawLine = false,
bool contrastTextColor = false );
void addColumnFeature( double startX,
double endX,
double startDepth,