diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CorrelationPlots/CMakeLists_files.cmake index e3a589a22b..4f3951d178 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/CMakeLists_files.cmake @@ -26,6 +26,7 @@ ${SOURCE_GROUP_SOURCE_FILES} ) list(APPEND QT_MOC_HEADERS +${CMAKE_CURRENT_LIST_DIR}/RimCorrelationPlot.h ${CMAKE_CURRENT_LIST_DIR}/RimCorrelationMatrixPlot.h ${CMAKE_CURRENT_LIST_DIR}/RimCorrelationReportPlot.h ) diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.cpp b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.cpp index a6362240cd..1c78636420 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.cpp +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.cpp @@ -549,7 +549,7 @@ void RimCorrelationMatrixPlot::updateLegend() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimCorrelationMatrixPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle ) +void RimCorrelationMatrixPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) { CorrelationMatrixShapeItem* matrixItem = dynamic_cast( plotItem ); if ( matrixItem ) diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.h b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.h index a8aeee06e0..d8b77cee90 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.h +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationMatrixPlot.h @@ -71,7 +71,7 @@ private: void createMatrix(); void updatePlotTitle() override; void updateLegend() override; - void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle ) override; + void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) override; private: caf::PdmField m_correlationFactor; diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.cpp b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.cpp index 17daac8d04..d8e6e93d10 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.cpp @@ -39,6 +39,8 @@ #include "cafPdmUiComboBoxEditor.h" +#include "qwt_plot_barchart.h" + #include #include #include @@ -295,6 +297,26 @@ void RimCorrelationPlot::updatePlotTitle() m_plotWidget->setPlotTitleFontSize( isMdiWindow() ? 8 : 10 ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCorrelationPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) +{ + QwtPlotBarChart* barChart = dynamic_cast( plotItem ); + if ( barChart && !curveDefinitions().empty() ) + { + auto curveDef = curveDefinitions().front(); + auto barTitle = barChart->title(); + for ( auto param : ensembleParameters() ) + { + if ( barTitle.text() == param.name ) + { + emit tornadoItemSelected( param, curveDef ); + } + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.h b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.h index 367e25b037..45bab27885 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.h +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationPlot.h @@ -18,7 +18,9 @@ #pragma once +#include "RiaSummaryCurveDefinition.h" #include "RimAbstractCorrelationPlot.h" +#include "RimSummaryCaseCollection.h" #include "cafAppEnum.h" #include @@ -32,6 +34,7 @@ class RiuGroupedBarChartBuilder; //================================================================================================== class RimCorrelationPlot : public RimAbstractCorrelationPlot { + Q_OBJECT; CAF_PDM_HEADER_INIT; public: @@ -55,6 +58,9 @@ public: bool sortByAbsoluteValues() const; void setSortByAbsoluteValues( bool sortByAbsoluteValues ); +signals: + void tornadoItemSelected( const EnsembleParameter&, const RiaSummaryCurveDefinition& curveDef ); + private: // Overridden PDM methods @@ -71,6 +77,7 @@ private: // Private methods void addDataToChartBuilder( RiuGroupedBarChartBuilder& chartBuilder ); void updatePlotTitle() override; + void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) override; private: caf::PdmField m_correlationFactor; diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.cpp b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.cpp index 484003555c..1ffcede5fa 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.cpp +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.cpp @@ -65,7 +65,11 @@ RimCorrelationReportPlot::RimCorrelationReportPlot() this->connect( m_correlationMatrixPlot(), SIGNAL( matrixCellSelected( const EnsembleParameter&, const RiaSummaryCurveDefinition& ) ), - SLOT( onMatrixCellSelected( const EnsembleParameter&, const RiaSummaryCurveDefinition& ) ) ); + SLOT( onDataSelection( const EnsembleParameter&, const RiaSummaryCurveDefinition& ) ) ); + + this->connect( m_correlationPlot(), + SIGNAL( tornadoItemSelected( const EnsembleParameter&, const RiaSummaryCurveDefinition& ) ), + SLOT( onDataSelection( const EnsembleParameter&, const RiaSummaryCurveDefinition& ) ) ); } //-------------------------------------------------------------------------------------------------- @@ -304,8 +308,7 @@ void RimCorrelationReportPlot::childFieldChangedByUi( const caf::PdmFieldHandle* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimCorrelationReportPlot::onMatrixCellSelected( const EnsembleParameter& param, - const RiaSummaryCurveDefinition& curveDef ) +void RimCorrelationReportPlot::onDataSelection( const EnsembleParameter& param, const RiaSummaryCurveDefinition& curveDef ) { m_correlationPlot->setCurveDefinitions( { curveDef } ); m_correlationPlot->loadDataAndUpdate(); diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.h b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.h index 42f15c4e8a..6dec310fef 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.h +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimCorrelationReportPlot.h @@ -74,7 +74,7 @@ private: void childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField ) override; private slots: - void onMatrixCellSelected( const EnsembleParameter& param, const RiaSummaryCurveDefinition& curveDef ); + void onDataSelection( const EnsembleParameter& param, const RiaSummaryCurveDefinition& curveDef ); private: caf::PdmProxyValueField m_plotWindowTitle; diff --git a/ApplicationCode/ProjectDataModel/RimPlot.cpp b/ApplicationCode/ProjectDataModel/RimPlot.cpp index 06e1b837d5..412d23f77d 100644 --- a/ApplicationCode/ProjectDataModel/RimPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimPlot.cpp @@ -163,8 +163,8 @@ void RimPlot::attachPlotWidgetSignals( RimPlot* plot, RiuQwtPlotWidget* plotWidg plot->connect( plotWidget, SIGNAL( plotSelected( bool ) ), SLOT( onPlotSelected( bool ) ) ); plot->connect( plotWidget, SIGNAL( axisSelected( int, bool ) ), SLOT( onAxisSelected( int, bool ) ) ); plot->connect( plotWidget, - SIGNAL( plotItemSelected( QwtPlotItem*, bool ) ), - SLOT( onPlotItemSelected( QwtPlotItem*, bool ) ) ); + SIGNAL( plotItemSelected( QwtPlotItem*, bool, int ) ), + SLOT( onPlotItemSelected( QwtPlotItem*, bool, int ) ) ); plot->connect( plotWidget, SIGNAL( onKeyPressEvent( QKeyEvent* ) ), SLOT( onKeyPressEvent( QKeyEvent* ) ) ); plot->connect( plotWidget, SIGNAL( onWheelEvent( QWheelEvent* ) ), SLOT( onWheelEvent( QWheelEvent* ) ) ); plot->connect( plotWidget, SIGNAL( destroyed() ), SLOT( onViewerDestroyed() ) ); @@ -199,7 +199,7 @@ void RimPlot::onPlotSelected( bool toggle ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle ) +void RimPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) { QwtPlotCurve* curve = dynamic_cast( plotItem ); if ( curve ) diff --git a/ApplicationCode/ProjectDataModel/RimPlot.h b/ApplicationCode/ProjectDataModel/RimPlot.h index 32940377b2..c39592b102 100644 --- a/ApplicationCode/ProjectDataModel/RimPlot.h +++ b/ApplicationCode/ProjectDataModel/RimPlot.h @@ -105,7 +105,7 @@ private: private slots: void onPlotSelected( bool toggle ); virtual void onAxisSelected( int axis, bool toggle ) {} - virtual void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle ); + virtual void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ); void onViewerDestroyed(); void onKeyPressEvent( QKeyEvent* event ); void onWheelEvent( QWheelEvent* event ); diff --git a/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp b/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp index f17b59f8b1..c16653c37e 100644 --- a/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp @@ -84,6 +84,9 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimGridCrossPlot* plot, QWidget* paren 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 ) ) ); m_annotationTool = std::unique_ptr( new RiuPlotAnnotationTool() ); m_selectedPointMarker = new QwtPlotMarker; @@ -189,35 +192,36 @@ void RiuGridCrossQwtPlot::contextMenuEvent( QContextMenuEvent* event ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuGridCrossQwtPlot::selectPoint( QwtPlotCurve* curve, int pointNumber ) +void RiuGridCrossQwtPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int pointNumber ) { - QPointF sample = curve->sample( pointNumber ); - m_selectedPointMarker->setValue( sample ); - m_selectedPointMarker->setAxes( QwtPlot::xBottom, QwtPlot::yLeft ); - m_selectedPointMarker->attach( this ); - QString curveName, xAxisName, yAxisName; - if ( curveText( curve, &curveName, &xAxisName, &yAxisName ) ) + if ( pointNumber == -1 ) + m_selectedPointMarker->detach(); + else { - QString labelFormat( "
%1:
%2 = %3, %4 = %5
" ); - QString labelString = - labelFormat.arg( curveName ).arg( xAxisName ).arg( sample.x() ).arg( yAxisName ).arg( sample.y() ); - QwtText curveLabel( labelString, QwtText::RichText ); - curveLabel.setBackgroundBrush( QBrush( QColor( 250, 250, 250, 220 ) ) ); - curveLabel.setPaintAttribute( QwtText::PaintBackground ); - curveLabel.setBorderPen( QPen( Qt::black, 1.0 ) ); - curveLabel.setBorderRadius( 2.0 ); - m_selectedPointMarker->setLabel( curveLabel ); + QwtPlotCurve* curve = dynamic_cast( plotItem ); + if ( curve ) + { + QPointF sample = curve->sample( pointNumber ); + m_selectedPointMarker->setValue( sample ); + m_selectedPointMarker->setAxes( QwtPlot::xBottom, QwtPlot::yLeft ); + m_selectedPointMarker->attach( this ); + QString curveName, xAxisName, yAxisName; + if ( curveText( curve, &curveName, &xAxisName, &yAxisName ) ) + { + QString labelFormat( "
%1:
%2 = %3, %4 = %5
" ); + QString labelString = + labelFormat.arg( curveName ).arg( xAxisName ).arg( sample.x() ).arg( yAxisName ).arg( sample.y() ); + QwtText curveLabel( labelString, QwtText::RichText ); + curveLabel.setBackgroundBrush( QBrush( QColor( 250, 250, 250, 220 ) ) ); + curveLabel.setPaintAttribute( QwtText::PaintBackground ); + curveLabel.setBorderPen( QPen( Qt::black, 1.0 ) ); + curveLabel.setBorderRadius( 2.0 ); + m_selectedPointMarker->setLabel( curveLabel ); + } + } } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuGridCrossQwtPlot::clearPointSelection() -{ - m_selectedPointMarker->detach(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.h b/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.h index 30e291cdba..50a5e3081c 100644 --- a/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.h @@ -67,14 +67,13 @@ signals: protected: void contextMenuEvent( QContextMenuEvent* ) override; - void selectPoint( QwtPlotCurve* curve, int pointNumber ) override; - void clearPointSelection() override; bool curveText( const QwtPlotCurve* curve, QString* curveTitle, QString* xParamName, QString* yParamName ) const; bool isZoomerActive() const override; void endZoomOperations() override; private slots: void onZoomedSlot(); + void onPlotItemSelected( QwtPlotItem* selectedItem, bool toggleItem, int sampleIndex ); private: std::unique_ptr m_annotationTool; diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWidget.cpp b/ApplicationCode/UserInterface/RiuQwtPlotWidget.cpp index e116af8bc2..948206754f 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotWidget.cpp +++ b/ApplicationCode/UserInterface/RiuQwtPlotWidget.cpp @@ -36,6 +36,7 @@ #include "qwt_legend.h" #include "qwt_legend_label.h" +#include "qwt_plot_barchart.h" #include "qwt_plot_canvas.h" #include "qwt_plot_curve.h" #include "qwt_plot_grid.h" @@ -741,20 +742,6 @@ QSize RiuQwtPlotWidget::minimumSizeHint() const return QSize( 0, 0 ); } -//-------------------------------------------------------------------------------------------------- -/// Empty default implementation -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotWidget::selectPoint( QwtPlotCurve* curve, int pointNumber ) -{ -} - -//-------------------------------------------------------------------------------------------------- -/// Empty default implementation -//-------------------------------------------------------------------------------------------------- -void RiuQwtPlotWidget::clearPointSelection() -{ -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -983,13 +970,32 @@ void RiuQwtPlotWidget::selectClosestPlotItem( const QPoint& pos, bool toggleItem else if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotShape ) { QwtPlotShapeItem* shapeItem = static_cast( *it ); - QPoint scalePos( invTransform( xBottom, pos.x() ), invTransform( yLeft, pos.y() ) ); + QPointF scalePos( invTransform( xBottom, pos.x() ), invTransform( yLeft, pos.y() ) ); if ( shapeItem->shape().boundingRect().contains( scalePos ) ) { closestItem = *it; distMin = 0.0; } } + else if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotBarChart ) + { + QwtPlotBarChart* barChart = static_cast( *it ); + QPointF scalePos( invTransform( xBottom, pos.x() ), invTransform( yLeft, pos.y() ) ); + + bool horizontal = barChart->orientation() == Qt::Horizontal; + for ( size_t i = 0; i < barChart->dataSize(); ++i ) + { + QPointF samplePoint = barChart->sample( i ); + double dist = horizontal ? std::abs( samplePoint.x() - scalePos.y() ) + : std::abs( samplePoint.x() - scalePos.x() ); + if ( dist < distMin ) + { + closestItem = *it; + closestCurvePoint = (int)i; + distMin = dist; + } + } + } } RiuPlotMainWindowTools::showPlotMainWindow(); @@ -998,16 +1004,8 @@ void RiuQwtPlotWidget::selectClosestPlotItem( const QPoint& pos, bool toggleItem { // TODO: highlight all selected curves highlightPlotItem( closestItem ); - emit plotItemSelected( closestItem, toggleItemInSelection ); + emit plotItemSelected( closestItem, toggleItemInSelection, distMin < 10 ? closestCurvePoint : -1 ); - if ( distMin < 10 && ( closestItem )->rtti() == QwtPlotItem::Rtti_PlotCurve ) - { - selectPoint( static_cast( closestItem ), closestCurvePoint ); - } - else - { - clearPointSelection(); - } scheduleReplot(); } else diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWidget.h b/ApplicationCode/UserInterface/RiuQwtPlotWidget.h index 87e0542cde..882ab6786d 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotWidget.h +++ b/ApplicationCode/UserInterface/RiuQwtPlotWidget.h @@ -136,7 +136,7 @@ public: signals: void plotSelected( bool toggleSelection ); void axisSelected( int axisId, bool toggleSelection ); - void plotItemSelected( QwtPlotItem* plotItem, bool toggleSelection ); + void plotItemSelected( QwtPlotItem* plotItem, bool toggleSelection, int sampleIndex ); void onKeyPressEvent( QKeyEvent* event ); void onWheelEvent( QWheelEvent* event ); @@ -153,8 +153,6 @@ protected: QSize sizeHint() const override; QSize minimumSizeHint() const override; - virtual void selectPoint( QwtPlotCurve* curve, int pointNumber ); - virtual void clearPointSelection(); virtual bool isZoomerActive() const; virtual void endZoomOperations();