From 40d5150b37bb3a6b55cd7d1b37a42b6b7f7fdc34 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 24 Mar 2017 12:10:05 +0100 Subject: [PATCH 01/28] #1358 Added support for "Zoom All" of well alloc plots --- .../RicViewZoomAllFeature.cpp | 42 ++++++++++++++----- .../Flow/RimWellAllocationPlot.cpp | 1 + 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp index 33952169e2..2459c54cd8 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp @@ -23,11 +23,13 @@ #include "RimSummaryPlot.h" #include "RimView.h" #include "RimViewWindow.h" +#include "RimWellAllocationPlot.h" #include "RimWellLogPlot.h" #include "RiuMainPlotWindow.h" #include "RiuMainWindow.h" #include "RiuSummaryQwtPlot.h" +#include "RiuWellAllocationPlot.h" #include "RiuWellLogPlot.h" #include @@ -62,21 +64,41 @@ void RicViewZoomAllFeature::onActionTriggered(bool isChecked) QList subwindows = mainPlotWindow->subWindowList(QMdiArea::StackingOrder); if (subwindows.size() > 0) { - RiuSummaryQwtPlot* summaryQwtPlot = dynamic_cast(subwindows.back()->widget()); - if (summaryQwtPlot) { - RimViewWindow* viewWindow = summaryQwtPlot->ownerPlotDefinition(); + RiuSummaryQwtPlot* summaryQwtPlot = dynamic_cast(subwindows.back()->widget()); + if (summaryQwtPlot) + { + RimViewWindow* viewWindow = summaryQwtPlot->ownerPlotDefinition(); - viewWindow->zoomAll(); - summaryQwtPlot->replot(); + viewWindow->zoomAll(); + summaryQwtPlot->replot(); + + return; + } } - RiuWellLogPlot* wellLogPlot = dynamic_cast(subwindows.back()->widget()); - if (wellLogPlot) { - RimViewWindow* viewWindow = wellLogPlot->ownerPlotDefinition(); - viewWindow->zoomAll(); - wellLogPlot->update(); + RiuWellLogPlot* wellLogPlot = dynamic_cast(subwindows.back()->widget()); + if (wellLogPlot) + { + RimViewWindow* viewWindow = wellLogPlot->ownerPlotDefinition(); + viewWindow->zoomAll(); + wellLogPlot->update(); + + return; + } + } + + { + RiuWellAllocationPlot* wellAllocationPlot = dynamic_cast(subwindows.back()->widget()); + if (wellAllocationPlot) + { + RimWellAllocationPlot* viewWindow = wellAllocationPlot->ownerPlotDefinition(); + viewWindow->zoomAll(); + wellAllocationPlot->update(); + + return; + } } } } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp index e580d1741c..e8125b9b3a 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp @@ -491,6 +491,7 @@ QWidget* RimWellAllocationPlot::viewWidget() //-------------------------------------------------------------------------------------------------- void RimWellAllocationPlot::zoomAll() { + m_accumulatedWellFlowPlot()->zoomAll(); } //-------------------------------------------------------------------------------------------------- From da53183f417a5130450667c54f268b81a664a6ae Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 24 Mar 2017 13:28:00 +0100 Subject: [PATCH 02/28] #1360 Well Alloc plots: Description should follow the flow type setting --- .../ProjectDataModel/Flow/RimWellAllocationPlot.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp index e8125b9b3a..e7979a3c6d 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp @@ -296,7 +296,8 @@ void RimWellAllocationPlot::updateFromWell() QString wellStatusText = QString("(%1)").arg(RimWellAllocationPlot::wellStatusTextForTimeStep(m_wellName, m_case, m_timeStep)); - setDescription("Well Allocation: " + m_wellName + " " + wellStatusText + ", " + m_case->timeStepStrings()[m_timeStep] + " (" + m_case->caseUserDescription() + ")"); + QString flowTypeText = m_flowType().uiText(); + setDescription(flowTypeText + " : " + m_wellName + " " + wellStatusText + ", " + m_case->timeStepStrings()[m_timeStep] + " (" + m_case->caseUserDescription() + ")"); /// Pie chart From fcd2d9690712aeed9c427b64b598724118283ac2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 24 Mar 2017 21:34:46 +0100 Subject: [PATCH 03/28] #1359 Sort tracers in category selection list in property editor --- .../RimEclipsePropertyFilter.cpp | 28 +++++++++++++++++-- .../RimEclipsePropertyFilter.h | 1 + .../ProjectDataModel/RimPropertyFilter.cpp | 14 ++++++++++ .../ProjectDataModel/RimPropertyFilter.h | 1 + 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp index a893e1494e..66ec316074 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp @@ -279,6 +279,30 @@ bool RimEclipsePropertyFilter::isPropertyFilterControlled() return isPropertyFilterControlled; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilter::setCategoriesFromTracerNames(const std::vector& tracerNames) +{ + std::vector> tracerNameValuesSorted; + + { + std::set> tracerNameSet; + + for (size_t i = 0; i < tracerNames.size(); i++) + { + tracerNameSet.insert(std::make_pair(tracerNames[i], static_cast(i))); + } + + for (auto it : tracerNameSet) + { + tracerNameValuesSorted.push_back(it); + } + } + + setCategoryNamesAndValues(tracerNameValuesSorted); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -337,7 +361,7 @@ void RimEclipsePropertyFilter::computeResultValueRange() if ( resultDefinition->hasCategoryResult() ) { - setCategoryNames(resultDefinition->flowDiagSolution()->tracerNames()); + setCategoriesFromTracerNames(resultDefinition->flowDiagSolution()->tracerNames()); } } } @@ -423,7 +447,7 @@ void RimEclipsePropertyFilter::updateFromCurrentTimeStep() if (resultDefinition->hasCategoryResult()) { - setCategoryNames(resultDefinition->flowDiagSolution()->tracerNames()); + setCategoriesFromTracerNames(resultDefinition->flowDiagSolution()->tracerNames()); } } diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h index 955b674cd9..8cd63c1248 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h @@ -71,6 +71,7 @@ private: void updateReadOnlyStateOfAllFields(); void updateRangeLabel(); bool isPropertyFilterControlled(); + void setCategoriesFromTracerNames(const std::vector& tracerNames); RimEclipsePropertyFilterCollection* parentContainer(); diff --git a/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp index dac5f040ab..35abd2db2e 100644 --- a/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp @@ -102,6 +102,20 @@ void RimPropertyFilter::setCategoryNames(const std::vector& categoryNam } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPropertyFilter::setCategoryNamesAndValues(const std::vector>& categoryNamesAndValues) +{ + clearCategories(); + + for (auto it : categoryNamesAndValues) + { + m_categoryNames.push_back(it.first); + m_categoryValues.push_back(it.second); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimPropertyFilter.h index fc8e3ebacc..bb786eebb1 100644 --- a/ApplicationCode/ProjectDataModel/RimPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimPropertyFilter.h @@ -37,6 +37,7 @@ public: protected: void setCategoryValues(const std::vector& categoryValues); void setCategoryNames(const std::vector& categoryNames); + void setCategoryNamesAndValues(const std::vector>& categoryNamesAndValues); void clearCategories(); virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; From 7a89aee0bbdc2445c82380a13c9852ff579dfa30 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 24 Mar 2017 22:40:57 +0100 Subject: [PATCH 04/28] #1296 Multiselect in property panel lists using ctrl-click is vulnerable to mouse drag --- .../cafUserInterface/cafPdmUiListEditor.cpp | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp index b0f8af841f..4e1585b9a6 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp @@ -243,8 +243,13 @@ QWidget* PdmUiListEditor::createEditorWidget(QWidget * parent) connect(m_listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection& )), this, SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection& ))); connect(m_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(slotListItemEdited(const QModelIndex&, const QModelIndex&))); + + // Used to track key press m_listView->installEventFilter(this); + // Used to track mouse events + m_listView->viewport()->installEventFilter(this); + return m_listView; } @@ -370,9 +375,28 @@ void PdmUiListEditor::pasteFromString(const QString& content) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiListEditor::eventFilter(QObject * listView, QEvent * event) +bool PdmUiListEditor::eventFilter(QObject* object, QEvent * event) { - if (listView == m_listView && event->type() == QEvent::KeyPress) + if (object == m_listView->viewport() && event->type() == QEvent::MouseMove) + { + QMouseEvent* mouseEvent = dynamic_cast(event); + if (mouseEvent) + { + if (mouseEvent->buttons() & Qt::LeftButton + && mouseEvent->modifiers() & Qt::ControlModifier) + { + // When Ctrl button is pressed, left mouse button is pressed, and the mouse is moving, + // a possible bug in Qt is observed causing the selection to end up with single item selection + // When returning here without doing anything, system behaves as expected + + // NOTE: The mouse event is handled by the viewport() of the list view, not the list view itself + + return true; + } + } + } + + if (object == m_listView && event->type() == QEvent::KeyPress) { if (m_optionsOnly) return false; CAF_ASSERT(m_options.isEmpty()); // Not supported yet From c536b7a8fe531f42f615b79a9eccad3b9093c33a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 27 Mar 2017 11:24:51 +0200 Subject: [PATCH 05/28] #1327 Added filter field used to limit available items in the selection list --- .../RimEclipseResultDefinition.cpp | 99 ++++++++++++++++++- .../RimEclipseResultDefinition.h | 4 + 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index f0d7e7f7e0..212c5c436b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -105,6 +105,8 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() m_selectedTracersUiField.xmlCapability()->setIOReadable(false); m_selectedTracersUiField.xmlCapability()->setIOWritable(false); m_selectedTracersUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_selectedTracersUiFieldFilter, "SelectedTracersFilter", "Filter", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -202,10 +204,56 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha if ( &m_selectedTracersUiField == changedField ) { m_flowSolution = m_flowSolutionUiField(); - m_selectedTracers = m_selectedTracersUiField(); + + if (m_selectedTracersUiFieldFilter().isEmpty()) + { + m_selectedTracers = m_selectedTracersUiField(); + } + else + { + auto filteredTracerNames = tracerNamesMatchingFilter(); + + // Keep selected strings not part of currently visible selection items + std::vector newSelection; + for (auto selectedTracer : m_selectedTracers()) + { + if (std::find(begin(filteredTracerNames), end(filteredTracerNames), selectedTracer) == end(filteredTracerNames)) + { + newSelection.push_back(selectedTracer); + } + } + + for (auto selectedTracerUi : m_selectedTracersUiField()) + { + newSelection.push_back(selectedTracerUi); + } + + m_selectedTracers = newSelection; + } + loadDataAndUpdate(); } + if (&m_selectedTracersUiFieldFilter == changedField) + { + auto visibleTracerNames = tracerNamesMatchingFilter(); + + std::vector subSelection; + + // Remove hidden items from selection + for (auto selectedTracer : m_selectedTracers()) + { + if (std::find(begin(visibleTracerNames), end(visibleTracerNames), selectedTracer) != end(visibleTracerNames)) + { + subSelection.push_back(selectedTracer); + } + } + + m_selectedTracersUiField = subSelection; + + updateConnectedEditors(); + } + updateAnyFieldHasChanged(); } @@ -347,6 +395,19 @@ void RimEclipseResultDefinition::loadDataAndUpdate() } } +bool isStringMatch(const QString& filterString, const QString& value) +{ + if (filterString.isEmpty()) return true; + if (filterString.trimmed() == "*") + { + if (!value.isEmpty()) return true; + else return false; + } + + QRegExp searcher(filterString, Qt::CaseInsensitive, QRegExp::WildcardUnix); + return searcher.exactMatch(value); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -356,7 +417,6 @@ QList RimEclipseResultDefinition::calculateValueOptions( if ( fieldNeedingOptions == &m_resultTypeUiField ) { - bool hasFlowDiagFluxes = false; RimEclipseResultCase* eclResCase = dynamic_cast(m_eclipseCase.p()); if ( eclResCase && eclResCase->eclipseCaseData() ) @@ -389,7 +449,7 @@ QList RimEclipseResultDefinition::calculateValueOptions( { if ( fieldNeedingOptions == &m_resultVariableUiField ) { - options = calcOptionsForVariableUiFieldStandard(); + options = calcOptionsForVariableUiFieldStandard(); } } else @@ -419,7 +479,7 @@ QList RimEclipseResultDefinition::calculateValueOptions( RimFlowDiagSolution* flowSol = m_flowSolutionUiField(); if (flowSol) { - std::vector tracerNames = flowSol->tracerNames(); + std::vector tracerNames = tracerNamesMatchingFilter(); std::map prefixedTracerNamesMap; for ( const QString& tracerName : tracerNames ) { @@ -935,6 +995,7 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm if (m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) { + uiOrdering.add(&m_selectedTracersUiFieldFilter); uiOrdering.add(&m_selectedTracersUiField); } @@ -973,3 +1034,33 @@ void RimEclipseResultDefinition::removePerCellFaceOptionItems(QList RimEclipseResultDefinition::tracerNamesMatchingFilter() const +{ + std::vector matchingNames; + + RimFlowDiagSolution* flowSol = m_flowSolutionUiField(); + if (flowSol) + { + std::vector tracerNames = flowSol->tracerNames(); + if (m_selectedTracersUiFieldFilter().isEmpty()) + { + matchingNames = tracerNames; + } + else + { + for (const QString& tracerName : tracerNames) + { + if (isStringMatch(m_selectedTracersUiFieldFilter, tracerName)) + { + matchingNames.push_back(tracerName); + } + } + } + } + + return matchingNames; +} + diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 0f9df36fac..1a6aa67832 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -122,6 +122,8 @@ protected: caf::PdmField< caf::AppEnum< FlowTracerSelectionType > > m_flowTracerSelectionMode; caf::PdmPtrField m_flowSolutionUiField; + + caf::PdmField m_selectedTracersUiFieldFilter; caf::PdmField > m_selectedTracersUiField; @@ -136,5 +138,7 @@ private: QList calcOptionsForVariableUiFieldStandard(); QStringList getResultNamesForCurrentUiResultType(); static void removePerCellFaceOptionItems(QList& optionItems); + + std::vector tracerNamesMatchingFilter() const; }; From 60b104329c30e675bb18f48f38e092e2ae255e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 24 Mar 2017 15:07:34 +0100 Subject: [PATCH 06/28] Guard against none-existing userDescriptionField in ViewWindow --- ApplicationCode/ProjectDataModel/RimViewWindow.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimViewWindow.cpp b/ApplicationCode/ProjectDataModel/RimViewWindow.cpp index aa2941ffa3..4718b549da 100644 --- a/ApplicationCode/ProjectDataModel/RimViewWindow.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewWindow.cpp @@ -160,11 +160,14 @@ void RimViewWindow::updateMdiWindowTitle() { if ( viewWidget() ) { - caf::PdmUiFieldHandle* uiFieldHandle = this->userDescriptionField()->uiCapability(); - if ( uiFieldHandle ) + if ( this->userDescriptionField() ) { - QVariant v = uiFieldHandle->uiValue(); - viewWidget()->setWindowTitle(v.toString()); + caf::PdmUiFieldHandle* uiFieldHandle = this->userDescriptionField()->uiCapability(); + if ( uiFieldHandle ) + { + QVariant v = uiFieldHandle->uiValue(); + viewWidget()->setWindowTitle(v.toString()); + } } } } From f102befd847e569719e89cd4410fd96bb49bb65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 24 Mar 2017 15:09:10 +0100 Subject: [PATCH 07/28] Added timestep access in RimEclipseCase in preparations for #1321 --- .../ProjectDataModel/RimEclipseCase.cpp | 16 ++++++++++++++++ .../ProjectDataModel/RimEclipseCase.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index c3fe251297..2ef806de91 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -602,3 +602,19 @@ QString RimEclipseCase::timeStepName(int frameIdx) return date.toString(m_timeStepFormatString); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QDateTime RimEclipseCase::timeStepDate(int frameIdx) +{ + return results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDate(0,frameIdx); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEclipseCase::timeStepDates() +{ + return results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDates(); +} diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.h b/ApplicationCode/ProjectDataModel/RimEclipseCase.h index 4b9adc940a..bef4d9e096 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.h @@ -86,6 +86,9 @@ public: virtual std::vector views(); virtual QStringList timeStepStrings(); virtual QString timeStepName(int frameIdx); + virtual QDateTime timeStepDate(int frameIdx); + std::vector timeStepDates(); + virtual cvf::BoundingBox activeCellsBoundingBox() const; virtual cvf::BoundingBox allCellsBoundingBox() const; From 1fefc6124f27e677305cacbd91840c07b4b1520b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 24 Mar 2017 15:10:39 +0100 Subject: [PATCH 08/28] #1321 Wip: First shot on bringing the flow characteristics curves up into the open. --- .../Flow/CMakeLists_files.cmake | 2 + .../Flow/RimFlowCharacteristicsPlot.cpp | 225 ++++++++++++++++++ .../Flow/RimFlowCharacteristicsPlot.h | 82 +++++++ .../Flow/RimFlowPlotCollection.cpp | 5 + .../Flow/RimFlowPlotCollection.h | 2 + .../ReservoirDataModel/RigFlowDiagResults.cpp | 21 ++ .../ReservoirDataModel/RigFlowDiagResults.h | 19 ++ .../RigFlowDiagSolverInterface.cpp | 67 ++++-- .../RigFlowDiagSolverInterface.h | 19 +- .../UserInterface/CMakeLists_files.cmake | 3 + .../RiuFlowCharacteristicsPlot.cpp | 154 ++++++++++++ .../RiuFlowCharacteristicsPlot.h | 70 ++++++ .../UserInterface/RiuSummaryQwtPlot.h | 3 +- 13 files changed, 644 insertions(+), 28 deletions(-) create mode 100644 ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp create mode 100644 ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h create mode 100644 ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp create mode 100644 ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h diff --git a/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake index a65e9daffd..e0d6fb0abe 100644 --- a/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake @@ -11,6 +11,7 @@ ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.h ${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.h ${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.h ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.h +${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -20,6 +21,7 @@ ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.cpp ${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.cpp ${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.cpp ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.cpp +${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp new file mode 100644 index 0000000000..d19200dd67 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp @@ -0,0 +1,225 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "RimFlowCharacteristicsPlot.h" + +#include "RimFlowDiagSolution.h" +#include "RimEclipseResultCase.h" + +#include "RigFlowDiagResults.h" + +#include "RiuFlowCharacteristicsPlot.h" +#include "RimProject.h" + + +CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFlowCharacteristicsPlot::RimFlowCharacteristicsPlot() +{ + CAF_PDM_InitObject("Flow Characteristics", ":/WellAllocPie16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_case, "FlowCase", "Case", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Flow Diag Solution", "", "", ""); + + this->m_showWindow = false; + setAsPlotMdiWindow(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFlowCharacteristicsPlot::~RimFlowCharacteristicsPlot() +{ + removeMdiWindowFromMdiArea(); + + deleteViewWidget(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::setFromFlowSolution(RimFlowDiagSolution* flowSolution) +{ + if ( !flowSolution ) + { + m_case = nullptr; + } + else + { + RimEclipseResultCase* eclCase; + flowSolution->firstAncestorOrThisOfType(eclCase); + m_case = eclCase; + } + + m_flowDiagSolution = flowSolution; + + loadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::deleteViewWidget() +{ + if (m_flowCharPlotWidget) + { + m_flowCharPlotWidget->deleteLater(); + m_flowCharPlotWidget= nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimFlowCharacteristicsPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if ( fieldNeedingOptions == &m_case ) + { + RimProject* proj = nullptr; + this->firstAncestorOrThisOfType(proj); + if ( proj ) + { + std::vector cases; + proj->descendantsIncludingThisOfType(cases); + + for ( RimEclipseResultCase* c : cases ) + { + options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIcon())); + } + } + } + else if ( fieldNeedingOptions == &m_flowDiagSolution ) + { + if ( m_case ) + { + std::vector flowSols = m_case->flowDiagSolutions(); + + for ( RimFlowDiagSolution* flowSol : flowSols ) + { + options.push_back(caf::PdmOptionItemInfo("None", nullptr)); + options.push_back(caf::PdmOptionItemInfo(flowSol->userDescription(), flowSol, false, flowSol->uiIcon())); + } + } + } + + return options; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* RimFlowCharacteristicsPlot::viewWidget() +{ + return m_flowCharPlotWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::zoomAll() +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue); + + if ( &m_case == changedField + || &m_flowDiagSolution == changedField) + { + this->loadDataAndUpdate(); + } + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QImage RimFlowCharacteristicsPlot::snapshotWindowContent() +{ + QImage image; + + if (m_flowCharPlotWidget) + { + QPixmap pix = QPixmap::grabWidget(m_flowCharPlotWidget); + image = pix.toImage(); + } + + return image; +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::loadDataAndUpdate() +{ + updateMdiWindowVisibility(); + + if (m_flowDiagSolution) + { + RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); + std::vector calculatedTimesteps = flowResult->calculatedTimeSteps(); + + std::vector timeStepDates = m_case->timeStepDates(); + std::vector lorenzVals(timeStepDates.size(), HUGE_VAL); + + for (int timeStepIdx: calculatedTimesteps) + { + lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx).m_lorenzCoefficient; + + if ( m_flowCharPlotWidget) + { + const auto & flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx); + m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx], + flowCharResults.m_flowCapStorageCapCurve.first, + flowCharResults.m_flowCapStorageCapCurve.second); + m_flowCharPlotWidget->addSweepEfficiencyCurve(timeStepDates[timeStepIdx], + flowCharResults.m_sweepEfficiencyCurve.first, + flowCharResults.m_sweepEfficiencyCurve.second); + } + } + + if ( m_flowCharPlotWidget) m_flowCharPlotWidget->setLorenzCurve(timeStepDates, lorenzVals); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* RimFlowCharacteristicsPlot::createViewWidget(QWidget* mainWindowParent) +{ + m_flowCharPlotWidget = new RiuFlowCharacteristicsPlot(this, mainWindowParent); + return m_flowCharPlotWidget; +} + + diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h new file mode 100644 index 0000000000..5eb58b0ead --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "RimViewWindow.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include + +class RimFlowDiagSolution; +class RimEclipseResultCase; + +class RiuFlowCharacteristicsPlot; + +namespace caf { + class PdmOptionItemInfo; +} + +namespace cvf { + class Color3f; +} + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimFlowCharacteristicsPlot : public RimViewWindow +{ + CAF_PDM_HEADER_INIT; + +public: + RimFlowCharacteristicsPlot(); + virtual ~RimFlowCharacteristicsPlot(); + + void setFromFlowSolution(RimFlowDiagSolution* flowSolution); + + // RimViewWindow overrides + + virtual QWidget* viewWidget() override; + virtual void zoomAll() override; + virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; + virtual void deleteViewWidget() override; + + + +protected: + // RimViewWindow overrides + + virtual void loadDataAndUpdate() override; + virtual QImage snapshotWindowContent() override; + + // Overridden PDM methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + +private: + caf::PdmPtrField m_case; + caf::PdmPtrField m_flowDiagSolution; + + QPointer m_flowCharPlotWidget; +}; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp index 1f29ada313..0f0cacda1e 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp @@ -19,6 +19,7 @@ #include "RimFlowPlotCollection.h" #include "RimWellAllocationPlot.h" +#include "RimFlowCharacteristicsPlot.h" #include "cvfAssert.h" @@ -33,6 +34,10 @@ RimFlowPlotCollection::RimFlowPlotCollection() { CAF_PDM_InitObject("Flow Diagnostics Plots", ":/WellAllocPlots16x16.png", "", ""); + CAF_PDM_InitFieldNoDefault(&m_flowCharacteristicsPlot, "FlowCharacteristicsPlot", "", "", "", ""); + m_flowCharacteristicsPlot.uiCapability()->setUiHidden(true); + m_flowCharacteristicsPlot = new RimFlowCharacteristicsPlot; + CAF_PDM_InitFieldNoDefault(&m_defaultPlot, "DefaultFlowPlot", "", "", "", ""); m_defaultPlot.uiCapability()->setUiHidden(true); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h index e48ab29229..0868fcddd0 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h @@ -23,6 +23,7 @@ #include "cafPdmChildField.h" class RimWellAllocationPlot; +class RimFlowCharacteristicsPlot; //================================================================================================== /// @@ -43,6 +44,7 @@ public: RimWellAllocationPlot* defaultPlot(); private: + caf::PdmChildField m_flowCharacteristicsPlot; caf::PdmChildField m_defaultPlot; caf::PdmChildArrayField m_flowPlots; }; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp index 7481e14b50..5db6725bd1 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp @@ -39,6 +39,7 @@ RigFlowDiagResults::RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t m_timeStepCount = timeStepCount; m_hasAtemptedNativeResults.resize(timeStepCount, false); m_injProdPairFluxCommunicationTimesteps.resize(timeStepCount); + m_flowCharResultFrames.resize(timeStepCount); } //-------------------------------------------------------------------------------------------------- @@ -118,6 +119,12 @@ void RigFlowDiagResults::calculateNativeResultsIfNotPreviouslyAttempted(size_t f m_injProdPairFluxCommunicationTimesteps[frameIndex].swap(nativeTimestepResults.injProdWellPairFluxes()); + m_flowCharResultFrames[frameIndex].m_lorenzCoefficient = nativeTimestepResults.lorenzCoefficient(); + m_flowCharResultFrames[frameIndex].m_flowCapStorageCapCurve.first.swap(nativeTimestepResults.flowCapStorageCapCurve().first); + m_flowCharResultFrames[frameIndex].m_flowCapStorageCapCurve.second.swap(nativeTimestepResults.flowCapStorageCapCurve().second); + m_flowCharResultFrames[frameIndex].m_sweepEfficiencyCurve.first.swap(nativeTimestepResults.sweepEfficiencyCurve().first); + m_flowCharResultFrames[frameIndex].m_sweepEfficiencyCurve.second.swap(nativeTimestepResults.sweepEfficiencyCurve().second); + m_hasAtemptedNativeResults[frameIndex] = true; } } @@ -652,3 +659,17 @@ double RigFlowDiagResults::maxAbsPairFlux(int frameIndex) return maxFlux; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigFlowDiagResults::calculatedTimeSteps() +{ + std::vector timestepIndices; + for (size_t tsIdx = 0; tsIdx < m_timeStepCount; ++tsIdx) + { + if (m_hasAtemptedNativeResults[tsIdx]) timestepIndices.push_back(static_cast(tsIdx)); + } + + return timestepIndices; +} diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h index 25a3662935..236e0616a3 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h @@ -62,6 +62,21 @@ public: std::pair injectorProducerPairFluxes(const std::string& injTracername, const std::string& prodTracerName, int frameIndex); double maxAbsPairFlux(int frameIndex); + std::vector calculatedTimeSteps(); + + struct FlowCharacteristicsResultFrame + { + FlowCharacteristicsResultFrame() : m_lorenzCoefficient(HUGE_VAL) {} + + using Curve = std::pair< std::vector, std::vector >; + + Curve m_flowCapStorageCapCurve; + Curve m_sweepEfficiencyCurve; + double m_lorenzCoefficient; + }; + + const FlowCharacteristicsResultFrame& flowCharacteristicsResults(int frameIndex) { return m_flowCharResultFrames[frameIndex];} + private: const std::vector* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); void calculateNativeResultsIfNotPreviouslyAttempted(size_t frameIndex); @@ -118,6 +133,10 @@ private: using InjectorProducerCommunicationMap = std::map< std::pair, std::pair >; std::vector m_injProdPairFluxCommunicationTimesteps; + + + std::vector m_flowCharResultFrames; + }; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp index fbe9812cf2..9fd5b6dfa1 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp @@ -39,7 +39,7 @@ /// //-------------------------------------------------------------------------------------------------- RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount) - : m_activeCellCount(activeCellCount) + : m_activeCellCount(activeCellCount), m_lorenzCoefficient(HUGE_VAL) { } @@ -107,12 +107,16 @@ void RigFlowDiagTimeStepResult::addResult(const RigFlowDiagResultAddress& resAdd class RigOpmFldStaticData : public cvf::Object { public: - RigOpmFldStaticData(const std::string& grid, const std::string& init) : eclGraph(Opm::ECLGraph::load(grid, init)), m_hasUnifiedRestartFile(false) {} + RigOpmFldStaticData(const std::string& grid, const std::string& init) : m_eclGraph(Opm::ECLGraph::load(grid, init)), m_hasUnifiedRestartFile(false) + { + m_poreVolume = m_eclGraph.poreVolume(); + } - Opm::ECLGraph eclGraph; - std::unique_ptr fldToolbox; - bool m_hasUnifiedRestartFile; - QStringList restartFileNames; + Opm::ECLGraph m_eclGraph; + std::vector m_poreVolume; + std::unique_ptr m_fldToolbox; + bool m_hasUnifiedRestartFile; + QStringList m_restartFileNames; }; @@ -168,31 +172,31 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI progressInfo.setProgressDescription("Calculating Connectivities"); const Opm::FlowDiagnostics::ConnectivityGraph connGraph = - Opm::FlowDiagnostics::ConnectivityGraph{ static_cast(m_opmFldData->eclGraph.numCells()), - m_opmFldData->eclGraph.neighbours() }; + Opm::FlowDiagnostics::ConnectivityGraph{ static_cast(m_opmFldData->m_eclGraph.numCells()), + m_opmFldData->m_eclGraph.neighbours() }; progressInfo.incrementProgress(); progressInfo.setProgressDescription("Initialize Solver"); // Create the Toolbox. - m_opmFldData->fldToolbox.reset(new Opm::FlowDiagnostics::Toolbox{ connGraph }); - m_opmFldData->fldToolbox->assignPoreVolume( m_opmFldData->eclGraph.poreVolume()); + m_opmFldData->m_fldToolbox.reset(new Opm::FlowDiagnostics::Toolbox{ connGraph }); + m_opmFldData->m_fldToolbox->assignPoreVolume( m_opmFldData->m_poreVolume); // Look for unified restart file QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE); if ( !restartFileName.isEmpty() ) { - m_opmFldData->eclGraph.assignFluxDataSource(restartFileName.toStdString()); + m_opmFldData->m_eclGraph.assignFluxDataSource(restartFileName.toStdString()); m_opmFldData->m_hasUnifiedRestartFile = true; } else { - m_opmFldData->restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE); + m_opmFldData->m_restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE); - size_t restartFileCount = static_cast(m_opmFldData->restartFileNames.size()); + size_t restartFileCount = static_cast(m_opmFldData->m_restartFileNames.size()); size_t maxTimeStepCount = m_eclipseCase->eclipseCaseData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount(); if (restartFileCount <= timeStepIndex && restartFileCount != maxTimeStepCount ) @@ -201,7 +205,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI return result; } - m_opmFldData->restartFileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file. + m_opmFldData->m_restartFileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file. m_opmFldData->m_hasUnifiedRestartFile = false; } } @@ -211,8 +215,8 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI if ( ! m_opmFldData->m_hasUnifiedRestartFile ) { - QString restartFileName = m_opmFldData->restartFileNames[static_cast(timeStepIndex)]; - m_opmFldData->eclGraph.assignFluxDataSource(restartFileName.toStdString()); + QString restartFileName = m_opmFldData->m_restartFileNames[static_cast(timeStepIndex)]; + m_opmFldData->m_eclGraph.assignFluxDataSource(restartFileName.toStdString()); } size_t resultIndexWithMaxTimeSteps = cvf::UNDEFINED_SIZE_T; @@ -220,7 +224,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI int reportStepNumber = m_eclipseCase->eclipseCaseData()->results(RifReaderInterface::MATRIX_RESULTS)->reportStepNumber(resultIndexWithMaxTimeSteps, timeStepIndex); - if ( ! m_opmFldData->eclGraph.selectReportStep(reportStepNumber) ) + if ( ! m_opmFldData->m_eclGraph.selectReportStep(reportStepNumber) ) { QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: Could not find the requested timestep in the result file. Results will not be loaded."); return result; @@ -231,20 +235,20 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI Opm::FlowDiagnostics::CellSetValues sumWellFluxPrCell; { - Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::extractFluxField(m_opmFldData->eclGraph, false); + Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::extractFluxField(m_opmFldData->m_eclGraph, false); - m_opmFldData->fldToolbox->assignConnectionFlux(connectionsVals); + m_opmFldData->m_fldToolbox->assignConnectionFlux(connectionsVals); progressInfo.incrementProgress(); Opm::ECLWellSolution wsol = Opm::ECLWellSolution{-1.0 , false}; const std::vector well_fluxes = - wsol.solution(m_opmFldData->eclGraph.rawResultData(), m_opmFldData->eclGraph.numGrids()); + wsol.solution(m_opmFldData->m_eclGraph.rawResultData(), m_opmFldData->m_eclGraph.numGrids()); - sumWellFluxPrCell = RigFlowDiagInterfaceTools::extractWellFlows(m_opmFldData->eclGraph, well_fluxes); + sumWellFluxPrCell = RigFlowDiagInterfaceTools::extractWellFlows(m_opmFldData->m_eclGraph, well_fluxes); - m_opmFldData->fldToolbox->assignInflowFlux(sumWellFluxPrCell); + m_opmFldData->m_fldToolbox->assignInflowFlux(sumWellFluxPrCell); // Filter connection cells with inconsistent well in flow direction (Hack, we should do something better) @@ -295,7 +299,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI std::unique_ptr injectorSolution; try { - injectorSolution.reset(new Toolbox::Forward( m_opmFldData->fldToolbox->computeInjectionDiagnostics(injectorCellSets))); + injectorSolution.reset(new Toolbox::Forward( m_opmFldData->m_fldToolbox->computeInjectionDiagnostics(injectorCellSets))); } catch (const std::exception& e) { @@ -325,7 +329,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI std::unique_ptr producerSolution; try { - producerSolution.reset(new Toolbox::Reverse(m_opmFldData->fldToolbox->computeProductionDiagnostics(prodjCellSets))); + producerSolution.reset(new Toolbox::Reverse(m_opmFldData->m_fldToolbox->computeProductionDiagnostics(prodjCellSets))); } catch ( const std::exception& e ) { @@ -366,6 +370,21 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI } } } + + try + { + Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*(injectorSolution.get()), + *(producerSolution.get()), + m_opmFldData->m_poreVolume); + + result.setFlowCapStorageCapCurve(flowCapStorCapCurve); + result.setSweepEfficiencyCurve(sweepEfficiency(flowCapStorCapCurve)); + result.setLorenzCoefficient(lorenzCoefficient(flowCapStorCapCurve)); + } + catch ( const std::exception& e ) + { + QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: " + QString(e.what())); + } } return result; // Relying on implicit move constructor diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h index 8623e3575f..653d9e54d2 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h @@ -41,17 +41,30 @@ public: const std::string& producerTracerName, const std::pair& injProdFluxes) ; - // Use to "steal" the data from this one using swap - std::map >& nativeResults() { return m_nativeResults; } + using Curve = std::pair< std::vector, std::vector >; + void setFlowCapStorageCapCurve(const Curve& flCapStCapCurve) { m_flowCapStorageCapCurve = flCapStCapCurve;} + void setSweepEfficiencyCurve(const Curve& sweepEffCurve) { m_sweepEfficiencyCurve = sweepEffCurve; } + void setLorenzCoefficient(double coeff) { m_lorenzCoefficient = coeff;} + + // Used to "steal" the data from this one using swap + std::map >& nativeResults() { return m_nativeResults; } std::map, std::pair > & injProdWellPairFluxes() { return m_injProdWellPairFluxes; } + Curve& flowCapStorageCapCurve() { return m_flowCapStorageCapCurve; } + Curve& sweepEfficiencyCurve() { return m_sweepEfficiencyCurve; } + double lorenzCoefficient() { return m_lorenzCoefficient;} + private: void addResult(const RigFlowDiagResultAddress& resAddr, const std::map& cellValues); - std::map > m_nativeResults; + std::map > m_nativeResults; std::map, std::pair > m_injProdWellPairFluxes; + Curve m_flowCapStorageCapCurve; + Curve m_sweepEfficiencyCurve; + double m_lorenzCoefficient; + size_t m_activeCellCount; }; diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index 1579fb480b..501cb99546 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -39,6 +39,7 @@ ${CEE_CURRENT_LIST_DIR}RiuGeoMechXfTensorResultAccessor.h ${CEE_CURRENT_LIST_DIR}RiuFemTimeHistoryResultAccessor.h ${CEE_CURRENT_LIST_DIR}RiuExportMultipleSnapshotsWidget.h ${CEE_CURRENT_LIST_DIR}RiuWellAllocationPlot.h +${CEE_CURRENT_LIST_DIR}RiuFlowCharacteristicsPlot.h ${CEE_CURRENT_LIST_DIR}RiuNightchartsWidget.h ${CEE_CURRENT_LIST_DIR}RiuMessagePanel.h ) @@ -78,6 +79,7 @@ ${CEE_CURRENT_LIST_DIR}RiuGeoMechXfTensorResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RiuFemTimeHistoryResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RiuExportMultipleSnapshotsWidget.cpp ${CEE_CURRENT_LIST_DIR}RiuWellAllocationPlot.cpp +${CEE_CURRENT_LIST_DIR}RiuFlowCharacteristicsPlot.cpp ${CEE_CURRENT_LIST_DIR}RiuNightchartsWidget.cpp ${CEE_CURRENT_LIST_DIR}RiuMessagePanel.cpp ) @@ -107,6 +109,7 @@ ${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h ${CEE_CURRENT_LIST_DIR}RiuExportMultipleSnapshotsWidget.h ${CEE_CURRENT_LIST_DIR}RiuWellAllocationPlot.h +${CEE_CURRENT_LIST_DIR}RiuFlowCharacteristicsPlot.h ${CEE_CURRENT_LIST_DIR}RiuNightchartsWidget.h ${CEE_CURRENT_LIST_DIR}RiuMessagePanel.h ) diff --git a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp new file mode 100644 index 0000000000..ac8a0d2107 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp @@ -0,0 +1,154 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "RiuFlowCharacteristicsPlot.h" +#include "RimFlowCharacteristicsPlot.h" +#include "RiuResultQwtPlot.h" + +#include "qwt_plot.h" +#include "cvfBase.h" +#include "cvfColor3.h" + +#include +#include +#include +#include +#include "RiuLineSegmentQwtPlotCurve.h" +#include + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuFlowCharacteristicsPlot::RiuFlowCharacteristicsPlot(RimFlowCharacteristicsPlot* plotDefinition, QWidget* parent) + : m_plotDefinition(plotDefinition), + QFrame(parent) +{ + Q_ASSERT(m_plotDefinition); + + QVBoxLayout* mainLayout = new QVBoxLayout(); + this->setLayout(mainLayout); + this->layout()->setMargin(0); + this->layout()->setSpacing(2); + + // White background + QPalette pal = this->palette(); + pal.setColor(QPalette::Background, Qt::white); + this->setAutoFillBackground(true); + this->setPalette(pal); + + m_lorenzPlot = new RiuResultQwtPlot(this); + m_flowCapVsStorageCapPlot = new RiuResultQwtPlot(this); + m_sweepEffPlot = new RiuResultQwtPlot(this); + mainLayout->addWidget(m_lorenzPlot); + mainLayout->addWidget(m_flowCapVsStorageCapPlot); + mainLayout->addWidget(m_sweepEffPlot); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuFlowCharacteristicsPlot::~RiuFlowCharacteristicsPlot() +{ + if (m_plotDefinition) + { + m_plotDefinition->handleMdiWindowClosed(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::setLorenzCurve(const std::vector& dateTimes, const std::vector& timeHistoryValues) +{ + m_lorenzPlot->deleteAllCurves(); + m_lorenzPlot->addCurve("Lorenz Coefficient", cvf::Color3f::BLUE, dateTimes, timeHistoryValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::addFlowCapStorageCapCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals) +{ + RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve(dateTime.toString()); + plotCurve->setSamplesFromTimeAndValues(xVals, yVals, false); + plotCurve->setTitle(dateTime.toString()); + + plotCurve->setPen(QPen(QColor(180, 0, 20))); + + plotCurve->attach(m_flowCapVsStorageCapPlot); + + m_flowCapVsStorageCapPlot->setAxisScale( QwtPlot::xBottom, 0.0, 1.0); + + m_flowCapVsStorageCapPlot->replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::addSweepEfficiencyCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals) +{ + RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve(dateTime.toString()); + plotCurve->setSamplesFromTimeAndValues(xVals, yVals, false); + plotCurve->setTitle(dateTime.toString()); + + plotCurve->setPen(QPen(QColor(180, 0, 20))); + + plotCurve->attach(m_sweepEffPlot); + + //m_sweepEffPlot->setAxisScale( QwtPlot::xBottom, 0.0, 1.0); + + m_sweepEffPlot->replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFlowCharacteristicsPlot* RiuFlowCharacteristicsPlot::ownerPlotDefinition() +{ + return m_plotDefinition; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize RiuFlowCharacteristicsPlot::minimumSizeHint() const +{ + return QSize(0, 100); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize RiuFlowCharacteristicsPlot::sizeHint() const +{ + return QSize(0, 0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::setDefaults() +{ + +} + diff --git a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h new file mode 100644 index 0000000000..6de6647d1f --- /dev/null +++ b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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_plot.h" + +#include "cafPdmPointer.h" + +#include +#include + +class RimFlowCharacteristicsPlot; +class RiuNightchartsWidget; +class RiuResultQwtPlot; + +class QLabel; + +namespace cvf { + class Color3f; +} + +//================================================================================================== +// +// +// +//================================================================================================== +class RiuFlowCharacteristicsPlot : public QFrame +{ + Q_OBJECT; +public: + RiuFlowCharacteristicsPlot(RimFlowCharacteristicsPlot* plotDefinition, QWidget* parent = NULL); + virtual ~RiuFlowCharacteristicsPlot(); + + void setLorenzCurve(const std::vector& dateTimes, const std::vector& timeHistoryValues); + void addFlowCapStorageCapCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals); + void addSweepEfficiencyCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals); + + RimFlowCharacteristicsPlot* ownerPlotDefinition(); + +protected: + virtual QSize sizeHint() const override; + virtual QSize minimumSizeHint() const override; + +private: + void setDefaults(); + +private: + caf::PdmPointer m_plotDefinition; + QPointer m_lorenzPlot; + QPointer m_flowCapVsStorageCapPlot; + QPointer m_sweepEffPlot; + +}; + diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index d6a9058195..7ccde7dbef 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -63,7 +63,8 @@ protected: virtual QSize sizeHint() const override; virtual QSize minimumSizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; + virtual void contextMenuEvent(QContextMenuEvent *) override; + private: friend class RiuQwtPlotPicker; QPointF closestCurvePoint(const QPoint& pos, QString* valueString, QString* timeString, int* yAxis) const; From 76019109f6607077e8b968cdd26c0651831e3142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 24 Mar 2017 15:16:05 +0100 Subject: [PATCH 09/28] Cr Lf cleanup --- ApplicationCode/UserInterface/RiuWellLogTrack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index 9338791a23..0c44ff8c0b 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -48,7 +48,7 @@ public: void setDepthZoom(double minDepth, double maxDepth); void setDepthTitle(const QString& title); void setXTitle(const QString& title); - + void setXRange(double min, double max); bool isRimTrackVisible(); From ef8a98d4e1172fa8580903f9cfc1944d31031f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 24 Mar 2017 17:16:47 +0100 Subject: [PATCH 10/28] #1321 Wip: Refactoring plot marker to be used more generally. Eg Flow Characteristics plots --- .../UserInterface/RiuSummaryQwtPlot.cpp | 292 ++++++++++-------- .../UserInterface/RiuSummaryQwtPlot.h | 5 +- 2 files changed, 162 insertions(+), 135 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index 34b559d55d..6d5529ea8d 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -55,9 +55,31 @@ class RiuQwtPlotPicker : public QwtPlotPicker { public: - explicit RiuQwtPlotPicker(QWidget *canvas) - : QwtPlotPicker(canvas) + explicit RiuQwtPlotPicker(QwtPlot* plot, bool isMainAxisHorizontal) + : QwtPlotPicker(plot->canvas()), m_plot(plot), m_isMainAxisHorizontal(isMainAxisHorizontal) { + this->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); + } + + ~RiuQwtPlotPicker() + { + m_plotMarker->detach(); + delete m_plotMarker; + } + + void removeMarker() + { + if (m_plotMarker->plot()) + { + m_plotMarker->detach(); + + m_plot->replot(); + } } protected: @@ -68,31 +90,154 @@ protected: { QwtText txt; - const RiuSummaryQwtPlot* sumPlot = dynamic_cast(this->plot()); - if (sumPlot) + if (m_plot) { - int closestYAxis = QwtPlot::yLeft; - QString timeString; - QString valueString; - QPointF closestPoint = sumPlot->closestCurvePoint(pos, &valueString, &timeString, &closestYAxis); + QwtPlot::Axis relatedYAxis = QwtPlot::yLeft; + QwtPlot::Axis relatedXAxis = QwtPlot::xBottom; + + QString mainAxisValueString; + QString valueAxisValueString; + QPointF closestPoint = closestCurvePoint(pos, &valueAxisValueString, &mainAxisValueString, &relatedXAxis, &relatedYAxis); if (!closestPoint.isNull()) { - QString str = valueString; + QString str = valueAxisValueString; - if (!timeString.isEmpty()) + if (!mainAxisValueString.isEmpty()) { - str += QString(" (%1)").arg(timeString); + str += QString(" (%1)").arg(mainAxisValueString); } txt.setText(str); } - RiuSummaryQwtPlot* nonConstPlot = const_cast(sumPlot); - nonConstPlot->updateClosestCurvePointMarker(closestPoint, closestYAxis); + updateClosestCurvePointMarker(closestPoint, relatedXAxis, relatedYAxis); } return txt; } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + QPointF closestCurvePoint(const QPoint& cursorPosition, QString* valueAxisValueString, QString* mainAxisValueString, QwtPlot::Axis* relatedXAxis, QwtPlot::Axis* relatedYAxis) const + { + QPointF samplePoint; + + QwtPlotCurve* closestCurve = nullptr; + double distMin = DBL_MAX; + int closestPointSampleIndex = -1; + + const QwtPlotItemList& itmList = m_plot->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(cursorPosition, &dist); + if (dist < distMin) + { + closestCurve = candidateCurve; + distMin = dist; + closestPointSampleIndex = candidateSampleIndex; + } + } + } + + if (closestCurve && distMin < 50) + { + samplePoint = closestCurve->sample(closestPointSampleIndex); + + if (relatedXAxis) *relatedXAxis = static_cast( closestCurve->xAxis()); + if (relatedYAxis) *relatedYAxis = static_cast( closestCurve->yAxis()); + } + + + if (mainAxisValueString) + { + const QwtScaleDraw* mainAxisScaleDraw = m_isMainAxisHorizontal ? m_plot->axisScaleDraw(*relatedXAxis): m_plot->axisScaleDraw(*relatedYAxis); + auto dateScaleDraw = dynamic_cast(mainAxisScaleDraw) ; + + qreal mainAxisSampleVal = 0.0; + if (m_isMainAxisHorizontal) + mainAxisSampleVal = samplePoint.x(); + else + mainAxisSampleVal = samplePoint.y(); + + if (dateScaleDraw) + { + QDateTime date = dateScaleDraw->toDateTime(mainAxisSampleVal); + *mainAxisValueString = date.toString("hh:mm dd.MMMM.yyyy"); + } + else if (mainAxisScaleDraw) + { + *mainAxisValueString = mainAxisScaleDraw->label(mainAxisSampleVal).text(); + } + } + + if (valueAxisValueString && closestCurve) + { + const QwtScaleDraw* valueAxisScaleDraw = m_isMainAxisHorizontal ? m_plot->axisScaleDraw(*relatedYAxis): m_plot->axisScaleDraw(*relatedXAxis); + + qreal valueAxisSampleVal = 0.0; + if (m_isMainAxisHorizontal) + valueAxisSampleVal = samplePoint.x(); + else + valueAxisSampleVal = samplePoint.y(); + + if (valueAxisScaleDraw) + { + *valueAxisValueString = valueAxisScaleDraw->label(valueAxisSampleVal).text(); + } + } + + return samplePoint; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void updateClosestCurvePointMarker(const QPointF& closestPoint, QwtPlot::Axis relatedXAxis, QwtPlot::Axis relatedYAxis) const + { + bool replotRequired = false; + + if (!closestPoint.isNull()) + { + if (!m_plotMarker->plot()) + { + m_plotMarker->attach(m_plot); + + replotRequired = true; + } + + if (m_plotMarker->value() != closestPoint) + { + m_plotMarker->setValue(closestPoint.x(), closestPoint.y()); + + // Set the axes that the marker realtes to, to make the positioning correct + m_plotMarker->setAxes(relatedXAxis, relatedYAxis); + + // TODO : Should use a color or other visual indicator to show what axis the curve relates to + + replotRequired = true; + } + } + else + { + if (m_plotMarker->plot()) + { + m_plotMarker->detach(); + + replotRequired = true; + } + } + + if (replotRequired) m_plot->replot(); + } + + QPointer m_plot; + QwtPlotMarker* m_plotMarker; + bool m_isMainAxisHorizontal; }; @@ -134,14 +279,8 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* pa connect(scalePicker, SIGNAL(clicked(int, double)), this, SLOT(onAxisClicked(int, double))); // Create a plot picker to display values next to mouse cursor - m_plotPicker = new RiuQwtPlotPicker(this->canvas()); - m_plotPicker->setTrackerMode(QwtPicker::AlwaysOn); + m_plotPicker = new RiuQwtPlotPicker(this, true); - 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); } //-------------------------------------------------------------------------------------------------- @@ -158,8 +297,6 @@ RiuSummaryQwtPlot::~RiuSummaryQwtPlot() m_plotDefinition->handleMdiWindowClosed(); } - m_plotMarker->detach(); - delete m_plotMarker; } //-------------------------------------------------------------------------------------------------- @@ -242,110 +379,6 @@ QSize RiuSummaryQwtPlot::sizeHint() const return QSize(0, 0); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QPointF RiuSummaryQwtPlot::closestCurvePoint(const QPoint& cursorPosition, QString* valueString, QString* timeString, int* yAxis) 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(cursorPosition, &dist); - if (dist < distMin) - { - closestCurve = candidateCurve; - distMin = dist; - closestPointSampleIndex = candidateSampleIndex; - } - } - } - - if (closestCurve && distMin < 50) - { - samplePoint = closestCurve->sample(closestPointSampleIndex); - - if (yAxis) *yAxis = closestCurve->yAxis(); - } - - - if (timeString) - { - const QwtScaleDraw* timeAxisScaleDraw = axisScaleDraw(QwtPlot::xBottom); - auto dateScaleDraw = dynamic_cast(timeAxisScaleDraw) ; - - if (dateScaleDraw) - { - QDateTime date = dateScaleDraw->toDateTime(samplePoint.x()); - *timeString = date.toString("hh:mm dd.MMMM.yyyy"); - } - else if (timeAxisScaleDraw) - { - *timeString = timeAxisScaleDraw->label(samplePoint.x()).text(); - } - } - - if (valueString && closestCurve) - { - const QwtScaleDraw* yAxisScaleDraw = axisScaleDraw(closestCurve->yAxis()); - if (yAxisScaleDraw) - { - *valueString = yAxisScaleDraw->label(samplePoint.y()).text(); - } - } - - return samplePoint; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuSummaryQwtPlot::updateClosestCurvePointMarker(const QPointF& closestPoint, int yAxis) -{ - bool replotRequired = false; - - if (!closestPoint.isNull()) - { - if (!m_plotMarker->plot()) - { - m_plotMarker->attach(this); - - replotRequired = true; - } - - if (m_plotMarker->value() != closestPoint) - { - m_plotMarker->setValue(closestPoint.x(), closestPoint.y()); - - // Set y-axis to be able to support more than one y-axis. Default y-axis is left axis. - // TODO : Should use a color or other visual indicator to show what axis the curve relates to - m_plotMarker->setYAxis(yAxis); - - replotRequired = true; - } - } - else - { - if (m_plotMarker->plot()) - { - m_plotMarker->detach(); - - replotRequired = true; - } - } - - if (replotRequired) this->replot(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -453,12 +486,7 @@ bool RiuSummaryQwtPlot::eventFilter(QObject* watched, QEvent* event) //-------------------------------------------------------------------------------------------------- void RiuSummaryQwtPlot::leaveEvent(QEvent *) { - if (m_plotMarker->plot()) - { - m_plotMarker->detach(); - - replot(); - } + m_plotPicker->removeMarker(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index 7ccde7dbef..4882a04181 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -30,6 +30,7 @@ class QwtInterval; class QwtPicker; class QwtPlotMarker; +class RiuQwtPlotPicker; class RimSummaryPlot; //================================================================================================== @@ -72,7 +73,6 @@ private: void setDefaults(); void selectClosestCurve(const QPoint& pos); - void showToolTip(const QPoint& pos); private slots: void onZoomedSlot( ); @@ -80,8 +80,7 @@ private slots: private: QwtPlotGrid* m_grid; - QwtPicker* m_plotPicker; - QwtPlotMarker* m_plotMarker; + RiuQwtPlotPicker* m_plotPicker; caf::PdmPointer m_plotDefinition; From ba1dfee4e6f2265a9452fbae77b96d7f32e99d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 27 Mar 2017 10:38:26 +0200 Subject: [PATCH 11/28] #1321 Finalized plot marker refactoring --- .../UserInterface/CMakeLists_files.cmake | 2 + .../UserInterface/RiuQwtCurvePointTracker.cpp | 213 ++++++++++++++++++ .../UserInterface/RiuQwtCurvePointTracker.h | 47 ++++ .../UserInterface/RiuSummaryQwtPlot.cpp | 205 +---------------- .../UserInterface/RiuSummaryQwtPlot.h | 7 +- 5 files changed, 269 insertions(+), 205 deletions(-) create mode 100644 ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp create mode 100644 ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index 501cb99546..7f5299f69f 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -20,6 +20,7 @@ ${CEE_CURRENT_LIST_DIR}RiuProcessMonitor.h ${CEE_CURRENT_LIST_DIR}RiuProjectPropertyView.h ${CEE_CURRENT_LIST_DIR}RiuPropertyViewTabWidget.h ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h +${CEE_CURRENT_LIST_DIR}RiuQwtCurvePointTracker.h ${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.h ${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.h ${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.h @@ -60,6 +61,7 @@ ${CEE_CURRENT_LIST_DIR}RiuProcessMonitor.cpp ${CEE_CURRENT_LIST_DIR}RiuProjectPropertyView.cpp ${CEE_CURRENT_LIST_DIR}RiuPropertyViewTabWidget.cpp ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.cpp +${CEE_CURRENT_LIST_DIR}RiuQwtCurvePointTracker.cpp ${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.cpp ${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.cpp ${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.cpp diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp new file mode 100644 index 0000000000..7786f4599e --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp @@ -0,0 +1,213 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017- Statoil 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 "RiuQwtCurvePointTracker.h" + +#include "qwt_plot_marker.h" +#include "qwt_symbol.h" + +#include "qwt_plot_curve.h" +#include "qwt_date_scale_draw.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtCurvePointTracker::RiuQwtCurvePointTracker(QwtPlot* plot, bool isMainAxisHorizontal): QwtPlotPicker(plot->canvas()), m_plot(plot), m_isMainAxisHorizontal(isMainAxisHorizontal) +{ + this->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); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtCurvePointTracker::~RiuQwtCurvePointTracker() +{ + m_plotMarker->detach(); + delete m_plotMarker; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtCurvePointTracker::removeMarkerOnFocusLeave() +{ + if ( m_plotMarker->plot() ) + { + m_plotMarker->detach(); + + m_plot->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtText RiuQwtCurvePointTracker::trackerText(const QPoint& pos) const +{ + QwtText txt; + + if ( m_plot ) + { + QwtPlot::Axis relatedYAxis = QwtPlot::yLeft; + QwtPlot::Axis relatedXAxis = QwtPlot::xBottom; + + QString mainAxisValueString; + QString valueAxisValueString; + QPointF closestPoint = closestCurvePoint(pos, &valueAxisValueString, &mainAxisValueString, &relatedXAxis, &relatedYAxis); + if ( !closestPoint.isNull() ) + { + QString str = valueAxisValueString; + + if ( !mainAxisValueString.isEmpty() ) + { + str += QString(" (%1)").arg(mainAxisValueString); + } + + txt.setText(str); + } + + updateClosestCurvePointMarker(closestPoint, relatedXAxis, relatedYAxis); + } + + return txt; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QPointF RiuQwtCurvePointTracker::closestCurvePoint(const QPoint& cursorPosition, QString* valueAxisValueString, QString* mainAxisValueString, QwtPlot::Axis* relatedXAxis, QwtPlot::Axis* relatedYAxis) const +{ + QPointF samplePoint; + + QwtPlotCurve* closestCurve = nullptr; + double distMin = DBL_MAX; + int closestPointSampleIndex = -1; + + const QwtPlotItemList& itmList = m_plot->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(cursorPosition, &dist); + if ( dist < distMin ) + { + closestCurve = candidateCurve; + distMin = dist; + closestPointSampleIndex = candidateSampleIndex; + } + } + } + + if ( closestCurve && distMin < 50 ) + { + samplePoint = closestCurve->sample(closestPointSampleIndex); + + if ( relatedXAxis ) *relatedXAxis = static_cast(closestCurve->xAxis()); + if ( relatedYAxis ) *relatedYAxis = static_cast(closestCurve->yAxis()); + } + + + if ( mainAxisValueString ) + { + const QwtScaleDraw* mainAxisScaleDraw = m_isMainAxisHorizontal ? m_plot->axisScaleDraw(*relatedXAxis): m_plot->axisScaleDraw(*relatedYAxis); + auto dateScaleDraw = dynamic_cast(mainAxisScaleDraw) ; + + qreal mainAxisSampleVal = 0.0; + if ( m_isMainAxisHorizontal ) + mainAxisSampleVal = samplePoint.x(); + else + mainAxisSampleVal = samplePoint.y(); + + if ( dateScaleDraw ) + { + QDateTime date = dateScaleDraw->toDateTime(mainAxisSampleVal); + *mainAxisValueString = date.toString("hh:mm dd.MMMM.yyyy"); + } + else if ( mainAxisScaleDraw ) + { + *mainAxisValueString = mainAxisScaleDraw->label(mainAxisSampleVal).text(); + } + } + + if ( valueAxisValueString && closestCurve ) + { + const QwtScaleDraw* valueAxisScaleDraw = m_isMainAxisHorizontal ? m_plot->axisScaleDraw(*relatedYAxis): m_plot->axisScaleDraw(*relatedXAxis); + + qreal valueAxisSampleVal = 0.0; + if ( m_isMainAxisHorizontal ) + valueAxisSampleVal = samplePoint.y(); + else + valueAxisSampleVal = samplePoint.x(); + + if ( valueAxisScaleDraw ) + { + *valueAxisValueString = valueAxisScaleDraw->label(valueAxisSampleVal).text(); + } + } + + return samplePoint; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtCurvePointTracker::updateClosestCurvePointMarker(const QPointF& closestPoint, QwtPlot::Axis relatedXAxis, QwtPlot::Axis relatedYAxis) const +{ + bool replotRequired = false; + + if ( !closestPoint.isNull() ) + { + if ( !m_plotMarker->plot() ) + { + m_plotMarker->attach(m_plot); + + replotRequired = true; + } + + if ( m_plotMarker->value() != closestPoint ) + { + m_plotMarker->setValue(closestPoint.x(), closestPoint.y()); + + // Set the axes that the marker realtes to, to make the positioning correct + m_plotMarker->setAxes(relatedXAxis, relatedYAxis); + + // TODO : Should use a color or other visual indicator to show what axis the curve relates to + + replotRequired = true; + } + } + else + { + if ( m_plotMarker->plot() ) + { + m_plotMarker->detach(); + + replotRequired = true; + } + } + + if ( replotRequired ) m_plot->replot(); +} diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h new file mode 100644 index 0000000000..f53e3f353c --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h @@ -0,0 +1,47 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017- Statoil 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_plot_picker.h" +#include "qwt_plot.h" + +#include + +class QwtPlotMarker; + +//-------------------------------------------------------------------------------------------------- +/// Class to add mouse over-tracking of curve points with text marker +//-------------------------------------------------------------------------------------------------- +class RiuQwtCurvePointTracker : public QwtPlotPicker +{ +public: + explicit RiuQwtCurvePointTracker(QwtPlot* plot, bool isMainAxisHorizontal); + ~RiuQwtCurvePointTracker(); + + void removeMarkerOnFocusLeave(); + +protected: + virtual QwtText trackerText(const QPoint& pos) const override; + QPointF closestCurvePoint(const QPoint& cursorPosition, QString* valueAxisValueString, QString* mainAxisValueString, QwtPlot::Axis* relatedXAxis, QwtPlot::Axis* relatedYAxis) const; + void updateClosestCurvePointMarker(const QPointF& closestPoint, QwtPlot::Axis relatedXAxis, QwtPlot::Axis relatedYAxis) const; + + QPointer m_plot; + QwtPlotMarker* m_plotMarker; + bool m_isMainAxisHorizontal; +}; + diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index 6d5529ea8d..56533c9da6 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -26,21 +26,19 @@ #include "RiuMainPlotWindow.h" #include "RiuQwtScalePicker.h" +#include "RiuQwtCurvePointTracker.h" #include "cafSelectionManager.h" -#include "qwt_date_scale_draw.h" #include "qwt_date_scale_engine.h" +#include "qwt_date_scale_draw.h" #include "qwt_legend.h" #include "qwt_plot_curve.h" #include "qwt_plot_grid.h" #include "qwt_plot_layout.h" -#include "qwt_plot_marker.h" #include "qwt_plot_panner.h" -#include "qwt_plot_picker.h" #include "qwt_plot_zoomer.h" #include "qwt_scale_engine.h" -#include "qwt_symbol.h" #include #include @@ -48,199 +46,6 @@ #include - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -class RiuQwtPlotPicker : public QwtPlotPicker -{ -public: - explicit RiuQwtPlotPicker(QwtPlot* plot, bool isMainAxisHorizontal) - : QwtPlotPicker(plot->canvas()), m_plot(plot), m_isMainAxisHorizontal(isMainAxisHorizontal) - { - this->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); - } - - ~RiuQwtPlotPicker() - { - m_plotMarker->detach(); - delete m_plotMarker; - } - - void removeMarker() - { - if (m_plotMarker->plot()) - { - m_plotMarker->detach(); - - m_plot->replot(); - } - } - -protected: - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - virtual QwtText trackerText(const QPoint& pos) const override - { - QwtText txt; - - if (m_plot) - { - QwtPlot::Axis relatedYAxis = QwtPlot::yLeft; - QwtPlot::Axis relatedXAxis = QwtPlot::xBottom; - - QString mainAxisValueString; - QString valueAxisValueString; - QPointF closestPoint = closestCurvePoint(pos, &valueAxisValueString, &mainAxisValueString, &relatedXAxis, &relatedYAxis); - if (!closestPoint.isNull()) - { - QString str = valueAxisValueString; - - if (!mainAxisValueString.isEmpty()) - { - str += QString(" (%1)").arg(mainAxisValueString); - } - - txt.setText(str); - } - - updateClosestCurvePointMarker(closestPoint, relatedXAxis, relatedYAxis); - } - - return txt; - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - QPointF closestCurvePoint(const QPoint& cursorPosition, QString* valueAxisValueString, QString* mainAxisValueString, QwtPlot::Axis* relatedXAxis, QwtPlot::Axis* relatedYAxis) const - { - QPointF samplePoint; - - QwtPlotCurve* closestCurve = nullptr; - double distMin = DBL_MAX; - int closestPointSampleIndex = -1; - - const QwtPlotItemList& itmList = m_plot->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(cursorPosition, &dist); - if (dist < distMin) - { - closestCurve = candidateCurve; - distMin = dist; - closestPointSampleIndex = candidateSampleIndex; - } - } - } - - if (closestCurve && distMin < 50) - { - samplePoint = closestCurve->sample(closestPointSampleIndex); - - if (relatedXAxis) *relatedXAxis = static_cast( closestCurve->xAxis()); - if (relatedYAxis) *relatedYAxis = static_cast( closestCurve->yAxis()); - } - - - if (mainAxisValueString) - { - const QwtScaleDraw* mainAxisScaleDraw = m_isMainAxisHorizontal ? m_plot->axisScaleDraw(*relatedXAxis): m_plot->axisScaleDraw(*relatedYAxis); - auto dateScaleDraw = dynamic_cast(mainAxisScaleDraw) ; - - qreal mainAxisSampleVal = 0.0; - if (m_isMainAxisHorizontal) - mainAxisSampleVal = samplePoint.x(); - else - mainAxisSampleVal = samplePoint.y(); - - if (dateScaleDraw) - { - QDateTime date = dateScaleDraw->toDateTime(mainAxisSampleVal); - *mainAxisValueString = date.toString("hh:mm dd.MMMM.yyyy"); - } - else if (mainAxisScaleDraw) - { - *mainAxisValueString = mainAxisScaleDraw->label(mainAxisSampleVal).text(); - } - } - - if (valueAxisValueString && closestCurve) - { - const QwtScaleDraw* valueAxisScaleDraw = m_isMainAxisHorizontal ? m_plot->axisScaleDraw(*relatedYAxis): m_plot->axisScaleDraw(*relatedXAxis); - - qreal valueAxisSampleVal = 0.0; - if (m_isMainAxisHorizontal) - valueAxisSampleVal = samplePoint.x(); - else - valueAxisSampleVal = samplePoint.y(); - - if (valueAxisScaleDraw) - { - *valueAxisValueString = valueAxisScaleDraw->label(valueAxisSampleVal).text(); - } - } - - return samplePoint; - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - void updateClosestCurvePointMarker(const QPointF& closestPoint, QwtPlot::Axis relatedXAxis, QwtPlot::Axis relatedYAxis) const - { - bool replotRequired = false; - - if (!closestPoint.isNull()) - { - if (!m_plotMarker->plot()) - { - m_plotMarker->attach(m_plot); - - replotRequired = true; - } - - if (m_plotMarker->value() != closestPoint) - { - m_plotMarker->setValue(closestPoint.x(), closestPoint.y()); - - // Set the axes that the marker realtes to, to make the positioning correct - m_plotMarker->setAxes(relatedXAxis, relatedYAxis); - - // TODO : Should use a color or other visual indicator to show what axis the curve relates to - - replotRequired = true; - } - } - else - { - if (m_plotMarker->plot()) - { - m_plotMarker->detach(); - - replotRequired = true; - } - } - - if (replotRequired) m_plot->replot(); - } - - QPointer m_plot; - QwtPlotMarker* m_plotMarker; - bool m_isMainAxisHorizontal; -}; - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -279,7 +84,7 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* pa connect(scalePicker, SIGNAL(clicked(int, double)), this, SLOT(onAxisClicked(int, double))); // Create a plot picker to display values next to mouse cursor - m_plotPicker = new RiuQwtPlotPicker(this, true); + m_curvePointTracker = new RiuQwtCurvePointTracker(this, true); } @@ -486,7 +291,7 @@ bool RiuSummaryQwtPlot::eventFilter(QObject* watched, QEvent* event) //-------------------------------------------------------------------------------------------------- void RiuSummaryQwtPlot::leaveEvent(QEvent *) { - m_plotPicker->removeMarker(); + m_curvePointTracker->removeMarkerOnFocusLeave(); } //-------------------------------------------------------------------------------------------------- @@ -530,7 +335,7 @@ void RiuSummaryQwtPlot::onZoomedSlot() { QwtInterval left, right, time; currentVisibleWindow(&left, &right, &time); - + this->setZoomWindow(left, right, time); m_plotDefinition->updateZoomWindowFromQwt(); diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index 4882a04181..0447ef0a85 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -30,7 +30,7 @@ class QwtInterval; class QwtPicker; class QwtPlotMarker; -class RiuQwtPlotPicker; +class RiuQwtCurvePointTracker; class RimSummaryPlot; //================================================================================================== @@ -67,9 +67,6 @@ protected: virtual void contextMenuEvent(QContextMenuEvent *) 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); @@ -80,7 +77,7 @@ private slots: private: QwtPlotGrid* m_grid; - RiuQwtPlotPicker* m_plotPicker; + RiuQwtCurvePointTracker* m_curvePointTracker; caf::PdmPointer m_plotDefinition; From f05a4027aaa61797f3a88e9a772abdac71f2fd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 27 Mar 2017 10:50:54 +0200 Subject: [PATCH 12/28] #1321 Applied new plot marker tracker class to well log plots --- .../UserInterface/RiuWellLogTrack.cpp | 155 +----------------- .../UserInterface/RiuWellLogTrack.h | 9 +- 2 files changed, 6 insertions(+), 158 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp index 891ca27e96..0a2496edb5 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp @@ -26,6 +26,7 @@ #include "RimWellLogCurve.h" #include "RiuMainPlotWindow.h" +#include "RiuQwtCurvePointTracker.h" #include "qwt_legend.h" #include "qwt_plot_curve.h" @@ -48,53 +49,6 @@ #define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1 #define RIU_SCROLLWHEEL_PANFACTOR 0.1 -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -class RiuWellLogTrackQwtPicker : public QwtPlotPicker -{ -public: - explicit 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; - } -}; - - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -111,14 +65,8 @@ RiuWellLogTrack::RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* 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); + m_curvePointTracker = new RiuQwtCurvePointTracker(this, false); } //-------------------------------------------------------------------------------------------------- @@ -128,100 +76,8 @@ 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(); -} //-------------------------------------------------------------------------------------------------- /// @@ -452,12 +308,7 @@ QSize RiuWellLogTrack::minimumSizeHint() const //-------------------------------------------------------------------------------------------------- void RiuWellLogTrack::leaveEvent(QEvent *) { - if (m_plotMarker->plot()) - { - m_plotMarker->detach(); - - replot(); - } + m_curvePointTracker->removeMarkerOnFocusLeave(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index 0c44ff8c0b..a5720f345a 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -25,6 +25,8 @@ class RimWellLogTrack; +class RiuQwtCurvePointTracker; + class QwtLegend; class QwtPicker; class QwtPlotGrid; @@ -61,17 +63,12 @@ protected: 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; + RiuQwtCurvePointTracker* m_curvePointTracker; }; From a82677c743d9f026e9635aa10eb546310de1b04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 27 Mar 2017 16:45:00 +0200 Subject: [PATCH 13/28] #1366 Added wheel zoom to point. Also preparations for #1321 --- .../UserInterface/CMakeLists_files.cmake | 3 + .../UserInterface/RiuQwtPlotWheelZoomer.cpp | 75 +++++++++++++++++++ .../UserInterface/RiuQwtPlotWheelZoomer.h | 40 ++++++++++ .../UserInterface/RiuSummaryQwtPlot.cpp | 16 ++-- 4 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp create mode 100644 ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index 7f5299f69f..28f1fef20d 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -21,6 +21,7 @@ ${CEE_CURRENT_LIST_DIR}RiuProjectPropertyView.h ${CEE_CURRENT_LIST_DIR}RiuPropertyViewTabWidget.h ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h ${CEE_CURRENT_LIST_DIR}RiuQwtCurvePointTracker.h +${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.h ${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.h ${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.h ${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.h @@ -62,6 +63,7 @@ ${CEE_CURRENT_LIST_DIR}RiuProjectPropertyView.cpp ${CEE_CURRENT_LIST_DIR}RiuPropertyViewTabWidget.cpp ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.cpp ${CEE_CURRENT_LIST_DIR}RiuQwtCurvePointTracker.cpp +${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.cpp ${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.cpp ${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.cpp ${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.cpp @@ -109,6 +111,7 @@ ${CEE_CURRENT_LIST_DIR}RiuWellLogTrack.h ${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.h ${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h +${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.h ${CEE_CURRENT_LIST_DIR}RiuExportMultipleSnapshotsWidget.h ${CEE_CURRENT_LIST_DIR}RiuWellAllocationPlot.h ${CEE_CURRENT_LIST_DIR}RiuFlowCharacteristicsPlot.h diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp new file mode 100644 index 0000000000..d5c3baffae --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017- Statoil 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 "RiuQwtPlotWheelZoomer.h" +#include "qwt_plot.h" +#include +#include + +#define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1 +#define RIU_SCROLLWHEEL_PANFACTOR 0.1 + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtPlotWheelZoomer::RiuQwtPlotWheelZoomer(QwtPlot* plot): QObject(plot), m_plot(plot) +{ + plot->canvas()->installEventFilter(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void zoomOnAxis(QwtPlot* plot, QwtPlot::Axis axis, double zoomFactor, int eventPos) +{ + QwtScaleMap scaleMap = plot->canvasMap(axis); + double zoomCenter = scaleMap.invTransform(eventPos); + double newMin = zoomCenter - zoomFactor * (zoomCenter - scaleMap.s1()); + double newMax = zoomCenter + zoomFactor * (-zoomCenter + scaleMap.s2()); + plot->setAxisScale(axis, newMin, newMax); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuQwtPlotWheelZoomer::eventFilter(QObject * watched, QEvent * event) +{ + QWheelEvent* wheelEvent = dynamic_cast(event); + if ( wheelEvent ) + { + if ( wheelEvent->modifiers() ) + { + double zoomFactor = 1.0/RIU_SCROLLWHEEL_ZOOMFACTOR; + if ( wheelEvent->delta() > 0 ) + { + zoomFactor = RIU_SCROLLWHEEL_ZOOMFACTOR; + } + + zoomOnAxis(m_plot, QwtPlot::xBottom, zoomFactor, wheelEvent->pos().x()); + zoomOnAxis(m_plot, QwtPlot::xTop, zoomFactor, wheelEvent->pos().x()); + zoomOnAxis(m_plot, QwtPlot::yLeft, zoomFactor, wheelEvent->pos().y()); + zoomOnAxis(m_plot, QwtPlot::yRight, zoomFactor, wheelEvent->pos().y()); + + m_plot->replot(); + emit zoomUpdated(); + } + } + return false; +} + diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h new file mode 100644 index 0000000000..a06f28b63a --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017- Statoil 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 + +class QwtPlot; +class QEvent; + +class RiuQwtPlotWheelZoomer : public QObject +{ + Q_OBJECT +public: + RiuQwtPlotWheelZoomer(QwtPlot* plot); + + virtual bool eventFilter(QObject * watched, QEvent * event) override; + +signals: + void zoomUpdated(); + +private: + QwtPlot* m_plot; +}; + + diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index 56533c9da6..22077a1ea3 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -66,19 +66,21 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* pa m_zoomerLeft->setTrackerPen(QColor(Qt::black)); m_zoomerLeft->initMousePattern(1); - // MidButton for the panning - QwtPlotPanner* panner = new QwtPlotPanner(canvas()); - panner->setMouseButton(Qt::MidButton); - - connect(m_zoomerLeft, SIGNAL(zoomed( const QRectF & )), SLOT(onZoomedSlot())); - connect(panner, SIGNAL(panned( int , int )), SLOT(onZoomedSlot())); - // Attach a zoomer for the right axis m_zoomerRight = new QwtPlotZoomer(canvas()); m_zoomerRight->setAxis(xTop, yRight); m_zoomerRight->setTrackerMode(QwtPicker::AlwaysOff); m_zoomerRight->initMousePattern(1); + // MidButton for the panning + QwtPlotPanner* panner = new QwtPlotPanner(canvas()); + panner->setMouseButton(Qt::MidButton); + + auto wheelZoomer = new RiuQwtPlotWheelZoomer(this); + + connect(wheelZoomer, SIGNAL(zoomUpdated()), SLOT(onZoomedSlot())); + connect(m_zoomerLeft, SIGNAL(zoomed( const QRectF & )), SLOT(onZoomedSlot())); + connect(panner, SIGNAL(panned( int , int )), SLOT(onZoomedSlot())); RiuQwtScalePicker* scalePicker = new RiuQwtScalePicker(this); connect(scalePicker, SIGNAL(clicked(int, double)), this, SLOT(onAxisClicked(int, double))); From c0ff734cc7478c727419eb6934d999bb62c4f760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 27 Mar 2017 16:47:59 +0200 Subject: [PATCH 14/28] Preparations for #1321: Aligned default stuff between the plot types. --- .../UserInterface/RiuQwtCurvePointTracker.cpp | 18 ++- .../UserInterface/RiuQwtCurvePointTracker.h | 14 +- .../UserInterface/RiuResultQwtPlot.cpp | 58 +------- .../UserInterface/RiuResultQwtPlot.h | 1 - .../UserInterface/RiuSummaryQwtPlot.cpp | 132 ++++++++++-------- .../UserInterface/RiuSummaryQwtPlot.h | 5 +- .../UserInterface/RiuWellLogTrack.cpp | 62 +------- .../UserInterface/RiuWellLogTrack.h | 2 - 8 files changed, 111 insertions(+), 181 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp index 7786f4599e..38878ffba8 100644 --- a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp @@ -23,12 +23,14 @@ #include "qwt_plot_curve.h" #include "qwt_date_scale_draw.h" +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RiuQwtCurvePointTracker::RiuQwtCurvePointTracker(QwtPlot* plot, bool isMainAxisHorizontal): QwtPlotPicker(plot->canvas()), m_plot(plot), m_isMainAxisHorizontal(isMainAxisHorizontal) +RiuQwtCurvePointTracker::RiuQwtCurvePointTracker(QwtPlot* plot, bool isMainAxisHorizontal) + : QwtPlotPicker(plot->canvas()), m_plot(plot), m_isMainAxisHorizontal(isMainAxisHorizontal) { this->setTrackerMode(QwtPicker::AlwaysOn); m_plotMarker = new QwtPlotMarker; @@ -60,6 +62,20 @@ void RiuQwtCurvePointTracker::removeMarkerOnFocusLeave() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuQwtCurvePointTracker::eventFilter(QObject *watched, QEvent *event) +{ + if ( event->type() == QEvent::Leave ) + { + this->removeMarkerOnFocusLeave(); + } + + // pass the event on to the parent class + return QwtPlotPicker::eventFilter(watched, event); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h index f53e3f353c..9142950532 100644 --- a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h @@ -33,12 +33,20 @@ public: explicit RiuQwtCurvePointTracker(QwtPlot* plot, bool isMainAxisHorizontal); ~RiuQwtCurvePointTracker(); +protected: + + virtual bool eventFilter(QObject *, QEvent *) override; void removeMarkerOnFocusLeave(); -protected: virtual QwtText trackerText(const QPoint& pos) const override; - QPointF closestCurvePoint(const QPoint& cursorPosition, QString* valueAxisValueString, QString* mainAxisValueString, QwtPlot::Axis* relatedXAxis, QwtPlot::Axis* relatedYAxis) const; - void updateClosestCurvePointMarker(const QPointF& closestPoint, QwtPlot::Axis relatedXAxis, QwtPlot::Axis relatedYAxis) const; + QPointF closestCurvePoint(const QPoint& cursorPosition, + QString* valueAxisValueString, + QString* mainAxisValueString, + QwtPlot::Axis* relatedXAxis, + QwtPlot::Axis* relatedYAxis) const; + void updateClosestCurvePointMarker(const QPointF& closestPoint, + QwtPlot::Axis relatedXAxis, + QwtPlot::Axis relatedYAxis) const; QPointer m_plot; QwtPlotMarker* m_plotMarker; diff --git a/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp b/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp index 6efc38bad3..e69b5e16ff 100644 --- a/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp @@ -39,6 +39,7 @@ #include #include +#include "RiuSummaryQwtPlot.h" //-------------------------------------------------------------------------------------------------- @@ -47,9 +48,6 @@ RiuResultQwtPlot::RiuResultQwtPlot(QWidget* parent) : QwtPlot(parent) { - m_grid = new QwtPlotGrid; - m_grid->attach(this); - setDefaults(); } @@ -59,9 +57,6 @@ RiuResultQwtPlot::RiuResultQwtPlot(QWidget* parent) RiuResultQwtPlot::~RiuResultQwtPlot() { deleteAllCurves(); - - m_grid->detach(); - delete m_grid; } //-------------------------------------------------------------------------------------------------- @@ -152,59 +147,20 @@ void RiuResultQwtPlot::contextMenuEvent(QContextMenuEvent* event) //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::setDefaults() { - QPalette newPalette(palette()); - newPalette.setColor(QPalette::Background, Qt::white); - setPalette(newPalette); - - setAutoFillBackground(true); - setCanvasBackground(Qt::white); - - QFrame* canvasFrame = dynamic_cast(canvas()); - if (canvasFrame) - { - canvasFrame->setFrameShape(QFrame::NoFrame); - } - - canvas()->setMouseTracking(true); - canvas()->installEventFilter(this); - - QPen gridPen(Qt::SolidLine); - gridPen.setColor(Qt::lightGray); - m_grid->setPen(gridPen); + RiuSummaryQwtPlot::setCommonPlotBehaviour(this); enableAxis(QwtPlot::xBottom, true); enableAxis(QwtPlot::yLeft, true); enableAxis(QwtPlot::xTop, false); enableAxis(QwtPlot::yRight, false); - plotLayout()->setAlignCanvasToScales(true); - - QwtDateScaleDraw* scaleDraw = new QwtDateScaleDraw(Qt::UTC); - scaleDraw->setDateFormat(QwtDate::Year, QString("dd-MM-yyyy")); - - QwtDateScaleEngine* scaleEngine = new QwtDateScaleEngine(Qt::UTC); - setAxisScaleEngine(QwtPlot::xBottom, scaleEngine); - setAxisScaleDraw(QwtPlot::xBottom, scaleDraw); - - QFont xAxisFont = axisFont(QwtPlot::xBottom); - xAxisFont.setPixelSize(9); - setAxisFont(QwtPlot::xBottom, xAxisFont); - - QFont yAxisFont = axisFont(QwtPlot::yLeft); - yAxisFont.setPixelSize(9); - setAxisFont(QwtPlot::yLeft, yAxisFont); - - QwtText axisTitleY = axisTitle(QwtPlot::yLeft); - QFont yAxisTitleFont = axisTitleY.font(); - yAxisTitleFont.setPixelSize(9); - yAxisTitleFont.setBold(false); - axisTitleY.setFont(yAxisTitleFont); - axisTitleY.setRenderFlags(Qt::AlignRight); - setAxisTitle(QwtPlot::yLeft, axisTitleY); - + RiuSummaryQwtPlot::enableDateBasedBottomXAxis(this); - QwtLegend* legend = new QwtLegend(this); + setAxisMaxMinor(QwtPlot::xBottom, 2); + setAxisMaxMinor(QwtPlot::yLeft, 3); + // The legend will be deleted in the destructor of the plot or when // another legend is inserted. + QwtLegend* legend = new QwtLegend(this); this->insertLegend(legend, BottomLegend); } diff --git a/ApplicationCode/UserInterface/RiuResultQwtPlot.h b/ApplicationCode/UserInterface/RiuResultQwtPlot.h index 7513b091f3..681858dfe5 100644 --- a/ApplicationCode/UserInterface/RiuResultQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuResultQwtPlot.h @@ -55,6 +55,5 @@ private: private: std::vector m_plotCurves; - QwtPlotGrid* m_grid; }; diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index 22077a1ea3..f773a262d8 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -45,6 +45,8 @@ #include #include +#include "qwt_plot_magnifier.h" +#include "RiuQwtPlotWheelZoomer.h" //-------------------------------------------------------------------------------------------------- /// @@ -54,9 +56,6 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* pa Q_ASSERT(plotDefinition); m_plotDefinition = plotDefinition; - m_grid = new QwtPlotGrid; - m_grid->attach(this); - setDefaults(); // LeftButton for the zooming @@ -85,9 +84,6 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* pa RiuQwtScalePicker* scalePicker = new RiuQwtScalePicker(this); connect(scalePicker, SIGNAL(clicked(int, double)), this, SLOT(onAxisClicked(int, double))); - // Create a plot picker to display values next to mouse cursor - m_curvePointTracker = new RiuQwtCurvePointTracker(this, true); - } //-------------------------------------------------------------------------------------------------- @@ -95,15 +91,11 @@ RiuSummaryQwtPlot::RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* pa //-------------------------------------------------------------------------------------------------- RiuSummaryQwtPlot::~RiuSummaryQwtPlot() { - m_grid->detach(); - delete m_grid; - if (m_plotDefinition) { m_plotDefinition->detachAllCurves(); m_plotDefinition->handleMdiWindowClosed(); } - } //-------------------------------------------------------------------------------------------------- @@ -191,71 +183,99 @@ QSize RiuSummaryQwtPlot::sizeHint() const //-------------------------------------------------------------------------------------------------- void RiuSummaryQwtPlot::setDefaults() { - QPalette newPalette(palette()); - newPalette.setColor(QPalette::Background, Qt::white); - setPalette(newPalette); - - setAutoFillBackground(true); - setCanvasBackground(Qt::white); - - QFrame* canvasFrame = dynamic_cast(canvas()); - if (canvasFrame) - { - canvasFrame->setFrameShape(QFrame::NoFrame); - } - - canvas()->setMouseTracking(true); - canvas()->installEventFilter(this); - - QPen gridPen(Qt::SolidLine); - gridPen.setColor(Qt::lightGray); - m_grid->setPen(gridPen); + setCommonPlotBehaviour(this); enableAxis(QwtPlot::xBottom, true); enableAxis(QwtPlot::yLeft, true); enableAxis(QwtPlot::xTop, false); enableAxis(QwtPlot::yRight, false); - plotLayout()->setAlignCanvasToScales(true); - useDateBasedTimeAxis(); - QFont xAxisFont = axisFont(QwtPlot::xBottom); - xAxisFont.setPixelSize(11); - setAxisFont(QwtPlot::xBottom, xAxisFont); setAxisMaxMinor(QwtPlot::xBottom, 2); - - QFont yAxisFont = axisFont(QwtPlot::yLeft); - yAxisFont.setPixelSize(11); - setAxisFont(QwtPlot::yLeft, yAxisFont); - setAxisMaxMinor(QwtPlot::yLeft, 3); - QwtText axisTitleY = axisTitle(QwtPlot::yLeft); - QFont yAxisTitleFont = axisTitleY.font(); - yAxisTitleFont.setPixelSize(11); - yAxisTitleFont.setBold(false); - axisTitleY.setFont(yAxisTitleFont); - axisTitleY.setRenderFlags(Qt::AlignRight); - setAxisTitle(QwtPlot::yLeft, axisTitleY); - - QwtLegend* legend = new QwtLegend(this); // The legend will be deleted in the destructor of the plot or when // another legend is inserted. + QwtLegend* legend = new QwtLegend(this); this->insertLegend(legend, BottomLegend); } +void RiuSummaryQwtPlot::setCommonPlotBehaviour(QwtPlot* plot) +{ + // Plot background and frame look + + QPalette newPalette(plot->palette()); + newPalette.setColor(QPalette::Background, Qt::white); + plot->setPalette(newPalette); + + plot->setAutoFillBackground(true); + plot->setCanvasBackground(Qt::white); + + QFrame* canvasFrame = dynamic_cast(plot->canvas()); + if (canvasFrame) + { + canvasFrame->setFrameShape(QFrame::NoFrame); + } + + // Grid + + QwtPlotGrid* grid = new QwtPlotGrid; + grid->attach(plot); + QPen gridPen(Qt::SolidLine); + gridPen.setColor(Qt::lightGray); + grid->setPen(gridPen); + + // Axis number font + QFont axisFont = plot->axisFont(QwtPlot::xBottom); + axisFont.setPixelSize(11); + + plot->setAxisFont(QwtPlot::xBottom, axisFont); + plot->setAxisFont(QwtPlot::xTop, axisFont); + plot->setAxisFont(QwtPlot::yLeft, axisFont); + plot->setAxisFont(QwtPlot::yRight, axisFont); + + // Axis title font + QwtText axisTitle = plot->axisTitle(QwtPlot::xBottom); + QFont axisTitleFont = axisTitle.font(); + axisTitleFont.setPixelSize(11); + axisTitleFont.setBold(false); + axisTitle.setFont(axisTitleFont); + axisTitle.setRenderFlags(Qt::AlignRight); + + plot->setAxisTitle(QwtPlot::xBottom, axisTitle); + plot->setAxisTitle(QwtPlot::xTop, axisTitle); + plot->setAxisTitle(QwtPlot::yLeft, axisTitle); + plot->setAxisTitle(QwtPlot::yRight, axisTitle); + + // Enable mousetracking and event filter + + plot->canvas()->setMouseTracking(true); + plot->canvas()->installEventFilter(plot); + plot->plotLayout()->setAlignCanvasToScales(true); + + new RiuQwtCurvePointTracker(plot, true); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuSummaryQwtPlot::useDateBasedTimeAxis() +{ + enableDateBasedBottomXAxis(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuSummaryQwtPlot::enableDateBasedBottomXAxis(QwtPlot* plot) { QwtDateScaleDraw* scaleDraw = new QwtDateScaleDraw(Qt::UTC); scaleDraw->setDateFormat(QwtDate::Year, QString("dd-MM-yyyy")); QwtDateScaleEngine* scaleEngine = new QwtDateScaleEngine(Qt::UTC); - setAxisScaleEngine(QwtPlot::xBottom, scaleEngine); - setAxisScaleDraw(QwtPlot::xBottom, scaleDraw); + plot->setAxisScaleEngine(QwtPlot::xBottom, scaleEngine); + plot->setAxisScaleDraw(QwtPlot::xBottom, scaleDraw); } //-------------------------------------------------------------------------------------------------- @@ -288,13 +308,6 @@ bool RiuSummaryQwtPlot::eventFilter(QObject* watched, QEvent* event) } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuSummaryQwtPlot::leaveEvent(QEvent *) -{ - m_curvePointTracker->removeMarkerOnFocusLeave(); -} //-------------------------------------------------------------------------------------------------- /// @@ -335,11 +348,6 @@ void RiuSummaryQwtPlot::selectClosestCurve(const QPoint& pos) //-------------------------------------------------------------------------------------------------- void RiuSummaryQwtPlot::onZoomedSlot() { - QwtInterval left, right, time; - currentVisibleWindow(&left, &right, &time); - - this->setZoomWindow(left, right, time); - m_plotDefinition->updateZoomWindowFromQwt(); } diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index 0447ef0a85..db7df2c86a 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -58,9 +58,11 @@ public: const QwtInterval& rightAxis, const QwtInterval& timeAxis); + static void setCommonPlotBehaviour(QwtPlot* plot); + static void enableDateBasedBottomXAxis(QwtPlot* plot); + protected: virtual bool eventFilter(QObject* watched, QEvent* event) override; - virtual void leaveEvent(QEvent *) override; virtual QSize sizeHint() const override; virtual QSize minimumSizeHint() const override; @@ -76,7 +78,6 @@ private slots: void onAxisClicked(int axis, double value); private: - QwtPlotGrid* m_grid; RiuQwtCurvePointTracker* m_curvePointTracker; caf::PdmPointer m_plotDefinition; diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp index 0a2496edb5..d5b6ab55ee 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp @@ -45,6 +45,7 @@ #include #include +#include "RiuSummaryQwtPlot.h" #define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1 #define RIU_SCROLLWHEEL_PANFACTOR 0.1 @@ -57,16 +58,9 @@ RiuWellLogTrack::RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* { Q_ASSERT(plotTrackDefinition); m_plotTrackDefinition = plotTrackDefinition; - - m_grid = new QwtPlotGrid(); - m_grid->attach(this); setFocusPolicy(Qt::ClickFocus); setDefaults(); - - // Create a plot picker to display values next to mouse cursor - - m_curvePointTracker = new RiuQwtCurvePointTracker(this, false); } //-------------------------------------------------------------------------------------------------- @@ -74,8 +68,7 @@ RiuWellLogTrack::RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* //-------------------------------------------------------------------------------------------------- RiuWellLogTrack::~RiuWellLogTrack() { - m_grid->detach(); - delete m_grid; + } @@ -84,33 +77,13 @@ RiuWellLogTrack::~RiuWellLogTrack() //-------------------------------------------------------------------------------------------------- void RiuWellLogTrack::setDefaults() { - QPalette newPalette(palette()); - newPalette.setColor(QPalette::Background, Qt::white); - setPalette(newPalette); - - setAutoFillBackground(true); - setCanvasBackground(Qt::white); - - QFrame* canvasFrame = dynamic_cast(canvas()); - if (canvasFrame) - { - canvasFrame->setFrameShape(QFrame::NoFrame); - } - - canvas()->setMouseTracking(true); - canvas()->installEventFilter(this); - - QPen gridPen(Qt::SolidLine); - gridPen.setColor(Qt::lightGray); - m_grid->setPen(gridPen); + RiuSummaryQwtPlot::setCommonPlotBehaviour(this); enableAxis(QwtPlot::xTop, true); enableAxis(QwtPlot::yLeft, true); enableAxis(QwtPlot::xBottom, false); enableAxis(QwtPlot::yRight, false); - plotLayout()->setAlignCanvasToScales(true); - axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Inverted, true); // Align the canvas with the actual min and max values of the curves @@ -119,28 +92,6 @@ void RiuWellLogTrack::setDefaults() setAxisScale(QwtPlot::yLeft, 1000, 0); setAxisScale(QwtPlot::xTop, -10, 100); - QFont xAxisFont = axisFont(QwtPlot::xTop); - xAxisFont.setPixelSize(9); - setAxisFont(QwtPlot::xTop, xAxisFont); - QwtText axisTitleX = axisTitle(QwtPlot::yLeft); - QFont xAxisTitleFont = axisTitleX.font(); - xAxisTitleFont.setPixelSize(9); - xAxisTitleFont.setBold(false); - axisTitleX.setFont(xAxisTitleFont); - axisTitleX.setRenderFlags(Qt::AlignRight); - setAxisTitle(QwtPlot::xTop, axisTitleX); - - QFont yAxisFont = axisFont(QwtPlot::yLeft); - yAxisFont.setPixelSize(9); - setAxisFont(QwtPlot::yLeft, yAxisFont); - - QwtText axisTitleY = axisTitle(QwtPlot::yLeft); - QFont yAxisTitleFont = axisTitleY.font(); - yAxisTitleFont.setPixelSize(9); - yAxisTitleFont.setBold(false); - axisTitleY.setFont(yAxisTitleFont); - axisTitleY.setRenderFlags(Qt::AlignRight); - setAxisTitle(QwtPlot::yLeft, axisTitleY); } //-------------------------------------------------------------------------------------------------- @@ -303,13 +254,6 @@ QSize RiuWellLogTrack::minimumSizeHint() const return QSize(0, 0); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuWellLogTrack::leaveEvent(QEvent *) -{ - m_curvePointTracker->removeMarkerOnFocusLeave(); -} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index a5720f345a..1f93563b4a 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -60,7 +60,6 @@ protected: virtual void focusInEvent(QFocusEvent* event); virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; - virtual void leaveEvent(QEvent *) override; private: void setDefaults(); @@ -68,7 +67,6 @@ private: private: caf::PdmPointer m_plotTrackDefinition; - QwtPlotGrid* m_grid; RiuQwtCurvePointTracker* m_curvePointTracker; }; From 0c834cdc0fa04775613456eae400acd61aa5f2ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 27 Mar 2017 18:12:41 +0200 Subject: [PATCH 15/28] Cleaning --- ApplicationCode/UserInterface/RiuResultQwtPlot.h | 10 ++++++++-- ApplicationCode/UserInterface/RiuSummaryQwtPlot.h | 3 --- ApplicationCode/UserInterface/RiuWellLogTrack.h | 3 --- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuResultQwtPlot.h b/ApplicationCode/UserInterface/RiuResultQwtPlot.h index 681858dfe5..c08250accc 100644 --- a/ApplicationCode/UserInterface/RiuResultQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuResultQwtPlot.h @@ -40,8 +40,14 @@ public: explicit RiuResultQwtPlot(QWidget* parent = NULL); virtual ~RiuResultQwtPlot(); - void addCurve(const QString& curveName, const cvf::Color3f& curveColor, const std::vector& dateTimes, const std::vector& timeHistoryValues); - void addCurve(const QString& curveName, const cvf::Color3f& curveColor, const std::vector& frameTimes, const std::vector& timeHistoryValues); + void addCurve(const QString& curveName, + const cvf::Color3f& curveColor, + const std::vector& dateTimes, + const std::vector& timeHistoryValues); + void addCurve(const QString& curveName, + const cvf::Color3f& curveColor, + const std::vector& frameTimes, + const std::vector& timeHistoryValues); void deleteAllCurves(); diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index db7df2c86a..0228cffe09 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -30,7 +30,6 @@ class QwtInterval; class QwtPicker; class QwtPlotMarker; -class RiuQwtCurvePointTracker; class RimSummaryPlot; //================================================================================================== @@ -78,8 +77,6 @@ private slots: void onAxisClicked(int axis, double value); private: - RiuQwtCurvePointTracker* m_curvePointTracker; - caf::PdmPointer m_plotDefinition; QPointer m_zoomerLeft; diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index 1f93563b4a..a278aa0b3b 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -25,8 +25,6 @@ class RimWellLogTrack; -class RiuQwtCurvePointTracker; - class QwtLegend; class QwtPicker; class QwtPlotGrid; @@ -67,6 +65,5 @@ private: private: caf::PdmPointer m_plotTrackDefinition; - RiuQwtCurvePointTracker* m_curvePointTracker; }; From 233c24849175b7e8526035a1511fa32b0f635d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 27 Mar 2017 18:22:09 +0200 Subject: [PATCH 16/28] #1366 Wheel works without Ctrl pressed --- .../UserInterface/RiuQwtPlotWheelZoomer.cpp | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp index d5c3baffae..72aee64f35 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp +++ b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.cpp @@ -53,23 +53,21 @@ bool RiuQwtPlotWheelZoomer::eventFilter(QObject * watched, QEvent * event) QWheelEvent* wheelEvent = dynamic_cast(event); if ( wheelEvent ) { - if ( wheelEvent->modifiers() ) + double zoomFactor = 1.0/RIU_SCROLLWHEEL_ZOOMFACTOR; + if ( wheelEvent->delta() > 0 ) { - double zoomFactor = 1.0/RIU_SCROLLWHEEL_ZOOMFACTOR; - if ( wheelEvent->delta() > 0 ) - { - zoomFactor = RIU_SCROLLWHEEL_ZOOMFACTOR; - } - - zoomOnAxis(m_plot, QwtPlot::xBottom, zoomFactor, wheelEvent->pos().x()); - zoomOnAxis(m_plot, QwtPlot::xTop, zoomFactor, wheelEvent->pos().x()); - zoomOnAxis(m_plot, QwtPlot::yLeft, zoomFactor, wheelEvent->pos().y()); - zoomOnAxis(m_plot, QwtPlot::yRight, zoomFactor, wheelEvent->pos().y()); - - m_plot->replot(); - emit zoomUpdated(); + zoomFactor = RIU_SCROLLWHEEL_ZOOMFACTOR; } + + zoomOnAxis(m_plot, QwtPlot::xBottom, zoomFactor, wheelEvent->pos().x()); + zoomOnAxis(m_plot, QwtPlot::xTop, zoomFactor, wheelEvent->pos().x()); + zoomOnAxis(m_plot, QwtPlot::yLeft, zoomFactor, wheelEvent->pos().y()); + zoomOnAxis(m_plot, QwtPlot::yRight, zoomFactor, wheelEvent->pos().y()); + + m_plot->replot(); + emit zoomUpdated(); } + return false; } From dc493b0b68275596afdb8003f6626b166ed068d0 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 27 Mar 2017 15:13:53 +0200 Subject: [PATCH 17/28] #1365 AppFwk : Allow list widgets to fill available height --- .../cafUserInterface/cafPdmUiListEditor.cpp | 43 ++++++++++++++++++- .../cafUserInterface/cafPdmUiListEditor.h | 12 +++--- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp index 4e1585b9a6..65fdf41e31 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp @@ -85,6 +85,45 @@ private: }; +//================================================================================================== +/// Helper class used to control height of size hint +//================================================================================================== +class QListViewHeightHint : public QListView +{ +public: + explicit QListViewHeightHint(QWidget *parent = 0) + : m_heightHint(-1) + { + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual QSize sizeHint() const override + { + QSize mySize = QListView::sizeHint(); + + if (m_heightHint > 0) + { + mySize.setHeight(m_heightHint); + } + + return mySize; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void setHeightHint(int heightHint) + { + m_heightHint = heightHint; + } + +private: + int m_heightHint; +}; + + namespace caf { @@ -151,6 +190,7 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) myPalette.setColor(QPalette::Base, attributes.m_baseColor); m_listView->setPalette(myPalette); + m_listView->setHeightHint(attributes.m_heightHint); } MyStringListModel* strListModel = dynamic_cast(m_model.data()); @@ -230,13 +270,12 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) } } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QWidget* PdmUiListEditor::createEditorWidget(QWidget * parent) { - m_listView = new QListView(parent); + m_listView = new QListViewHeightHint(parent); m_model = new MyStringListModel(m_listView); m_listView->setModel(m_model); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h index b68133c632..b5fd08105e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h @@ -42,7 +42,7 @@ class QGridLayout; class QStringListModel; class QItemSelection; -class QListView; +class QListViewHeightHint; class QLabel; class QModelIndex; @@ -56,7 +56,7 @@ class PdmUiListEditorAttribute : public PdmUiEditorAttribute { public: PdmUiListEditorAttribute() - : m_baseColor(Qt::white) + : m_heightHint(2000) { QPalette myPalette; @@ -64,7 +64,8 @@ public: } public: - QColor m_baseColor; + QColor m_baseColor; + int m_heightHint; }; @@ -95,15 +96,12 @@ private: void pasteFromString(const QString& content); private: - QPointer m_listView; + QPointer m_listView; QPointer m_label; QPointer m_model; QList m_options; bool m_optionsOnly; - - - }; From bf9d65d2492dc5f0c1c56523147608ae0618212a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 27 Mar 2017 15:20:11 +0200 Subject: [PATCH 18/28] #1365 Added sizeHint to QMinimizePanel --- .../cafUserInterface/QMinimizePanel.cpp | 22 +++++++++++++++++++ Fwk/AppFwk/cafUserInterface/QMinimizePanel.h | 1 + 2 files changed, 23 insertions(+) diff --git a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp index 893fdb0c53..fb19b92594 100644 --- a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp +++ b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp @@ -189,6 +189,28 @@ QString QMinimizePanel::title() const return m_titleLabel->text(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize QMinimizePanel::sizeHint() const +{ + QSize labelSize = m_titleLabel->sizeHint(); + QSize titleBarHint = labelSize + QSize(4 + labelSize.height() + 8 - 2 + 1, 8); + + if (!m_contentFrame->isHidden()) + { + QSize titleBarMin(0, labelSize.height() + 8); + QSize contentsMin(m_contentFrame->sizeHint()); + QSize total = contentsMin.expandedTo(titleBarMin); + total.rheight() += titleBarMin.height(); + return total; + } + else + { + return titleBarHint; + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h index 22d58c7069..3acc72ff97 100644 --- a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h +++ b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h @@ -53,6 +53,7 @@ public: QFrame * contentFrame() { return m_contentFrame; } void setTitle (const QString& title); QString title() const; + virtual QSize sizeHint() const override; public slots: void setExpanded(bool isExpanded); From 6e6e884ab39b81fc05ebbdc45a3d7913afd6aa0a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 27 Mar 2017 15:24:08 +0200 Subject: [PATCH 19/28] #1365 Whitespace and comment headers --- .../cafUserInterface/QMinimizePanel.cpp | 18 ++++++--- Fwk/AppFwk/cafUserInterface/QMinimizePanel.h | 37 +++++++++++-------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp index fb19b92594..9a08d6dbd4 100644 --- a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp +++ b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp @@ -33,14 +33,15 @@ // for more details. // //################################################################################################## + #include "QMinimizePanel.h" +#include #include +#include +#include #include #include -#include -#include "QApplication" -#include //-------------------------------------------------------------------------------------------------- /// @@ -128,6 +129,9 @@ QMinimizePanel::QMinimizePanel(const QString &title, QWidget* parent/*=0*/) this->initialize(title); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void QMinimizePanel::initialize(const QString &title) { m_titleFrame = new QFrame(this); @@ -159,7 +163,6 @@ void QMinimizePanel::initialize(const QString &title) QPalette contentFramePalette = m_contentFrame->palette(); contentFramePalette.setBrush(QPalette::Window, QColor(255,250,250,85)); - //contentFramePalette.setBrush(QPalette::Foreground, contentFramePalette.dark()); m_contentFrame->setPalette(contentFramePalette); connect(m_collapseButton, SIGNAL(clicked()),this, SLOT(toggleExpanded()) ); @@ -203,6 +206,7 @@ QSize QMinimizePanel::sizeHint() const QSize contentsMin(m_contentFrame->sizeHint()); QSize total = contentsMin.expandedTo(titleBarMin); total.rheight() += titleBarMin.height(); + return total; } else @@ -247,6 +251,7 @@ QSize QMinimizePanel::minimumSizeHint() const QSize contentsMin(m_contentFrame->minimumSizeHint()); QSize total = contentsMin.expandedTo(titleBarMin); total.rheight() += titleBarMin.height(); + return total; } else @@ -276,7 +281,10 @@ void QMinimizePanel::resizeEvent(QResizeEvent *resizeEv ) m_contentFrame->setGeometry(0, titleHeight-1, width, heigth - (titleHeight-1)); } -bool QMinimizePanel::event(QEvent* event) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool QMinimizePanel::event(QEvent* event) { if (event->type() == QEvent::LayoutRequest) { diff --git a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h index 3acc72ff97..f1738b58d8 100644 --- a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h +++ b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h @@ -42,7 +42,12 @@ class QFrame; class QLabel; class QPushButton; -class QMinimizePanel: public QWidget +//================================================================================================== +// +// +// +//================================================================================================== +class QMinimizePanel : public QWidget { Q_OBJECT public: @@ -50,31 +55,31 @@ public: explicit QMinimizePanel(const QString &title, QWidget* parent=0); ~QMinimizePanel(); - QFrame * contentFrame() { return m_contentFrame; } - void setTitle (const QString& title); - QString title() const; + QFrame* contentFrame() { return m_contentFrame; } + void setTitle (const QString& title); + QString title() const; + virtual QSize sizeHint() const override; public slots: - void setExpanded(bool isExpanded); - void toggleExpanded(); + void setExpanded(bool isExpanded); + void toggleExpanded(); signals: - void expandedChanged(bool isExpanded); + void expandedChanged(bool isExpanded); public: - virtual QSize minimumSizeHint() const override; + virtual QSize minimumSizeHint() const override; protected: - QFrame* m_titleFrame; - QLabel* m_titleLabel; - QPushButton* m_collapseButton; - QFrame* m_contentFrame; + QFrame* m_titleFrame; + QLabel* m_titleLabel; + QPushButton* m_collapseButton; + QFrame* m_contentFrame; - virtual void resizeEvent(QResizeEvent *) override; - virtual bool event(QEvent* event) override; // To catch QEvent::LayoutRequest + virtual void resizeEvent(QResizeEvent *) override; + virtual bool event(QEvent* event) override; // To catch QEvent::LayoutRequest private: - void initialize(const QString &title); + void initialize(const QString &title); }; - From dec65d0af44a12ac95b4fd3067e49e3c72bcc8e0 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 27 Mar 2017 22:54:13 +0200 Subject: [PATCH 20/28] #1365 Limit max height for result variable for flow --- .../RimEclipseResultDefinition.cpp | 16 ++++++++++++++++ .../RimEclipseResultDefinition.h | 1 + 2 files changed, 17 insertions(+) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 212c5c436b..6378fd1361 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -1009,6 +1009,22 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm uiOrdering.skipRemainingFields(true); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (m_resultTypeUiField() == RimDefines::FLOW_DIAGNOSTICS + && field == &m_resultVariableUiField) + { + caf::PdmUiListEditorAttribute* listEditAttr = dynamic_cast(attribute); + if (listEditAttr) + { + listEditAttr->m_heightHint = 50; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 1a6aa67832..e0a12d143d 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -101,6 +101,7 @@ protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual void initAfterRead(); virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; protected: caf::PdmField< caf::AppEnum< RimDefines::ResultCatType > > m_resultType; From a6ce3c9ef4643034c86b02e9acd62a0b94717da2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 28 Mar 2017 09:47:06 +0200 Subject: [PATCH 21/28] Fixed missing includes on Linux --- .../Flow/RimFlowCharacteristicsPlot.cpp | 10 ++++++---- .../ReservoirDataModel/RigFlowDiagResults.cpp | 11 +++++++++++ .../ReservoirDataModel/RigFlowDiagResults.h | 9 +++++---- .../UserInterface/RiuQwtCurvePointTracker.cpp | 3 +++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp index d19200dd67..5f3191fab5 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp @@ -18,14 +18,16 @@ #include "RimFlowCharacteristicsPlot.h" -#include "RimFlowDiagSolution.h" -#include "RimEclipseResultCase.h" - #include "RigFlowDiagResults.h" -#include "RiuFlowCharacteristicsPlot.h" +#include "RimEclipseResultCase.h" +#include "RimFlowDiagSolution.h" #include "RimProject.h" +#include "RiuFlowCharacteristicsPlot.h" + +#include // Needed for HUGE_VAL on Linux + CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot"); diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp index 5db6725bd1..ce61f758ea 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp @@ -29,6 +29,8 @@ #include "RigFlowDiagResultFrames.h" #include "RigStatisticsDataCache.h" +#include // Needed for HUGE_VAL on Linux + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -673,3 +675,12 @@ std::vector RigFlowDiagResults::calculatedTimeSteps() return timestepIndices; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResults::FlowCharacteristicsResultFrame::FlowCharacteristicsResultFrame() + : m_lorenzCoefficient(HUGE_VAL) +{ + +} diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h index 236e0616a3..fa230eb809 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h @@ -19,6 +19,10 @@ #include "RigFlowDiagResultAddress.h" +#include "RimFlowDiagSolution.h" + +#include "cafPdmPointer.h" + #include "cvfBase.h" #include "cvfObject.h" @@ -26,9 +30,6 @@ #include #include -#include "cafPdmPointer.h" -#include "RimFlowDiagSolution.h" - class RigFlowDiagResultFrames; class RigStatisticsDataCache; class RigFlowDiagSolverInterface; @@ -66,7 +67,7 @@ public: struct FlowCharacteristicsResultFrame { - FlowCharacteristicsResultFrame() : m_lorenzCoefficient(HUGE_VAL) {} + FlowCharacteristicsResultFrame(); using Curve = std::pair< std::vector, std::vector >; diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp index 38878ffba8..3c83ce3ae8 100644 --- a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp @@ -23,6 +23,9 @@ #include "qwt_plot_curve.h" #include "qwt_date_scale_draw.h" + +#include // For DBL_MAX + #include From 960e6833c4cebd3b04058149432cefe2780884ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 28 Mar 2017 23:30:01 +0200 Subject: [PATCH 22/28] #1321 Made zoom all and snapshot work --- ApplicationCode/Application/RiaApplication.cpp | 8 ++++++++ .../SummaryPlotCommands/RicViewZoomAllFeature.cpp | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index db0a1f2086..4c8ca5fe5c 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -49,6 +49,7 @@ #include "RimEclipseWellCollection.h" #include "RimFaultCollection.h" #include "RimFormationNamesCollection.h" +#include "RimFlowCharacteristicsPlot.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" #include "RimGeoMechModels.h" @@ -83,6 +84,7 @@ #include "RiuViewer.h" #include "RiuWellLogPlot.h" #include "RiuWellAllocationPlot.h" +#include "RiuFlowCharacteristicsPlot.h" #include "RicImportSummaryCaseFeature.h" #include "RicSnapshotViewToClipboardFeature.h" @@ -1648,6 +1650,12 @@ RimViewWindow* RiaApplication::activeViewWindow() { viewWindow = wellAllocationPlot->ownerPlotDefinition(); } + + RiuFlowCharacteristicsPlot* flowCharacteristicsPlot = dynamic_cast(subwindows.back()->widget()); + if (flowCharacteristicsPlot) + { + viewWindow = flowCharacteristicsPlot->ownerPlotDefinition(); + } } } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp index 2459c54cd8..f65a863ae6 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.cpp @@ -35,6 +35,8 @@ #include #include #include +#include "RiuFlowCharacteristicsPlot.h" +#include "RimFlowCharacteristicsPlot.h" CAF_CMD_SOURCE_INIT(RicViewZoomAllFeature, "RicViewZoomAllFeature"); @@ -100,6 +102,18 @@ void RicViewZoomAllFeature::onActionTriggered(bool isChecked) return; } } + + { + RiuFlowCharacteristicsPlot* flowCharPlot = dynamic_cast(subwindows.back()->widget()); + if (flowCharPlot) + { + RimFlowCharacteristicsPlot* viewWindow = flowCharPlot->ownerPlotDefinition(); + viewWindow->zoomAll(); + flowCharPlot->update(); + + return; + } + } } } } From ba60bf3c134a0b2dd560d31c5d85420181614597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 28 Mar 2017 23:35:53 +0200 Subject: [PATCH 23/28] #1321 Added a comand to show Flow Characteristics plot. Added timestp colors, zoom, mouse tracking, and titles --- .../Application/RiaColorTables.cpp | 27 +++ ApplicationCode/Application/RiaColorTables.h | 2 + .../FlowCommands/CMakeLists_files.cmake | 2 + .../RicAddStoredWellAllocationPlotFeature.cpp | 4 +- .../RicShowFlowCharacteristicsPlotFeature.cpp | 98 ++++++++++ .../RicShowFlowCharacteristicsPlotFeature.h | 40 +++++ .../RicShowWellAllocationPlotFeature.cpp | 6 +- .../Flow/RimFlowCharacteristicsPlot.cpp | 35 ++-- .../Flow/RimFlowCharacteristicsPlot.h | 2 - .../Flow/RimFlowPlotCollection.cpp | 58 +++--- .../Flow/RimFlowPlotCollection.h | 9 +- .../RimContextCommandBuilder.cpp | 6 + .../RiuFlowCharacteristicsPlot.cpp | 169 +++++++++++++++--- .../RiuFlowCharacteristicsPlot.h | 18 +- .../UserInterface/RiuViewerCommands.cpp | 2 + 15 files changed, 398 insertions(+), 80 deletions(-) create mode 100644 ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.cpp create mode 100644 ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h diff --git a/ApplicationCode/Application/RiaColorTables.cpp b/ApplicationCode/Application/RiaColorTables.cpp index 43a924319d..3452a01150 100644 --- a/ApplicationCode/Application/RiaColorTables.cpp +++ b/ApplicationCode/Application/RiaColorTables.cpp @@ -402,3 +402,30 @@ const caf::ColorTable& RiaColorTables::selectionPaletteColors() return colorTable; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const caf::ColorTable& RiaColorTables::timestepsPaletteColors() +{ + static std::vector colors{ + cvf::Color3ub( 56, 56, 255), // Vivid Blue + cvf::Color3ub( 0, 143, 239), // Dark Light Blue + cvf::Color3ub( 0, 112, 136), // Dark Green-Blue + cvf::Color3ub( 51, 204, 255), // Bluer Turquoise + cvf::Color3ub( 0, 221, 221), // Turquoise + cvf::Color3ub( 0, 205, 68), // Bluish Green + cvf::Color3ub( 78, 204, 0), // Clear Green + cvf::Color3ub(164, 193, 0), // Mid Yellowish Green + cvf::Color3ub(236, 188, 0), // Mid Yellow + cvf::Color3ub(236, 118, 0), // Orange + cvf::Color3ub(202, 0, 0), // Red + cvf::Color3ub(248, 0, 170), // Magenta + cvf::Color3ub(201, 168, 206), // Light Violet + cvf::Color3ub(169, 2, 240), // Purple + }; + + static caf::ColorTable colorTable = caf::ColorTable(colors); + + return colorTable; +} diff --git a/ApplicationCode/Application/RiaColorTables.h b/ApplicationCode/Application/RiaColorTables.h index fb4fc18b09..b40c3f95a1 100644 --- a/ApplicationCode/Application/RiaColorTables.h +++ b/ApplicationCode/Application/RiaColorTables.h @@ -48,4 +48,6 @@ public: static const caf::ColorTable& summaryCurveNoneRedGreenBlueBrownPaletteColors(); static const caf::ColorTable& wellLogPlotPaletteColors(); static const caf::ColorTable& selectionPaletteColors(); + static const caf::ColorTable& timestepsPaletteColors(); + }; diff --git a/ApplicationCode/Commands/FlowCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/FlowCommands/CMakeLists_files.cmake index aef7e3e590..62aa0b34c8 100644 --- a/ApplicationCode/Commands/FlowCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/FlowCommands/CMakeLists_files.cmake @@ -6,6 +6,7 @@ endif() set (SOURCE_GROUP_HEADER_FILES ${CEE_CURRENT_LIST_DIR}RicShowWellAllocationPlotFeature.h +${CEE_CURRENT_LIST_DIR}RicShowFlowCharacteristicsPlotFeature.h ${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature.h ${CEE_CURRENT_LIST_DIR}RicShowContributingWellsFromPlotFeature.h ${CEE_CURRENT_LIST_DIR}RicShowContributingWellsFeature.h @@ -16,6 +17,7 @@ ${CEE_CURRENT_LIST_DIR}RicSelectViewUI.h set (SOURCE_GROUP_SOURCE_FILES ${CEE_CURRENT_LIST_DIR}RicShowWellAllocationPlotFeature.cpp +${CEE_CURRENT_LIST_DIR}RicShowFlowCharacteristicsPlotFeature.cpp ${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature.cpp ${CEE_CURRENT_LIST_DIR}RicShowContributingWellsFromPlotFeature.cpp ${CEE_CURRENT_LIST_DIR}RicShowContributingWellsFeature.cpp diff --git a/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.cpp b/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.cpp index be7c8e1fae..d65d102229 100644 --- a/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.cpp +++ b/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.cpp @@ -47,7 +47,7 @@ bool RicAddStoredWellAllocationPlotFeature::isCommandEnabled() { RimWellAllocationPlot* wellAllocationPlot = dynamic_cast(caf::SelectionManager::instance()->selectedItem()); - if (flowPlotColl->defaultPlot() == wellAllocationPlot) + if (flowPlotColl->defaultWellAllocPlot() == wellAllocationPlot) { return true; } @@ -72,7 +72,7 @@ void RicAddStoredWellAllocationPlotFeature::onActionTriggered(bool isChecked) RimWellAllocationPlot* wellAllocationPlot = dynamic_cast(sourceObject->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); CVF_ASSERT(wellAllocationPlot); - flowPlotColl->addPlot(wellAllocationPlot); + flowPlotColl->addWellAllocPlotToStoredPlots(wellAllocationPlot); wellAllocationPlot->resolveReferencesRecursively(); wellAllocationPlot->loadDataAndUpdate(); diff --git a/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.cpp b/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.cpp new file mode 100644 index 0000000000..3aa4b902d3 --- /dev/null +++ b/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.cpp @@ -0,0 +1,98 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "RicShowFlowCharacteristicsPlotFeature.h" + +#include "RiaApplication.h" + +#include "RimEclipseResultCase.h" +#include "RimEclipseView.h" +#include "RimFlowCharacteristicsPlot.h" +#include "RimFlowPlotCollection.h" +#include "RimMainPlotCollection.h" +#include "RimProject.h" +#include "RimView.h" + +#include "RiuMainPlotWindow.h" + +#include + +CAF_CMD_SOURCE_INIT(RicShowFlowCharacteristicsPlotFeature, "RicShowFlowCharacteristicsPlotFeature"); + +RimEclipseResultCase* activeEclipseResultCase() +{ + RimView * activeView = RiaApplication::instance()->activeReservoirView(); + + auto eclView = dynamic_cast(activeView); + + if (!eclView) return nullptr; + + auto eclCase = dynamic_cast(eclView->ownerCase()); + + return eclCase; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicShowFlowCharacteristicsPlotFeature::isCommandEnabled() +{ + RimEclipseResultCase* eclCase = activeEclipseResultCase(); + + if (!eclCase) return false; + + if (!eclCase->defaultFlowDiagSolution()) return false; + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowFlowCharacteristicsPlotFeature::onActionTriggered(bool isChecked) +{ + RimEclipseResultCase* eclCase = activeEclipseResultCase(); + + if (eclCase && eclCase->defaultFlowDiagSolution()) + { + if (RiaApplication::instance()->project()) + { + RimFlowPlotCollection* flowPlotColl = RiaApplication::instance()->project()->mainPlotCollection->flowPlotCollection(); + if (flowPlotColl) + { + RiuMainPlotWindow* plotwindow = RiaApplication::instance()->getOrCreateAndShowMainPlotWindow(); + + flowPlotColl->defaultFlowCharacteristicsPlot()->setFromFlowSolution(eclCase->defaultFlowDiagSolution()); + flowPlotColl->defaultFlowCharacteristicsPlot()->updateConnectedEditors(); + + // Make sure the summary plot window is created and visible + plotwindow->selectAsCurrentItem(flowPlotColl->defaultFlowCharacteristicsPlot()); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowFlowCharacteristicsPlotFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/WellAllocPlot16x16.png")); + actionToSetup->setText("Plot Flow Characteristics"); +} diff --git a/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h b/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h new file mode 100644 index 0000000000..b9846b507a --- /dev/null +++ b/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "cafCmdFeature.h" + +class RimEclipseWell; + + +//================================================================================================== +/// +//================================================================================================== +class RicShowFlowCharacteristicsPlotFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled() override; + virtual void onActionTriggered( bool isChecked ) override; + virtual void setupActionLook( QAction* actionToSetup ) override; +}; + + diff --git a/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.cpp b/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.cpp index d6a2143609..51291eeb82 100644 --- a/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.cpp +++ b/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.cpp @@ -69,12 +69,12 @@ void RicShowWellAllocationPlotFeature::onActionTriggered(bool isChecked) RimFlowPlotCollection* flowPlotColl = RiaApplication::instance()->project()->mainPlotCollection->flowPlotCollection(); if (flowPlotColl) { - flowPlotColl->defaultPlot()->setFromSimulationWell(eclWell); - flowPlotColl->defaultPlot()->updateConnectedEditors(); + flowPlotColl->defaultWellAllocPlot()->setFromSimulationWell(eclWell); + flowPlotColl->defaultWellAllocPlot()->updateConnectedEditors(); // Make sure the summary plot window is created and visible RiuMainPlotWindow* plotwindow = RiaApplication::instance()->getOrCreateAndShowMainPlotWindow(); - plotwindow->selectAsCurrentItem(flowPlotColl->defaultPlot()); + plotwindow->selectAsCurrentItem(flowPlotColl->defaultWellAllocPlot()); } } } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp index 5f3191fab5..e5731d6e17 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp @@ -74,6 +74,7 @@ void RimFlowCharacteristicsPlot::setFromFlowSolution(RimFlowDiagSolution* flowSo } m_flowDiagSolution = flowSolution; + m_showWindow = true; loadDataAndUpdate(); } @@ -143,6 +144,7 @@ QWidget* RimFlowCharacteristicsPlot::viewWidget() //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::zoomAll() { + if (m_flowCharPlotWidget) m_flowCharPlotWidget->zoomAll(); } @@ -187,7 +189,7 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate() { updateMdiWindowVisibility(); - if (m_flowDiagSolution) + if (m_flowDiagSolution && m_flowCharPlotWidget) { RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); std::vector calculatedTimesteps = flowResult->calculatedTimeSteps(); @@ -195,23 +197,26 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate() std::vector timeStepDates = m_case->timeStepDates(); std::vector lorenzVals(timeStepDates.size(), HUGE_VAL); - for (int timeStepIdx: calculatedTimesteps) - { - lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx).m_lorenzCoefficient; + m_flowCharPlotWidget->removeAllCurves(); - if ( m_flowCharPlotWidget) - { - const auto & flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx); - m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx], - flowCharResults.m_flowCapStorageCapCurve.first, - flowCharResults.m_flowCapStorageCapCurve.second); - m_flowCharPlotWidget->addSweepEfficiencyCurve(timeStepDates[timeStepIdx], - flowCharResults.m_sweepEfficiencyCurve.first, - flowCharResults.m_sweepEfficiencyCurve.second); - } + for ( int timeStepIdx: calculatedTimesteps ) + { + lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx).m_lorenzCoefficient; + } + m_flowCharPlotWidget->setLorenzCurve(timeStepDates, lorenzVals); + + for ( int timeStepIdx: calculatedTimesteps ) + { + + const auto & flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx); + m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx], + flowCharResults.m_flowCapStorageCapCurve.first, + flowCharResults.m_flowCapStorageCapCurve.second); + m_flowCharPlotWidget->addSweepEfficiencyCurve(timeStepDates[timeStepIdx], + flowCharResults.m_sweepEfficiencyCurve.first, + flowCharResults.m_sweepEfficiencyCurve.second); } - if ( m_flowCharPlotWidget) m_flowCharPlotWidget->setLorenzCurve(timeStepDates, lorenzVals); } } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h index 5eb58b0ead..9cec121e0c 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h @@ -62,8 +62,6 @@ public: virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; virtual void deleteViewWidget() override; - - protected: // RimViewWindow overrides diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp index 0f0cacda1e..81fceff554 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.cpp @@ -36,12 +36,11 @@ RimFlowPlotCollection::RimFlowPlotCollection() CAF_PDM_InitFieldNoDefault(&m_flowCharacteristicsPlot, "FlowCharacteristicsPlot", "", "", "", ""); m_flowCharacteristicsPlot.uiCapability()->setUiHidden(true); - m_flowCharacteristicsPlot = new RimFlowCharacteristicsPlot; - CAF_PDM_InitFieldNoDefault(&m_defaultPlot, "DefaultFlowPlot", "", "", "", ""); - m_defaultPlot.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_defaultWellAllocPlot, "DefaultFlowPlot", "", "", "", ""); + m_defaultWellAllocPlot.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&m_flowPlots, "FlowPlots", "Stored Plots", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_storedWellAllocPlots, "FlowPlots", "Stored Plots", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -49,9 +48,9 @@ RimFlowPlotCollection::RimFlowPlotCollection() //-------------------------------------------------------------------------------------------------- RimFlowPlotCollection::~RimFlowPlotCollection() { - delete m_defaultPlot(); + delete m_defaultWellAllocPlot(); - m_flowPlots.deleteAllChildObjects(); + m_storedWellAllocPlots.deleteAllChildObjects(); } //-------------------------------------------------------------------------------------------------- @@ -59,12 +58,12 @@ RimFlowPlotCollection::~RimFlowPlotCollection() //-------------------------------------------------------------------------------------------------- void RimFlowPlotCollection::closeDefaultPlotWindowAndDeletePlots() { - if ( m_defaultPlot ) + if ( m_defaultWellAllocPlot ) { - m_defaultPlot->removeFromMdiAreaAndDeleteViewWidget(); - delete m_defaultPlot(); + m_defaultWellAllocPlot->removeFromMdiAreaAndDeleteViewWidget(); + delete m_defaultWellAllocPlot(); } - m_flowPlots.deleteAllChildObjects(); + m_storedWellAllocPlots.deleteAllChildObjects(); } //-------------------------------------------------------------------------------------------------- @@ -72,12 +71,12 @@ void RimFlowPlotCollection::closeDefaultPlotWindowAndDeletePlots() //-------------------------------------------------------------------------------------------------- void RimFlowPlotCollection::loadDataAndUpdate() { - caf::ProgressInfo plotProgress(m_flowPlots.size() + 1, ""); + caf::ProgressInfo plotProgress(m_storedWellAllocPlots.size() + 1, ""); - if (m_defaultPlot) m_defaultPlot->loadDataAndUpdate(); + if (m_defaultWellAllocPlot) m_defaultWellAllocPlot->loadDataAndUpdate(); plotProgress.incrementProgress(); - for (RimWellAllocationPlot* p : m_flowPlots) + for (RimWellAllocationPlot* p : m_storedWellAllocPlots) { p->loadDataAndUpdate(); plotProgress.incrementProgress(); @@ -90,31 +89,46 @@ void RimFlowPlotCollection::loadDataAndUpdate() size_t RimFlowPlotCollection::plotCount() const { size_t plotCount = 0; - if (m_defaultPlot) plotCount = 1; - plotCount += m_flowPlots.size(); + if (m_defaultWellAllocPlot) plotCount = 1; + plotCount += m_storedWellAllocPlots.size(); return plotCount; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFlowPlotCollection::addPlot(RimWellAllocationPlot* plot) +void RimFlowPlotCollection::addWellAllocPlotToStoredPlots(RimWellAllocationPlot* plot) { - m_flowPlots.push_back(plot); + m_storedWellAllocPlots.push_back(plot); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellAllocationPlot* RimFlowPlotCollection::defaultPlot() +RimWellAllocationPlot* RimFlowPlotCollection::defaultWellAllocPlot() { - if ( !m_defaultPlot() ) + if ( !m_defaultWellAllocPlot() ) { - m_defaultPlot = new RimWellAllocationPlot; - m_defaultPlot->setDescription("Default Flow Diagnostics Plot"); + m_defaultWellAllocPlot = new RimWellAllocationPlot; + m_defaultWellAllocPlot->setDescription("Default Flow Diagnostics Plot"); } this->updateConnectedEditors(); - return m_defaultPlot(); + return m_defaultWellAllocPlot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFlowCharacteristicsPlot* RimFlowPlotCollection::defaultFlowCharacteristicsPlot() +{ + if ( !m_flowCharacteristicsPlot() ) + { + m_flowCharacteristicsPlot = new RimFlowCharacteristicsPlot; + } + + this->updateConnectedEditors(); + + return m_flowCharacteristicsPlot(); } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h index 0868fcddd0..b7af74f634 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h @@ -40,11 +40,12 @@ public: void loadDataAndUpdate(); size_t plotCount() const; - void addPlot(RimWellAllocationPlot* plot); - RimWellAllocationPlot* defaultPlot(); + void addWellAllocPlotToStoredPlots(RimWellAllocationPlot* plot); + RimWellAllocationPlot* defaultWellAllocPlot(); + RimFlowCharacteristicsPlot* defaultFlowCharacteristicsPlot(); private: caf::PdmChildField m_flowCharacteristicsPlot; - caf::PdmChildField m_defaultPlot; - caf::PdmChildArrayField m_flowPlots; + caf::PdmChildField m_defaultWellAllocPlot; + caf::PdmChildArrayField m_storedWellAllocPlots; }; diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index d3fdd2cf86..a159daccea 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -34,6 +34,7 @@ #include "RimEclipseView.h" #include "RimEclipseWell.h" #include "RimFault.h" +#include "RimFlowDiagSolution.h" #include "RimFormationNames.h" #include "RimFormationNamesCollection.h" #include "RimGeoMechCase.h" @@ -137,6 +138,7 @@ QStringList RimContextCommandBuilder::commandsFromSelection() commandIds << "Separator"; commandIds << "RicNewViewFeature"; + commandIds << "RicShowFlowCharacteristicsPlotFeature"; commandIds << "RicEclipseCaseNewGroupFeature"; commandIds << "Separator"; commandIds << "RicCopyReferencesToClipboardFeature"; @@ -353,6 +355,10 @@ QStringList RimContextCommandBuilder::commandsFromSelection() { commandIds << "RicAddStoredWellAllocationPlotFeature"; } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicShowFlowCharacteristicsPlotFeature"; + } if (dynamic_cast(uiItem)) diff --git a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp index ac8a0d2107..286aa4d895 100644 --- a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp +++ b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp @@ -30,6 +30,12 @@ #include #include "RiuLineSegmentQwtPlotCurve.h" #include +#include "RiuSummaryQwtPlot.h" +#include "RiuQwtPlotWheelZoomer.h" +#include "qwt_plot_zoomer.h" +#include "RiaColorTables.h" +#include "qwt_plot_zoneitem.h" +#include "qwt_date.h" @@ -42,10 +48,10 @@ RiuFlowCharacteristicsPlot::RiuFlowCharacteristicsPlot(RimFlowCharacteristicsPlo { Q_ASSERT(m_plotDefinition); - QVBoxLayout* mainLayout = new QVBoxLayout(); + QGridLayout* mainLayout = new QGridLayout(); this->setLayout(mainLayout); - this->layout()->setMargin(0); - this->layout()->setSpacing(2); + this->layout()->setMargin(3); + this->layout()->setSpacing(3); // White background QPalette pal = this->palette(); @@ -53,15 +59,39 @@ RiuFlowCharacteristicsPlot::RiuFlowCharacteristicsPlot(RimFlowCharacteristicsPlo this->setAutoFillBackground(true); this->setPalette(pal); - m_lorenzPlot = new RiuResultQwtPlot(this); - m_flowCapVsStorageCapPlot = new RiuResultQwtPlot(this); - m_sweepEffPlot = new RiuResultQwtPlot(this); - mainLayout->addWidget(m_lorenzPlot); - mainLayout->addWidget(m_flowCapVsStorageCapPlot); - mainLayout->addWidget(m_sweepEffPlot); - + m_lorenzPlot = new QwtPlot(this); + m_flowCapVsStorageCapPlot = new QwtPlot(this); + m_sweepEffPlot = new QwtPlot(this); + + mainLayout->addWidget(m_lorenzPlot, 0 ,0, 1, 2); + mainLayout->addWidget(m_flowCapVsStorageCapPlot, 1, 0); + mainLayout->addWidget(m_sweepEffPlot, 1, 1); + + RiuSummaryQwtPlot::setCommonPlotBehaviour(m_lorenzPlot); + new RiuQwtPlotWheelZoomer(m_lorenzPlot); + addWindowZoom(m_lorenzPlot); + RiuSummaryQwtPlot::enableDateBasedBottomXAxis(m_lorenzPlot); + m_lorenzPlot->setTitle("Lorenz Coefficient"); + + RiuSummaryQwtPlot::setCommonPlotBehaviour(m_sweepEffPlot); + new RiuQwtPlotWheelZoomer(m_sweepEffPlot); + addWindowZoom(m_sweepEffPlot); + m_sweepEffPlot->setTitle("Sweep Efficiency"); + + RiuSummaryQwtPlot::setCommonPlotBehaviour(m_flowCapVsStorageCapPlot); + new RiuQwtPlotWheelZoomer(m_flowCapVsStorageCapPlot); + addWindowZoom(m_flowCapVsStorageCapPlot); + m_flowCapVsStorageCapPlot->setTitle("Flow Capacity vs Storage Capacity"); } +void RiuFlowCharacteristicsPlot::addWindowZoom(QwtPlot* plot) +{ + auto zoomer = new QwtPlotZoomer(plot->canvas()); + zoomer->setRubberBandPen(QColor(Qt::black)); + zoomer->setTrackerMode(QwtPicker::AlwaysOff); + zoomer->setTrackerPen(QColor(Qt::black)); + zoomer->initMousePattern(1); +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -78,8 +108,56 @@ RiuFlowCharacteristicsPlot::~RiuFlowCharacteristicsPlot() //-------------------------------------------------------------------------------------------------- void RiuFlowCharacteristicsPlot::setLorenzCurve(const std::vector& dateTimes, const std::vector& timeHistoryValues) { - m_lorenzPlot->deleteAllCurves(); - m_lorenzPlot->addCurve("Lorenz Coefficient", cvf::Color3f::BLUE, dateTimes, timeHistoryValues); + initializeColors(dateTimes); + + m_lorenzPlot->detachItems(QwtPlotItem::Rtti_PlotCurve, true); + auto curve = createEmptyCurve(m_lorenzPlot, "Lorenz Coefficient", QColor(0, 0, 0)); + curve->setSamplesFromDateAndValues(dateTimes, timeHistoryValues, false); + //curve->setSymbol(QwtSymbol ) + + //size_t tsIdx = 0; + //for ( const QDateTime& dateTime: dateTimes ) + //{ + // auto curve = createEmptyCurve(m_lorenzPlot, dateTime.toString(), m_dateToColorMap[dateTime]); + // std::vector timeStep; + // timeStep.push_back(dateTime); + // std::vector lorCoeff; + // lorCoeff.push_back(timeHistoryValues[tsIdx]); + // + // curve->setSamplesFromDateAndValues(timeStep, lorCoeff, false); + // + // ++tsIdx; + //} + //double milliSecSinceEpoch = QwtDate::toDouble(filteredDateTimes[i]); + + for ( size_t tsIdx = 0; tsIdx < dateTimes.size(); ++tsIdx ) + { + double currentTsValue = QwtDate::toDouble(dateTimes[tsIdx]); + + double minTsValue = currentTsValue; + if ( tsIdx > 0 ) minTsValue = 0.5 * (currentTsValue + QwtDate::toDouble(dateTimes[tsIdx-1])); + + double maxTsValue = currentTsValue; + if ( tsIdx < dateTimes.size()-1 ) maxTsValue = 0.5 * (currentTsValue + QwtDate::toDouble(dateTimes[tsIdx+1])); + + auto plotZone = new QwtPlotZoneItem(); + plotZone->setOrientation(Qt::Vertical); + plotZone->setInterval(minTsValue, maxTsValue); + plotZone->setBrush(QBrush(m_dateToColorMap[dateTimes[tsIdx]])); + plotZone->attach(m_lorenzPlot); + } + + m_lorenzPlot->replot(); +} + +RiuLineSegmentQwtPlotCurve* RiuFlowCharacteristicsPlot::createEmptyCurve(QwtPlot* plot, const QString& curveName, const QColor& curveColor ) +{ + RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve(curveName); + + plotCurve->setTitle(curveName); + plotCurve->setPen(QPen(curveColor)); + plotCurve->attach(plot); + return plotCurve; } //-------------------------------------------------------------------------------------------------- @@ -87,16 +165,10 @@ void RiuFlowCharacteristicsPlot::setLorenzCurve(const std::vector& da //-------------------------------------------------------------------------------------------------- void RiuFlowCharacteristicsPlot::addFlowCapStorageCapCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals) { - RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve(dateTime.toString()); + CVF_ASSERT(!m_dateToColorMap.empty()); + + RiuLineSegmentQwtPlotCurve* plotCurve = createEmptyCurve(m_flowCapVsStorageCapPlot, dateTime.toString(), m_dateToColorMap[dateTime]); plotCurve->setSamplesFromTimeAndValues(xVals, yVals, false); - plotCurve->setTitle(dateTime.toString()); - - plotCurve->setPen(QPen(QColor(180, 0, 20))); - - plotCurve->attach(m_flowCapVsStorageCapPlot); - - m_flowCapVsStorageCapPlot->setAxisScale( QwtPlot::xBottom, 0.0, 1.0); - m_flowCapVsStorageCapPlot->replot(); } @@ -105,19 +177,42 @@ void RiuFlowCharacteristicsPlot::addFlowCapStorageCapCurve(const QDateTime& date //-------------------------------------------------------------------------------------------------- void RiuFlowCharacteristicsPlot::addSweepEfficiencyCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals) { - RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve(dateTime.toString()); + CVF_ASSERT(!m_dateToColorMap.empty()); + + RiuLineSegmentQwtPlotCurve* plotCurve = createEmptyCurve(m_sweepEffPlot, dateTime.toString(), m_dateToColorMap[dateTime]); plotCurve->setSamplesFromTimeAndValues(xVals, yVals, false); - plotCurve->setTitle(dateTime.toString()); - - plotCurve->setPen(QPen(QColor(180, 0, 20))); - - plotCurve->attach(m_sweepEffPlot); - - //m_sweepEffPlot->setAxisScale( QwtPlot::xBottom, 0.0, 1.0); m_sweepEffPlot->replot(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::removeAllCurves() +{ + m_lorenzPlot->detachItems(QwtPlotItem::Rtti_PlotCurve, true); + m_sweepEffPlot->detachItems(QwtPlotItem::Rtti_PlotCurve, true); + m_flowCapVsStorageCapPlot->detachItems(QwtPlotItem::Rtti_PlotCurve, true); + m_dateToColorMap.clear(); +} + +void zoomAllInPlot(QwtPlot * plot) +{ + plot->setAxisAutoScale(QwtPlot::xBottom, true); + plot->setAxisAutoScale(QwtPlot::yLeft, true); + plot->replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::zoomAll() +{ + zoomAllInPlot(m_lorenzPlot); + zoomAllInPlot(m_sweepEffPlot); + zoomAllInPlot(m_flowCapVsStorageCapPlot); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -152,3 +247,19 @@ void RiuFlowCharacteristicsPlot::setDefaults() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuFlowCharacteristicsPlot::initializeColors(const std::vector& dateTimes) +{ + CVF_ASSERT(m_dateToColorMap.empty()); + + const caf::ColorTable& palette = RiaColorTables::timestepsPaletteColors(); + cvf::Color3ubArray colorArray = caf::ColorTable::interpolateColorArray(palette.color3ubArray(), dateTimes.size()); + + for (size_t tsIdx = 0; tsIdx < dateTimes.size(); ++tsIdx) + { + m_dateToColorMap[dateTimes[tsIdx]] = QColor( colorArray[tsIdx].r(), colorArray[tsIdx].g(), colorArray[tsIdx].b()); + } +} + diff --git a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h index 6de6647d1f..ea3e4c62ea 100644 --- a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h +++ b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h @@ -28,6 +28,7 @@ class RimFlowCharacteristicsPlot; class RiuNightchartsWidget; class RiuResultQwtPlot; +class RiuLineSegmentQwtPlotCurve; class QLabel; @@ -51,8 +52,14 @@ public: void addFlowCapStorageCapCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals); void addSweepEfficiencyCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals); + void removeAllCurves(); + void zoomAll(); + RimFlowCharacteristicsPlot* ownerPlotDefinition(); + static void addWindowZoom(QwtPlot* plot); + static RiuLineSegmentQwtPlotCurve* createEmptyCurve(QwtPlot* plot, const QString& curveName, const QColor& curveColor); + protected: virtual QSize sizeHint() const override; virtual QSize minimumSizeHint() const override; @@ -60,11 +67,16 @@ protected: private: void setDefaults(); + + void initializeColors(const std::vector& dateTimes); + private: caf::PdmPointer m_plotDefinition; - QPointer m_lorenzPlot; - QPointer m_flowCapVsStorageCapPlot; - QPointer m_sweepEffPlot; + QPointer m_lorenzPlot; + QPointer m_flowCapVsStorageCapPlot; + QPointer m_sweepEffPlot; + + std::map m_dateToColorMap; }; diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.cpp b/ApplicationCode/UserInterface/RiuViewerCommands.cpp index 34edfa152e..39c48f0a22 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.cpp +++ b/ApplicationCode/UserInterface/RiuViewerCommands.cpp @@ -328,6 +328,8 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) commandIds << "Separator"; commandIds << "RicNewGridTimeHistoryCurveFeature"; + commandIds << "RicShowFlowCharacteristicsPlotFeature"; + RimContextCommandBuilder::appendCommandsToMenu(commandIds, &menu); From c257c529447782eb3c1e661987b4519e939a012b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 29 Mar 2017 07:47:14 +0200 Subject: [PATCH 24/28] #1367 Fixed regression related to edit of items in ListView --- .../cafUserInterface/cafPdmUiListEditor.cpp | 84 ++++++++++--------- .../cafUserInterface/cafPdmUiListEditor.h | 5 +- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp index 65fdf41e31..75865cac22 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp @@ -58,7 +58,6 @@ - //================================================================================================== /// Helper class used to override flags to disable editable items //================================================================================================== @@ -137,12 +136,12 @@ CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiListEditor); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiListEditor::PdmUiListEditor(): m_optionsOnly(true) +PdmUiListEditor::PdmUiListEditor() : + m_isEditOperationsAvailable(true), + m_optionItemCount(0) { } - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -180,6 +179,14 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) m_listView->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_listView->setToolTip(field()->uiToolTip(uiConfigName)); + bool optionsOnly = true; + QList options = field()->valueOptions(&optionsOnly); + m_optionItemCount = options.size(); + if (options.size() > 0 || field()->isUiReadOnly(uiConfigName)) + { + m_isEditOperationsAvailable = false; + } + PdmUiListEditorAttribute attributes; caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); if (uiObject) @@ -197,14 +204,13 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) CAF_ASSERT(strListModel); - m_options = field()->valueOptions(&m_optionsOnly); - if (!m_options.isEmpty()) + if (!options.isEmpty()) { - CAF_ASSERT(m_optionsOnly); // Handling Additions on the fly not implemented + CAF_ASSERT(optionsOnly); // Handling Additions on the fly not implemented strListModel->setItemsEditable(false); QModelIndex currentItem = m_listView->selectionModel()->currentIndex(); - QStringList texts = PdmOptionItemInfo::extractUiTexts(m_options); + QStringList texts = PdmOptionItemInfo::extractUiTexts(options); strListModel->setStringList(texts); QVariant fieldValue = field()->uiValue(); @@ -306,7 +312,7 @@ QWidget* PdmUiListEditor::createLabelWidget(QWidget * parent) //-------------------------------------------------------------------------------------------------- void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) { - if (m_options.isEmpty()) return; + if (m_optionItemCount == 0) return; QVariant fieldValue = field()->uiValue(); if (fieldValue.type() == QVariant::Int || fieldValue.type() == QVariant::UInt) @@ -323,7 +329,7 @@ void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, cons QModelIndexList idxList = m_listView->selectionModel()->selectedIndexes(); if (idxList.size() >= 1) { - if (idxList[0].row() < m_options.size()) + if (idxList[0].row() < m_optionItemCount) { this->setValueToField(QVariant(static_cast(idxList[0].row()))); } @@ -354,7 +360,7 @@ void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, cons QList valuesToSetInField; for (int i = 0; i < idxList.size(); ++i) { - if (idxList[i].row() < m_options.size()) + if (idxList[i].row() < m_optionItemCount) { valuesToSetInField.push_back(QVariant(static_cast(idxList[i].row()))); } @@ -363,13 +369,13 @@ void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, cons this->setValueToField(valuesToSetInField); } } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiListEditor::slotListItemEdited(const QModelIndex&, const QModelIndex&) { - if (m_optionsOnly) return; - CAF_ASSERT(m_options.isEmpty()); // Not supported yet + CAF_ASSERT(m_isEditOperationsAvailable); QStringList uiList = m_model->stringList(); @@ -437,37 +443,39 @@ bool PdmUiListEditor::eventFilter(QObject* object, QEvent * event) if (object == m_listView && event->type() == QEvent::KeyPress) { - if (m_optionsOnly) return false; - CAF_ASSERT(m_options.isEmpty()); // Not supported yet - QKeyEvent* keyEv = static_cast(event); - if (keyEv->key() == Qt::Key_Delete || keyEv->key() == Qt::Key_Backspace ) + + if (m_isEditOperationsAvailable) { - QModelIndexList idxList = m_listView->selectionModel()->selectedIndexes(); - bool isAnyDeleted = false; - while(idxList.size()) + if (keyEv->key() == Qt::Key_Delete || keyEv->key() == Qt::Key_Backspace ) { - m_model->removeRow(idxList[0].row()); - idxList = m_listView->selectionModel()->selectedIndexes(); - isAnyDeleted = true; - } - - if (isAnyDeleted) - { - QStringList uiList = m_model->stringList(); - - // Remove dummy elements specifically at the end of list. - - QStringList result; - foreach (const QString &str, uiList) + QModelIndexList idxList = m_listView->selectionModel()->selectedIndexes(); + bool isAnyDeleted = false; + while(idxList.size()) { - if (str != "" && str != " ") result += str; + m_model->removeRow(idxList[0].row()); + idxList = m_listView->selectionModel()->selectedIndexes(); + isAnyDeleted = true; } - this->setValueToField(result); + + if (isAnyDeleted) + { + QStringList uiList = m_model->stringList(); + + // Remove dummy elements specifically at the end of list. + + QStringList result; + foreach (const QString &str, uiList) + { + if (str != "" && str != " ") result += str; + } + this->setValueToField(result); + } + return true; } - return true; } - else if (keyEv->modifiers() & Qt::ControlModifier) + + if (keyEv->modifiers() & Qt::ControlModifier) { if (keyEv->key() == Qt::Key_C) { @@ -480,7 +488,7 @@ bool PdmUiListEditor::eventFilter(QObject* object, QEvent * event) return true; } } - else if (keyEv->key() == Qt::Key_V) + else if (m_isEditOperationsAvailable && keyEv->key() == Qt::Key_V) { QClipboard* clipboard = QApplication::clipboard(); if (clipboard) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h index b5fd08105e..c088bbf056 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h @@ -39,7 +39,6 @@ #include "cafPdmUiFieldEditorHandle.h" -class QGridLayout; class QStringListModel; class QItemSelection; class QListViewHeightHint; @@ -100,8 +99,8 @@ private: QPointer m_label; QPointer m_model; - QList m_options; - bool m_optionsOnly; + bool m_isEditOperationsAvailable; + int m_optionItemCount; }; From 3007a62238cf3ef99fc0fd1634ed7b7e1fe59d84 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 29 Mar 2017 08:13:45 +0200 Subject: [PATCH 25/28] System : Improved control of cotire --- CMakeLists.txt | 3 --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c14bc938ad..0af37fbedb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,9 +104,6 @@ if(RESINSIGHT_ENABLE_COTIRE) set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(cotire) - - set(CAF_USE_COTIRE TRUE CACHE INTERNAL "CAF: Use cotire") - endif() diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 23148be42c..deae069417 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -141,7 +141,7 @@ target_link_libraries ( ${PROJECT_NAME} ${QT_LIBRARIES} ) -if (CAF_USE_COTIRE) +if (COMMAND cotire) cotire(${PROJECT_NAME}) # make sure the unity target is included in the active builds to trigger rebuild before debug From a7b3bca94a7c3189227adf80f5e4e2ac684496ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 29 Mar 2017 09:28:14 +0200 Subject: [PATCH 26/28] #1321 Added timestep selection to the Flow Characteristics plot --- .../Flow/RimFlowCharacteristicsPlot.cpp | 64 ++++++++++++++++++- .../Flow/RimFlowCharacteristicsPlot.h | 16 ++++- .../RimContextCommandBuilder.cpp | 5 ++ 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp index e5731d6e17..12dd9ac24f 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp @@ -29,6 +29,17 @@ #include // Needed for HUGE_VAL on Linux +namespace caf +{ +template<> +void AppEnum< RimFlowCharacteristicsPlot::TimeSelectionType >::setUp() +{ + addItem(RimFlowCharacteristicsPlot::ALL_AVAILABLE, "ALL_AVAILABLE", "All available"); + addItem(RimFlowCharacteristicsPlot::SELECT_AVAILABLE, "SELECT_AVAILABLE", "Select"); + setDefault(RimFlowCharacteristicsPlot::ALL_AVAILABLE); +} +} + CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot"); @@ -41,6 +52,8 @@ RimFlowCharacteristicsPlot::RimFlowCharacteristicsPlot() CAF_PDM_InitFieldNoDefault(&m_case, "FlowCase", "Case", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Flow Diag Solution", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_timeStepSelectionType, "TimeSelectionType", "Time Steps", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "SelectedTimeSteps", "", "", "", ""); this->m_showWindow = false; setAsPlotMdiWindow(); @@ -126,11 +139,40 @@ QList RimFlowCharacteristicsPlot::calculateValueOptions( } } } + else if ( fieldNeedingOptions == &m_selectedTimeSteps ) + { + if ( m_flowDiagSolution ) + { + RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); + std::vector calculatedTimesteps = flowResult->calculatedTimeSteps(); + + std::vector timeStepDates = m_case->timeStepDates(); + + for ( int tsIdx : calculatedTimesteps ) + { + options.push_back(caf::PdmOptionItemInfo(timeStepDates[tsIdx].toString(), tsIdx)); + } + } + } return options; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_case); + uiOrdering.add(&m_flowDiagSolution); + uiOrdering.add(&m_timeStepSelectionType); + + if (m_timeStepSelectionType == SELECT_AVAILABLE) uiOrdering.add(&m_selectedTimeSteps); + + uiOrdering.skipRemainingFields(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -155,12 +197,14 @@ void RimFlowCharacteristicsPlot::fieldChangedByUi(const caf::PdmFieldHandle* cha { RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue); - if ( &m_case == changedField - || &m_flowDiagSolution == changedField) + if ( &m_case == changedField ) { - this->loadDataAndUpdate(); + m_flowDiagSolution = m_case->defaultFlowDiagSolution(); } + // All fields update plot + + this->loadDataAndUpdate(); } @@ -194,6 +238,20 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate() RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); std::vector calculatedTimesteps = flowResult->calculatedTimeSteps(); + if (m_timeStepSelectionType == SELECT_AVAILABLE) + { + // Find set intersection of selected and available time steps + std::set calculatedTimeStepsSet; + calculatedTimeStepsSet.insert(calculatedTimesteps.begin(), calculatedTimesteps.end()); + calculatedTimesteps.clear(); + + auto selectedTimeSteps = m_selectedTimeSteps(); + for (int tsIdx : selectedTimeSteps) + { + if (calculatedTimeStepsSet.count(tsIdx)) calculatedTimesteps.push_back(tsIdx); + } + } + std::vector timeStepDates = m_case->timeStepDates(); std::vector lorenzVals(timeStepDates.size(), HUGE_VAL); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h index 9cec121e0c..f11932a94c 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h @@ -62,6 +62,11 @@ public: virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; virtual void deleteViewWidget() override; + enum TimeSelectionType + { + ALL_AVAILABLE, + SELECT_AVAILABLE + }; protected: // RimViewWindow overrides @@ -71,10 +76,15 @@ protected: // Overridden PDM methods virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: - caf::PdmPtrField m_case; - caf::PdmPtrField m_flowDiagSolution; - QPointer m_flowCharPlotWidget; + + caf::PdmPtrField m_case; + caf::PdmPtrField m_flowDiagSolution; + caf::PdmField > m_timeStepSelectionType; + caf::PdmField > m_selectedTimeSteps; + + QPointer m_flowCharPlotWidget; }; diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index a159daccea..7465e4f8e9 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -35,6 +35,7 @@ #include "RimEclipseWell.h" #include "RimFault.h" #include "RimFlowDiagSolution.h" +#include "RimFlowPlotCollection.h" #include "RimFormationNames.h" #include "RimFormationNamesCollection.h" #include "RimGeoMechCase.h" @@ -359,6 +360,10 @@ QStringList RimContextCommandBuilder::commandsFromSelection() { commandIds << "RicShowFlowCharacteristicsPlotFeature"; } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicShowFlowCharacteristicsPlotFeature"; + } if (dynamic_cast(uiItem)) From ceec6cb9ec709ab55855660248fc554a492637f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Wed, 29 Mar 2017 11:21:06 +0200 Subject: [PATCH 27/28] #1353 Compute valid statistics for parameters with results for all cells --- .../RigEclipseNativeVisibleCellsStatCalc.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h index f5a229a04f..beb4283b9e 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h @@ -64,7 +64,11 @@ private: { if (!(*m_cellVisibilities)[cIdx]) continue; - size_t cellResultIndex = actCellInfo->cellResultIndex(cIdx); + size_t cellResultIndex = cIdx; + if (m_caseData->isUsingGlobalActiveIndex(m_scalarResultIndex)) + { + cellResultIndex = actCellInfo->cellResultIndex(cIdx); + } if (cellResultIndex != cvf::UNDEFINED_SIZE_T) accumulator.addValue(values[cellResultIndex]); } From e998f09250ddcbe95e4388168940f5fa6fd8ffed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Wed, 29 Mar 2017 11:22:04 +0200 Subject: [PATCH 28/28] Fixed typo --- ApplicationCode/UserInterface/RiuResultInfoPanel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp index b49341938d..e6c5a8d74d 100644 --- a/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp @@ -79,6 +79,6 @@ void RiuResultInfoPanel::convertStringToHTML(QString* str) //-------------------------------------------------------------------------------------------------- QSize RiuResultInfoPanel::sizeHint () const { - // As small as possible fow now + // As small as possible for now return QSize(20, 20); }