From 2639c7172fde2e1ed5f519748b17205dfc4ea8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Herje?= <82032112+jorgenherje@users.noreply.github.com> Date: Mon, 12 Jun 2023 15:44:39 +0200 Subject: [PATCH] Fix bug in color mapping when changing mapping mode for Tables * Fix color mapping and ticks in table legend - For Summary and WellConnectivity - Add range types: automatic and user defined - Remove category from mapping type - Add closest to zero for correct logarithmic scale --------- Co-authored-by: Magne Sjaastad --- .../Flow/RimWellConnectivityTable.cpp | 55 +++++++++++++++- .../Flow/RimWellConnectivityTable.h | 11 ++++ .../RimRegularLegendConfig.cpp | 17 ++++- .../ProjectDataModel/RimRegularLegendConfig.h | 3 +- .../Summary/RimSummaryTable.cpp | 62 ++++++++++++++++++- .../Summary/RimSummaryTable.h | 11 ++++ .../UserInterface/RiuMatrixPlotWidget.cpp | 16 ++++- .../RiuScalarMapperLegendFrame.cpp | 8 +++ .../RiuScalarMapperLegendFrame.h | 1 + 9 files changed, 175 insertions(+), 9 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp index 54c350079e..5f81a4f6f3 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp @@ -103,6 +103,14 @@ void AppEnum::setUp() addItem( RimWellConnectivityTable::TimeStepRangeFilterMode::TIME_STEP_COUNT, "TIME_STEP_COUNT", "Time Step Count" ); setDefault( RimWellConnectivityTable::TimeStepRangeFilterMode::TIME_STEP_COUNT ); } + +template <> +void AppEnum::setUp() +{ + addItem( RimWellConnectivityTable::RangeType::AUTOMATIC, "AUTOMATIC", "Min and Max in Table" ); + addItem( RimWellConnectivityTable::RangeType::USER_DEFINED, "USER_DEFINED_MAX_MIN", "User Defined Range" ); + setDefault( RimWellConnectivityTable::RangeType::AUTOMATIC ); +} } // namespace caf //-------------------------------------------------------------------------------------------------- @@ -178,6 +186,9 @@ RimWellConnectivityTable::RimWellConnectivityTable() m_legendConfig->setAutomaticRanges( 0.0, 100.0, 0.0, 100.0 ); m_legendConfig->setColorLegend( RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::HEAT_MAP ) ); + CAF_PDM_InitFieldNoDefault( &m_mappingType, "MappingType", "Mapping Type" ); + CAF_PDM_InitFieldNoDefault( &m_rangeType, "RangeType", "Range Type" ); + setLegendsVisible( true ); setAsPlotMdiWindow(); setShowWindow( false ); @@ -405,6 +416,23 @@ void RimWellConnectivityTable::fieldChangedByUi( const caf::PdmFieldHandle* chan { m_matrixPlotWidget->setValueFontSize( valueLabelFontSize() ); } + else if ( changedField == &m_rangeType && m_legendConfig ) + { + auto rangeMode = m_rangeType == RangeType::AUTOMATIC ? RimLegendConfig::RangeModeType::AUTOMATIC_ALLTIMESTEPS + : RimLegendConfig::RangeModeType::USER_DEFINED; + m_legendConfig->setRangeMode( rangeMode ); + m_legendConfig->updateTickCountAndUserDefinedRange(); + onLoadDataAndUpdate(); + } + else if ( changedField == &m_mappingType && m_legendConfig ) + { + m_legendConfig->setMappingMode( m_mappingType() ); + if ( m_rangeType == RangeType::AUTOMATIC ) + { + m_legendConfig->updateTickCountAndUserDefinedRange(); + } + onLoadDataAndUpdate(); + } } //-------------------------------------------------------------------------------------------------- @@ -472,7 +500,10 @@ void RimWellConnectivityTable::defineUiOrdering( QString uiConfigName, caf::PdmU caf::PdmUiGroup* tableSettingsGroup = uiOrdering.addNewGroup( "Table Settings" ); tableSettingsGroup->add( &m_showValueLabels ); - m_legendConfig->uiOrdering( "FlagColorsAndMappingModeOnly", *tableSettingsGroup ); + m_legendConfig->uiOrdering( "FlagAndColorsOnly", *tableSettingsGroup ); + tableSettingsGroup->add( &m_mappingType ); + tableSettingsGroup->add( &m_rangeType ); + m_legendConfig->uiOrdering( "UserDefinedMinMaxOnly", *tableSettingsGroup ); caf::PdmUiGroup* fontGroup = uiOrdering.addNewGroup( "Fonts" ); fontGroup->setCollapsedByDefault(); @@ -605,6 +636,9 @@ void RimWellConnectivityTable::onLoadDataAndUpdate() // Fill matrix plot widget with filtered rows/columns double maxValue = 0.0; m_matrixPlotWidget->setColumnHeaders( filteredColumnHeaders ); + + double posClosestToZeroValue = std::numeric_limits::max(); + double negClosestToZeroValue = std::numeric_limits::lowest(); for ( const auto& [rowName, rowValues] : filteredRows ) { // Add columns with values above threshold @@ -615,16 +649,24 @@ void RimWellConnectivityTable::onLoadDataAndUpdate() maxValue = maxValue < rowValues[i] ? rowValues[i] : maxValue; columns.push_back( rowValues[i] ); + + // Find positive and negative value closest to zero + if ( rowValues[i] > 0.0 && rowValues[i] < posClosestToZeroValue ) posClosestToZeroValue = rowValues[i]; + if ( rowValues[i] < 0.0 && rowValues[i] > negClosestToZeroValue ) negClosestToZeroValue = rowValues[i]; } m_matrixPlotWidget->setRowValues( rowName, columns ); } + if ( negClosestToZeroValue == std::numeric_limits::lowest() ) negClosestToZeroValue = -0.1; + if ( posClosestToZeroValue == std::numeric_limits::max() ) posClosestToZeroValue = 0.1; + // Set ranges using max value if ( m_legendConfig ) { const auto [min, max] = createLegendMinMaxValues( maxValue ); m_legendConfig->setAutomaticRanges( min, max, 0.0, 0.0 ); + m_legendConfig->setClosestToZeroValues( posClosestToZeroValue, negClosestToZeroValue, posClosestToZeroValue, negClosestToZeroValue ); } // Set titles and font sizes @@ -713,6 +755,17 @@ QList RimWellConnectivityTable::calculateValueOptions( c { options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() ); } + else if ( fieldNeedingOptions == &m_mappingType ) + { + std::vector mappingTypes = { RimRegularLegendConfig::MappingType::LINEAR_DISCRETE, + RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS, + RimRegularLegendConfig::MappingType::LOG10_CONTINUOUS, + RimRegularLegendConfig::MappingType::LOG10_DISCRETE }; + for ( const auto mappingType : mappingTypes ) + { + options.push_back( caf::PdmOptionItemInfo( caf::AppEnum::uiText( mappingType ), mappingType ) ); + } + } return options; } diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.h b/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.h index 67358e4f8b..171d87df9f 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.h +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.h @@ -22,6 +22,8 @@ #include "RigFlowDiagResultAddress.h" +#include "RimRegularLegendConfig.h" + #include "cafPdmField.h" #include "cafPdmPtrField.h" @@ -79,6 +81,12 @@ public: TIME_STEP_COUNT, }; + enum class RangeType + { + AUTOMATIC, + USER_DEFINED + }; + public: RimWellConnectivityTable(); ~RimWellConnectivityTable() override; @@ -186,6 +194,9 @@ private: caf::PdmField m_syncSelectedInjectorsFromProducerSelection; caf::PdmField m_applySelectedInectorProducerTracers; + caf::PdmField m_mappingType; + caf::PdmField> m_rangeType; + caf::PdmField m_axisTitleFontSize; caf::PdmField m_axisLabelFontSize; caf::PdmField m_valueLabelFontSize; diff --git a/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.cpp b/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.cpp index 3a78de1af1..c492ac8755 100644 --- a/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.cpp @@ -1244,11 +1244,24 @@ void RimRegularLegendConfig::defineUiOrdering( QString uiConfigName, caf::PdmUiO uiOrdering.add( &m_colorLegend ); uiOrdering.skipRemainingFields( true ); } - else if ( uiConfigName == "FlagColorsAndMappingModeOnly" ) + else if ( uiConfigName == "FlagAndColorsOnly" ) { uiOrdering.add( &m_showLegend ); uiOrdering.add( &m_colorLegend ); - uiOrdering.add( &m_mappingMode ); + uiOrdering.skipRemainingFields( true ); + } + else if ( uiConfigName == "UserDefinedMinMaxOnly" ) + { + uiOrdering.add( &m_userDefinedMaxValue ); + uiOrdering.add( &m_userDefinedMinValue ); + uiOrdering.skipRemainingFields( true ); + } + else if ( uiConfigName == "RangeModeAndUserDefinedMinMaxOnly" ) + { + // TODO: DELETE!!! + uiOrdering.add( &m_rangeMode ); + uiOrdering.add( &m_userDefinedMaxValue ); + uiOrdering.add( &m_userDefinedMinValue ); uiOrdering.skipRemainingFields( true ); } else diff --git a/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.h b/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.h index 27482708fe..78a9ed5307 100644 --- a/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.h +++ b/ApplicationLibCode/ProjectDataModel/RimRegularLegendConfig.h @@ -174,6 +174,8 @@ public: void defineUiOrderingColorOnly( caf::PdmUiOrdering* colorGroup ); + void updateTickCountAndUserDefinedRange(); + private: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void sendChangedSignal( const caf::PdmFieldHandle* changedField ); @@ -189,7 +191,6 @@ private: void updateCategoryItems(); void configureCategoryMapper(); - void updateTickCountAndUserDefinedRange(); friend class RimViewLinker; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.cpp index ebf0c4cd14..c3a84ec506 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.cpp @@ -27,7 +27,6 @@ #include "RimEclipseResultCase.h" #include "RimEclipseView.h" -#include "RimRegularLegendConfig.h" #include "RimSummaryCase.h" #include "RimSummaryCaseMainCollection.h" #include "RimTools.h" @@ -43,6 +42,20 @@ CAF_PDM_SOURCE_INIT( RimSummaryTable, "RimSummaryTable" ); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +namespace caf +{ +template <> +void AppEnum::setUp() +{ + addItem( RimSummaryTable::RangeType::AUTOMATIC, "AUTOMATIC", "Min and Max in Table" ); + addItem( RimSummaryTable::RangeType::USER_DEFINED, "USER_DEFINED_MAX_MIN", "User Defined Range" ); + setDefault( RimSummaryTable::RangeType::AUTOMATIC ); +} +} // namespace caf + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -87,6 +100,9 @@ RimSummaryTable::RimSummaryTable() m_legendConfig->setAutomaticRanges( 0.0, 100.0, 0.0, 100.0 ); m_legendConfig->setColorLegend( RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::HEAT_MAP ) ); + CAF_PDM_InitFieldNoDefault( &m_mappingType, "MappingType", "Mapping Type" ); + CAF_PDM_InitFieldNoDefault( &m_rangeType, "RangeType", "Range Type" ); + setLegendsVisible( true ); setAsPlotMdiWindow(); setShowWindow( true ); @@ -250,6 +266,23 @@ void RimSummaryTable::fieldChangedByUi( const caf::PdmFieldHandle* changedField, { m_matrixPlotWidget->setValueFontSize( valueLabelFontSize() ); } + else if ( changedField == &m_rangeType && m_legendConfig ) + { + auto rangeMode = m_rangeType == RangeType::AUTOMATIC ? RimLegendConfig::RangeModeType::AUTOMATIC_ALLTIMESTEPS + : RimLegendConfig::RangeModeType::USER_DEFINED; + m_legendConfig->setRangeMode( rangeMode ); + m_legendConfig->updateTickCountAndUserDefinedRange(); + onLoadDataAndUpdate(); + } + else if ( changedField == &m_mappingType && m_legendConfig ) + { + m_legendConfig->setMappingMode( m_mappingType() ); + if ( m_rangeType == RangeType::AUTOMATIC ) + { + m_legendConfig->updateTickCountAndUserDefinedRange(); + } + onLoadDataAndUpdate(); + } } //-------------------------------------------------------------------------------------------------- @@ -279,7 +312,10 @@ void RimSummaryTable::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering caf::PdmUiGroup* tableSettingsGroup = uiOrdering.addNewGroup( "Table Settings" ); tableSettingsGroup->add( &m_showValueLabels ); - m_legendConfig->uiOrdering( "FlagColorsAndMappingModeOnly", *tableSettingsGroup ); + m_legendConfig->uiOrdering( "FlagAndColorsOnly", *tableSettingsGroup ); + tableSettingsGroup->add( &m_mappingType ); + tableSettingsGroup->add( &m_rangeType ); + m_legendConfig->uiOrdering( "UserDefinedMinMaxOnly", *tableSettingsGroup ); caf::PdmUiGroup* fontGroup = uiOrdering.addNewGroup( "Fonts" ); fontGroup->setCollapsedByDefault(); @@ -346,6 +382,17 @@ QList RimSummaryTable::calculateValueOptions( const caf: { options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() ); } + else if ( fieldNeedingOptions == &m_mappingType ) + { + std::vector mappingTypes = { RimRegularLegendConfig::MappingType::LINEAR_DISCRETE, + RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS, + RimRegularLegendConfig::MappingType::LOG10_CONTINUOUS, + RimRegularLegendConfig::MappingType::LOG10_DISCRETE }; + for ( const auto mappingType : mappingTypes ) + { + options.push_back( caf::PdmOptionItemInfo( caf::AppEnum::uiText( mappingType ), mappingType ) ); + } + } return options; } @@ -382,16 +429,27 @@ void RimSummaryTable::onLoadDataAndUpdate() // Clear matrix plot m_matrixPlotWidget->clearPlotData(); m_matrixPlotWidget->setColumnHeaders( timeStepStrings ); + + double posClosestToZeroValue = std::numeric_limits::max(); + double negClosestToZeroValue = std::numeric_limits::lowest(); for ( const auto& vectorData : m_tableData.vectorDataCollection ) { if ( excludedRows.contains( vectorData.category ) ) continue; + // Find positive and negative value closest to zero + for ( const auto& value : vectorData.values ) + { + if ( value > 0.0 && value < posClosestToZeroValue ) posClosestToZeroValue = value; + if ( value < 0.0 && value > negClosestToZeroValue ) negClosestToZeroValue = value; + } + m_matrixPlotWidget->setRowValues( vectorData.category, vectorData.values ); } if ( m_legendConfig ) { m_legendConfig->setAutomaticRanges( m_tableData.minValue, m_tableData.maxValue, 0.0, 0.0 ); + m_legendConfig->setClosestToZeroValues( posClosestToZeroValue, negClosestToZeroValue, posClosestToZeroValue, negClosestToZeroValue ); } // Set titles and font sizes diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.h index 34e28fcd49..172b90eb21 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryTable.h @@ -24,6 +24,7 @@ #include "RifEclipseSummaryAddress.h" +#include "RimRegularLegendConfig.h" #include "RimSummaryTableTools.h" #include "cafPdmField.h" @@ -45,6 +46,13 @@ class RimSummaryTable : public RimPlotWindow { CAF_PDM_HEADER_INIT; +public: + enum class RangeType + { + AUTOMATIC, + USER_DEFINED + }; + public: RimSummaryTable(); ~RimSummaryTable() override; @@ -120,6 +128,9 @@ private: caf::PdmField m_valueLabelFontSize; caf::PdmField m_showValueLabels; + caf::PdmField m_mappingType; + caf::PdmField> m_rangeType; + private: using VectorData = RimSummaryTableTools::VectorData; using TableData = RimSummaryTableTools::TableData; diff --git a/ApplicationLibCode/UserInterface/RiuMatrixPlotWidget.cpp b/ApplicationLibCode/UserInterface/RiuMatrixPlotWidget.cpp index b232bd1ffb..8c34fb0123 100644 --- a/ApplicationLibCode/UserInterface/RiuMatrixPlotWidget.cpp +++ b/ApplicationLibCode/UserInterface/RiuMatrixPlotWidget.cpp @@ -25,6 +25,7 @@ #include "RimViewWindow.h" #include "RiuAbstractLegendFrame.h" +#include "RiuCategoryLegendFrame.h" #include "RiuQwtLinearScaleEngine.h" #include "RiuQwtPlotItem.h" #include "RiuQwtPlotTools.h" @@ -176,9 +177,18 @@ void RiuMatrixPlotWidget::createPlot() createMatrixCells(); scheduleReplot(); - auto frame = dynamic_cast( m_legendFrame.data() ); - frame->updateTickValues(); - frame->update(); + auto scalarMapperFrame = dynamic_cast( m_legendFrame.data() ); + auto categoryFrame = dynamic_cast( m_legendFrame.data() ); + if ( scalarMapperFrame ) + { + scalarMapperFrame->setScalarMapper( m_legendConfig->scalarMapper() ); + scalarMapperFrame->updateTickValues(); + scalarMapperFrame->update(); + } + if ( categoryFrame ) + { + categoryFrame->update(); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.cpp b/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.cpp index a0da2dad7c..33f51b8a6c 100644 --- a/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.cpp +++ b/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.cpp @@ -77,6 +77,14 @@ void RiuScalarMapperLegendFrame::updateTickValues() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuScalarMapperLegendFrame::setScalarMapper( cvf::ScalarMapper* scalarMapper ) +{ + m_scalarMapper = scalarMapper; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.h b/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.h index ceddfb62b2..2d0e9b8b0c 100644 --- a/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.h +++ b/ApplicationLibCode/UserInterface/RiuScalarMapperLegendFrame.h @@ -47,6 +47,7 @@ public: void setTickPrecision( int precision ); void setTickFormat( NumberFormat format ); void updateTickValues(); + void setScalarMapper( cvf::ScalarMapper* scalarMapper ); private: void layoutInfo( LayoutInfo* layout ) const override;