From c7ac7ab9f909b4af0a991e45b9f1ab9d3b2917c0 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 22 Nov 2016 11:56:37 +0100 Subject: [PATCH] #943 Well log plot: Display curve value when pointing with cursor --- .../UserInterface/RiuSummaryQwtPlot.h | 6 +- .../UserInterface/RiuWellLogTrack.cpp | 169 +++++++++++++++++- .../UserInterface/RiuWellLogTrack.h | 13 +- 3 files changed, 184 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index c6e886c9ca..7f555c4207 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -57,14 +57,16 @@ public: const QwtInterval& rightAxis, const QwtInterval& timeAxis); - QPointF closestCurvePoint(const QPoint& pos, QString* valueString, QString* timeString, int* yAxis) const; - void updateClosestCurvePointMarker(const QPointF& pos, int yAxis); protected: virtual bool eventFilter(QObject* watched, QEvent* event) override; virtual void leaveEvent(QEvent *) override; private: + friend class RiuQwtPlotPicker; + QPointF closestCurvePoint(const QPoint& pos, QString* valueString, QString* timeString, int* yAxis) const; + void updateClosestCurvePointMarker(const QPointF& pos, int yAxis); + void setDefaults(); void selectClosestCurve(const QPoint& pos); void showToolTip(const QPoint& pos); diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp index 5f9b878133..5903e2ce30 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp @@ -19,6 +19,8 @@ #include "RiuWellLogTrack.h" +#include "RiaApplication.h" + #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" #include "RimWellLogCurve.h" @@ -29,8 +31,11 @@ #include "qwt_plot_curve.h" #include "qwt_plot_grid.h" #include "qwt_plot_layout.h" +#include "qwt_plot_marker.h" +#include "qwt_plot_picker.h" #include "qwt_scale_draw.h" #include "qwt_scale_engine.h" +#include "qwt_symbol.h" #include "qwt_text.h" #include @@ -39,11 +44,57 @@ #include #include -#include "RiaApplication.h" #define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1 #define RIU_SCROLLWHEEL_PANFACTOR 0.1 +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RiuWellLogTrackQwtPicker : public QwtPlotPicker +{ +public: + RiuWellLogTrackQwtPicker(QWidget *canvas) + : QwtPlotPicker(canvas) + { + } + +protected: + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual QwtText trackerText(const QPoint& pos) const override + { + QwtText txt; + + const RiuWellLogTrack* wellLogTrack = dynamic_cast(this->plot()); + if (wellLogTrack) + { + QString depthString; + QString valueString; + QPointF closestPoint = wellLogTrack->closestCurvePoint(pos, &valueString, &depthString); + if (!closestPoint.isNull()) + { + QString str = valueString; + + if (!depthString.isEmpty()) + { + str += QString(" (%1)").arg(depthString); + } + + txt.setText(str); + } + + RiuWellLogTrack* nonConstPlot = const_cast(wellLogTrack); + nonConstPlot->updateClosestCurvePointMarker(closestPoint); + } + + return txt; + } +}; + + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -58,6 +109,16 @@ RiuWellLogTrack::RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* setFocusPolicy(Qt::ClickFocus); setDefaults(); + + // Create a plot picker to display values next to mouse cursor + m_plotPicker = new RiuWellLogTrackQwtPicker(this->canvas()); + m_plotPicker->setTrackerMode(QwtPicker::AlwaysOn); + + m_plotMarker = new QwtPlotMarker; + + // QwtPlotMarker takes ownership of the symbol, it is deleted in destructor of QwtPlotMarker + QwtSymbol* mySymbol = new QwtSymbol(QwtSymbol::Ellipse, Qt::NoBrush, QPen(Qt::black, 2.0), QSize(12, 12)); + m_plotMarker->setSymbol(mySymbol); } //-------------------------------------------------------------------------------------------------- @@ -67,6 +128,99 @@ RiuWellLogTrack::~RiuWellLogTrack() { m_grid->detach(); delete m_grid; + + m_plotMarker->detach(); + delete m_plotMarker; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QPointF RiuWellLogTrack::closestCurvePoint(const QPoint& pos, QString* valueString, QString* depthString) const +{ + QPointF samplePoint; + + QwtPlotCurve* closestCurve = nullptr; + double distMin = DBL_MAX; + int closestPointSampleIndex = -1; + + const QwtPlotItemList& itmList = itemList(); + for (QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++) + { + if ((*it)->rtti() == QwtPlotItem::Rtti_PlotCurve) + { + QwtPlotCurve* candidateCurve = static_cast(*it); + double dist = DBL_MAX; + int candidateSampleIndex = candidateCurve->closestPoint(pos, &dist); + if (dist < distMin) + { + closestCurve = candidateCurve; + distMin = dist; + closestPointSampleIndex = candidateSampleIndex; + } + } + } + + if (closestCurve && distMin < 50) + { + samplePoint = closestCurve->sample(closestPointSampleIndex); + } + + if (depthString) + { + const QwtScaleDraw* depthAxisScaleDraw = axisScaleDraw(QwtPlot::yLeft); + if (depthAxisScaleDraw) + { + *depthString = depthAxisScaleDraw->label(samplePoint.y()).text(); + } + } + + if (valueString && closestCurve) + { + const QwtScaleDraw* xAxisScaleDraw = axisScaleDraw(closestCurve->xAxis()); + if (xAxisScaleDraw) + { + *valueString = xAxisScaleDraw->label(samplePoint.x()).text(); + } + } + + return samplePoint; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::updateClosestCurvePointMarker(const QPointF& pos) +{ + bool replotRequired = false; + + if (!pos.isNull()) + { + if (!m_plotMarker->plot()) + { + m_plotMarker->attach(this); + + replotRequired = true; + } + + if (m_plotMarker->value() != pos) + { + m_plotMarker->setValue(pos.x(), pos.y()); + + replotRequired = true; + } + } + else + { + if (m_plotMarker->plot()) + { + m_plotMarker->detach(); + + replotRequired = true; + } + } + + if (replotRequired) this->replot(); } //-------------------------------------------------------------------------------------------------- @@ -276,6 +430,19 @@ QSize RiuWellLogTrack::minimumSizeHint() const return QSize(0, 0); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::leaveEvent(QEvent *) +{ + if (m_plotMarker->plot()) + { + m_plotMarker->detach(); + + replot(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index 83d89fbf50..d939d8f560 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -20,11 +20,15 @@ #pragma once #include "qwt_plot.h" + #include "cafPdmPointer.h" class RimWellLogTrack; -class QwtPlotGrid; + class QwtLegend; +class QwtPicker; +class QwtPlotGrid; +class QwtPlotMarker; class QEvent; @@ -53,13 +57,20 @@ protected: virtual void focusInEvent(QFocusEvent* event); virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; + virtual void leaveEvent(QEvent *) override; private: + friend class RiuWellLogTrackQwtPicker; + QPointF closestCurvePoint(const QPoint& pos, QString* valueString, QString* depthString) const; + void updateClosestCurvePointMarker(const QPointF& pos); + void setDefaults(); void selectClosestCurve(const QPoint& pos); private: caf::PdmPointer m_plotTrackDefinition; QwtPlotGrid* m_grid; + QwtPicker* m_plotPicker; + QwtPlotMarker* m_plotMarker; };