From 5d6188b39c377bac914d97afdbda8a420c44cbf3 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Thu, 28 Jun 2018 08:23:16 +0200 Subject: [PATCH] #3103 Manual tick marker setting --- .../ProjectDataModel/RimWellLogTrack.cpp | 112 ++++++++++++------ .../ProjectDataModel/RimWellLogTrack.h | 3 + .../UserInterface/CMakeLists_files.cmake | 2 + .../UserInterface/RiuQwtLinearScaleEngine.cpp | 33 ++++++ .../UserInterface/RiuQwtLinearScaleEngine.h | 32 +++++ .../UserInterface/RiuWellLogTrack.cpp | 55 ++++++++- .../UserInterface/RiuWellLogTrack.h | 4 + 7 files changed, 204 insertions(+), 37 deletions(-) create mode 100644 ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp create mode 100644 ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp index a54c017954..159aa41dfb 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp @@ -20,6 +20,8 @@ #include "RimWellLogTrack.h" #include "RiaApplication.h" +#include "RiaExtractionTools.h" +#include "RiaSimWellBranchTools.h" #include "RigEclipseCaseData.h" #include "RigEclipseWellLogExtractor.h" @@ -55,12 +57,9 @@ #include "RiuWellLogPlot.h" #include "RiuWellLogTrack.h" +#include "RiuQwtLinearScaleEngine.h" #include "cvfAssert.h" -#include "qwt_scale_engine.h" -#include "RiaSimWellBranchTools.h" -#include "RiaExtractionTools.h" - #define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0 #define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0 #define RI_LOGPLOTTRACK_MINOR_TICK_DEFAULT @@ -153,6 +152,12 @@ RimWellLogTrack::RimWellLogTrack() CAF_PDM_InitFieldNoDefault(&m_showXGridLines, "ShowXGridLines", "Show Grid Lines", "", "", ""); + CAF_PDM_InitField(&m_explicitTickIntervals, "ExplicitTickIntervals", false, "Manually Set Tick Intervals", "", "", ""); + CAF_PDM_InitField(&m_majorTickInterval, "MajorTickIntervals", 0.0, "Major Tick Interval", "", "", ""); + CAF_PDM_InitField(&m_minorTickInterval, "MinorTickIntervals", 0.0, "Minor Tick Interval", "", "", ""); + m_majorTickInterval.uiCapability()->setUiHidden(true); + m_minorTickInterval.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_showFormations, "ShowFormations", false, "Show", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_formationSource, "FormationSource", "Source", "", "", ""); @@ -253,7 +258,24 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, updateAxisAndGridTickIntervals(); m_wellLogTrackPlotWidget->replot(); } - else if (changedField == &m_showXGridLines) + else if (changedField == &m_explicitTickIntervals) + { + if (m_wellLogTrackPlotWidget) + { + m_majorTickInterval = m_wellLogTrackPlotWidget->getCurrentMajorTickInterval(); + m_minorTickInterval = m_wellLogTrackPlotWidget->getCurrentMinorTickInterval(); + } + m_majorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + m_minorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + if (!m_explicitTickIntervals()) + { + updateAxisAndGridTickIntervals(); + m_wellLogTrackPlotWidget->replot(); + } + } + else if (changedField == &m_showXGridLines || + changedField == &m_majorTickInterval || + changedField == &m_minorTickInterval) { updateAxisAndGridTickIntervals(); m_wellLogTrackPlotWidget->replot(); @@ -261,10 +283,11 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, else if (changedField == &m_visibleXRangeMin || changedField == &m_visibleXRangeMax) { m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); - m_wellLogTrackPlotWidget->replot(); m_isAutoScaleXEnabled = false; updateEditors(); - updateParentPlotLayout(); + updateParentPlotLayout(); + updateAxisAndGridTickIntervals(); + m_wellLogTrackPlotWidget->replot(); } else if (changedField == &m_isAutoScaleXEnabled) { @@ -279,6 +302,11 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, else if (changedField == &m_isLogarithmicScaleEnabled) { updateAxisScaleEngine(); + if (m_isLogarithmicScaleEnabled()) + { + m_explicitTickIntervals = false; + } + m_explicitTickIntervals.uiCapability()->setUiHidden(m_isLogarithmicScaleEnabled()); this->calculateXZoomRangeAndUpdateQwt(); computeAndSetXRangeMinForLogarithmicScale(); @@ -405,34 +433,40 @@ void RimWellLogTrack::updateAxisAndGridTickIntervals() { if (!m_wellLogTrackPlotWidget) return; - int xMajorTickIntervals = 3; - int xMinorTickIntervals = 0; - switch (m_widthScaleFactor()) + if (m_explicitTickIntervals) { - case EXTRA_NARROW_TRACK: - xMajorTickIntervals = 3; - xMinorTickIntervals = 2; - break; - case NARROW_TRACK: - xMajorTickIntervals = 3; - xMinorTickIntervals = 5; - break; - case NORMAL_TRACK: - xMajorTickIntervals = 5; - xMinorTickIntervals = 5; - break; - case WIDE_TRACK: - xMajorTickIntervals = 5; - xMinorTickIntervals = 10; - break; - case EXTRA_WIDE_TRACK: - xMajorTickIntervals = 10; - xMinorTickIntervals = 10; - break; + m_wellLogTrackPlotWidget->setMajorAndMinorTickIntervals(m_majorTickInterval(), m_minorTickInterval()); } - - m_wellLogTrackPlotWidget->setAxisMaxMajor(QwtPlot::xTop, xMajorTickIntervals); - m_wellLogTrackPlotWidget->setAxisMaxMinor(QwtPlot::xTop, xMinorTickIntervals); + else + { + int xMajorTickIntervals = 3; + int xMinorTickIntervals = 0; + switch (m_widthScaleFactor()) + { + case EXTRA_NARROW_TRACK: + xMajorTickIntervals = 3; + xMinorTickIntervals = 2; + break; + case NARROW_TRACK: + xMajorTickIntervals = 3; + xMinorTickIntervals = 5; + break; + case NORMAL_TRACK: + xMajorTickIntervals = 5; + xMinorTickIntervals = 5; + break; + case WIDE_TRACK: + xMajorTickIntervals = 5; + xMinorTickIntervals = 10; + break; + case EXTRA_WIDE_TRACK: + xMajorTickIntervals = 10; + xMinorTickIntervals = 10; + break; + } + m_wellLogTrackPlotWidget->setAutoTickIntervals(xMajorTickIntervals, xMinorTickIntervals); + } + switch (m_showXGridLines()) { case GRID_X_NONE: @@ -647,11 +681,14 @@ void RimWellLogTrack::loadDataAndUpdate() if ( m_wellLogTrackPlotWidget ) { m_wellLogTrackPlotWidget->updateLegend(); - this->updateAxisAndGridTickIntervals(); this->updateAxisScaleEngine(); this->updateFormationNamesOnPlot(); this->applyXZoomFromVisibleRange(); + this->updateAxisAndGridTickIntervals(); } + + m_majorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + m_minorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); } //-------------------------------------------------------------------------------------------------- @@ -1070,10 +1107,10 @@ void RimWellLogTrack::updateAxisScaleEngine() } else { - m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new QwtLinearScaleEngine); + m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new RiuQwtLinearScaleEngine); // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work - m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine); + m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new RiuQwtLinearScaleEngine); } } @@ -1191,6 +1228,9 @@ void RimWellLogTrack::uiOrderingForXAxisSettings(caf::PdmUiOrdering& uiOrdering) gridGroup->add(&m_visibleXRangeMin); gridGroup->add(&m_visibleXRangeMax); gridGroup->add(&m_showXGridLines); + gridGroup->add(&m_explicitTickIntervals); + gridGroup->add(&m_majorTickInterval); + gridGroup->add(&m_minorTickInterval); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h index 48134d1849..7db6ba0544 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h @@ -176,6 +176,9 @@ private: caf::PdmField m_isAutoScaleXEnabled; caf::PdmField m_isLogarithmicScaleEnabled; caf::PdmField> m_showXGridLines; + caf::PdmField m_explicitTickIntervals; + caf::PdmField m_majorTickInterval; + caf::PdmField m_minorTickInterval; caf::PdmField m_showFormations; caf::PdmField> m_formationSource; diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index 29557d6499..36c987fbfe 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -18,6 +18,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuProjectPropertyView.h ${CMAKE_CURRENT_LIST_DIR}/RiuPropertyViewTabWidget.h ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotPanel.h ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotUpdater.h +${CMAKE_CURRENT_LIST_DIR}/RiuQwtLinearScaleEngine.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtCurvePointTracker.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.h @@ -92,6 +93,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuProjectPropertyView.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPropertyViewTabWidget.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotPanel.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotUpdater.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuQwtLinearScaleEngine.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtCurvePointTracker.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.cpp diff --git a/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp new file mode 100644 index 0000000000..09820f2159 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#include "RiuQwtLinearScaleEngine.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtScaleDiv RiuQwtLinearScaleEngine::divideScale(double x1, double x2, double majorStepInterval, double minorStepInterval) +{ + QwtInterval interval(x1, x2); + QwtInterval roundedInterval = this->align(interval, majorStepInterval); + QList majorTicks = this->buildMajorTicks(roundedInterval, majorStepInterval); + QList minorTicks = this->buildMajorTicks(roundedInterval, minorStepInterval); + + return QwtScaleDiv(x1, x2, minorTicks, minorTicks, majorTicks); +} diff --git a/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h new file mode 100644 index 0000000000..003d951a64 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h @@ -0,0 +1,32 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "qwt_scale_engine.h" + +//================================================================================================== +// +// +// +//================================================================================================== +class RiuQwtLinearScaleEngine : public QwtLinearScaleEngine +{ +public: + QwtScaleDiv divideScale(double x1, double x2, double majorStepInterval, double minorStepInterval); +}; diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp index 3b76108547..2dc9f1b0a1 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp @@ -28,6 +28,8 @@ #include "RiuPlotMainWindowTools.h" #include "RiuQwtCurvePointTracker.h" +#include "RiuQwtLinearScaleEngine.h" + #include "qwt_legend.h" #include "qwt_plot_curve.h" #include "qwt_plot_grid.h" @@ -35,7 +37,6 @@ #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" @@ -305,3 +306,55 @@ void RiuWellLogTrack::enableGridLines(bool majorGridLines, bool minorGridLines) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::setMajorAndMinorTickIntervals(double majorTickInterval, double minorTickInterval) +{ + RiuQwtLinearScaleEngine* scaleEngine = dynamic_cast(this->axisScaleEngine(QwtPlot::xTop)); + if (scaleEngine) + { + QwtInterval currentRange = this->axisInterval(QwtPlot::xTop); + QwtScaleDiv scaleDiv = scaleEngine->divideScale(currentRange.minValue(), currentRange.maxValue(), majorTickInterval, minorTickInterval); + + this->setAxisScaleDiv(QwtPlot::xTop, scaleDiv); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::setAutoTickIntervals(int maxMajorTickIntervals, int maxMinorTickIntervals) +{ + this->setAxisMaxMajor(QwtPlot::xTop, maxMajorTickIntervals); + this->setAxisMaxMinor(QwtPlot::xTop, maxMinorTickIntervals); + // Reapply axis limits to force Qwt to use the tick settings. + QwtInterval currentRange = this->axisInterval(QwtPlot::xTop); + this->setAxisScale(QwtPlot::xTop, currentRange.minValue(), currentRange.maxValue()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RiuWellLogTrack::getCurrentMajorTickInterval() const +{ + QwtScaleDiv scaleDiv = this->axisScaleDiv(QwtPlot::xTop); + QList majorTicks = scaleDiv.ticks(QwtScaleDiv::MajorTick); + if (majorTicks.size() < 2) return 0.0; + + return majorTicks.at(1) - majorTicks.at(0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RiuWellLogTrack::getCurrentMinorTickInterval() const +{ + QwtScaleDiv scaleDiv = this->axisScaleDiv(QwtPlot::xTop); + QList minorTicks = scaleDiv.ticks(QwtScaleDiv::MinorTick); + if (minorTicks.size() < 2) return 0.0; + + return minorTicks.at(1) - minorTicks.at(0); + +} + diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index b061013b16..f1cfaa9805 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -55,6 +55,10 @@ public: void enableVerticalAxisLabelsAndTitle(bool enable); int widthScaleFactor() const; void enableGridLines(bool majorGridLines, bool minorGridLines); + void setMajorAndMinorTickIntervals(double majorTickInterval, double minorTickInterval); + void setAutoTickIntervals(int maxMajorTickIntervals, int maxMinorTickIntervals); + double getCurrentMajorTickInterval() const; + double getCurrentMinorTickInterval() const; protected: virtual bool eventFilter(QObject* watched, QEvent* event); virtual QSize sizeHint() const;