From 71d18b9e761e9079cbca2ffbb430b0afdf85291b Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Wed, 10 Aug 2022 13:52:30 +0200 Subject: [PATCH] #9093 MultiPlot: improve axis alignment by resizing scales --- .../UserInterface/RiuMultiPlotPage.cpp | 96 ++++++++++++++++++- .../UserInterface/RiuMultiPlotPage.h | 25 +++-- .../UserInterface/RiuSummaryMultiPlotPage.cpp | 4 + .../UserInterface/RiuWellLogPlot.cpp | 1 + 4 files changed, 116 insertions(+), 10 deletions(-) diff --git a/ApplicationLibCode/UserInterface/RiuMultiPlotPage.cpp b/ApplicationLibCode/UserInterface/RiuMultiPlotPage.cpp index f286440254..186811e92f 100644 --- a/ApplicationLibCode/UserInterface/RiuMultiPlotPage.cpp +++ b/ApplicationLibCode/UserInterface/RiuMultiPlotPage.cpp @@ -49,10 +49,12 @@ #include "cvfAssert.h" +#include "qwt_axis.h" #include "qwt_legend.h" #include "qwt_plot_layout.h" #include "qwt_plot_renderer.h" #include "qwt_scale_draw.h" +#include "qwt_scale_widget.h" #include #include @@ -579,6 +581,7 @@ void RiuMultiPlotPage::performUpdate( RiaDefines::MultiPlotPageUpdateType whatTo reinsertPlotWidgets(); alignCanvasTops(); + alignAxes(); return; } @@ -586,7 +589,9 @@ void RiuMultiPlotPage::performUpdate( RiaDefines::MultiPlotPageUpdateType whatTo { refreshLegends(); alignCanvasTops(); + alignAxes(); } + if ( ( whatToUpdate & RiaDefines::MultiPlotPageUpdateType::TITLE ) == RiaDefines::MultiPlotPageUpdateType::TITLE ) { updateSubTitles(); @@ -624,6 +629,8 @@ void RiuMultiPlotPage::reinsertPlotWidgets() QList> legends = this->legendsForVisiblePlots(); QList> plotWidgets = this->visiblePlotWidgets(); + m_visibleIndexToPositionMapping.clear(); + if ( !plotWidgets.empty() ) { auto [rowCount, columnCount] = this->rowAndColumnCount( plotWidgets.size() ); @@ -636,7 +643,10 @@ void RiuMultiPlotPage::reinsertPlotWidgets() int colSpan = std::min( expectedColSpan, columnCount ); int rowSpan = plotWidgets[visibleIndex]->rowSpan(); - std::tie( row, column ) = findAvailableRowAndColumn( row, column, colSpan, columnCount ); + auto position = findAvailableRowAndColumn( row, column, colSpan, columnCount ); + std::tie( row, column ) = position; + + m_visibleIndexToPositionMapping[visibleIndex] = position; m_gridLayout->addWidget( subTitles[visibleIndex], 3 * row, column, 1, colSpan ); if ( legends[visibleIndex] ) @@ -928,3 +938,87 @@ void RiuMultiPlotPage::updateTitleFont() titleFont.setPixelSize( m_titleFontPixelSize ); m_plotTitle->setFont( titleFont ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiPlotPage::alignAxes() +{ + auto [rowCount, columnCount] = rowAndColumnCount( visiblePlotWidgets().size() ); + + auto matchRow = []( int row, int column, int targetRow ) { return row == targetRow; }; + + for ( int row = 0; row < rowCount; row++ ) + { + alignAxis( QwtAxisId( QwtAxis::Position::XTop, 0 ), row, matchRow ); + alignAxis( QwtAxisId( QwtAxis::Position::XBottom, 0 ), row, matchRow ); + } + + auto matchColumn = []( int row, int column, int targetColumn ) { return column == targetColumn; }; + + for ( int column = 0; column < columnCount; column++ ) + { + alignAxis( QwtAxisId( QwtAxis::Position::YLeft, 0 ), column, matchColumn ); + alignAxis( QwtAxisId( QwtAxis::Position::YRight, 0 ), column, matchColumn ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiPlotPage::alignAxis( QwtAxisId axis, int targetRowOrColumn, std::function matchPosition ) +{ + auto rowAndColumnFromIdx = [this]( int idx ) { + auto hit = m_visibleIndexToPositionMapping.find( idx ); + CAF_ASSERT( hit != m_visibleIndexToPositionMapping.end() ); + return hit->second; + }; + + QList> plotWidgets = visiblePlotWidgets(); + + // Find the max extent of the "scale draws" for the given axis + double maxExtent = 0; + for ( int tIdx = 0; tIdx < plotWidgets.size(); ++tIdx ) + { + RiuPlotWidget* plotWidget = plotWidgets[tIdx]; + auto [row, column] = rowAndColumnFromIdx( tIdx ); + bool matchesRowOrColumn = matchPosition( row, column, targetRowOrColumn ); + if ( plotWidget && matchesRowOrColumn ) + { + RiuQwtPlotWidget* riuQwtPlotWidget = dynamic_cast( plotWidget ); + + if ( riuQwtPlotWidget ) + { + QwtPlot* p = riuQwtPlotWidget->qwtPlot(); + if ( p ) + { + QwtScaleWidget* scaleWidget = p->axisWidget( axis ); + QwtScaleDraw* sd = scaleWidget->scaleDraw(); + sd->setMinimumExtent( 0.0 ); + maxExtent = std::max( sd->extent( scaleWidget->font() ), maxExtent ); + } + } + } + } + + // Set minimum extent for all "scale draws" for the given axis. + for ( int tIdx = 0; tIdx < plotWidgets.size(); ++tIdx ) + { + RiuPlotWidget* plotWidget = plotWidgets[tIdx]; + auto [row, column] = rowAndColumnFromIdx( tIdx ); + bool matchesRowOrColumn = matchPosition( row, column, targetRowOrColumn ); + if ( plotWidget && matchesRowOrColumn ) + { + RiuQwtPlotWidget* riuQwtPlotWidget = dynamic_cast( plotWidget ); + if ( riuQwtPlotWidget ) + { + QwtPlot* p = riuQwtPlotWidget->qwtPlot(); + if ( p ) + { + QwtScaleWidget* scaleWidget = p->axisWidget( axis ); + scaleWidget->scaleDraw()->setMinimumExtent( maxExtent ); + } + } + } + } +} diff --git a/ApplicationLibCode/UserInterface/RiuMultiPlotPage.h b/ApplicationLibCode/UserInterface/RiuMultiPlotPage.h index 575bdb6f2b..2427bf340e 100644 --- a/ApplicationLibCode/UserInterface/RiuMultiPlotPage.h +++ b/ApplicationLibCode/UserInterface/RiuMultiPlotPage.h @@ -24,6 +24,8 @@ #include "cafPdmPointer.h" #include "cafSelectionChangedReceiver.h" +#include "qwt_axis_id.h" + #include #include #include @@ -31,6 +33,7 @@ #include #include +#include #include class RiaPlotWindowRedrawScheduler; @@ -105,6 +108,9 @@ protected: std::pair rowAndColumnCount( int plotWidgetCount ) const; + void alignAxes(); + void alignAxis( QwtAxisId axis, int row, std::function positionMatcher ); + void onSelectionManagerSelectionChanged( const std::set& changedSelectionLevels ) override; virtual bool showYAxis( int row, int column ) const; @@ -128,15 +134,16 @@ private slots: void onLegendUpdated(); protected: - QPointer m_layout; - QPointer m_plotLayout; - QPointer m_plotWidgetFrame; - QPointer m_gridLayout; - QPointer m_plotTitle; - QList> m_subTitles; - QList> m_legends; - QList> m_plotWidgets; - caf::PdmPointer m_plotDefinition; + QPointer m_layout; + QPointer m_plotLayout; + QPointer m_plotWidgetFrame; + QPointer m_gridLayout; + QPointer m_plotTitle; + QList> m_subTitles; + QList> m_legends; + QList> m_plotWidgets; + std::map> m_visibleIndexToPositionMapping; + caf::PdmPointer m_plotDefinition; int m_titleFontPixelSize; int m_subTitleFontPixelSize; diff --git a/ApplicationLibCode/UserInterface/RiuSummaryMultiPlotPage.cpp b/ApplicationLibCode/UserInterface/RiuSummaryMultiPlotPage.cpp index 72ff0aa121..528aa649ef 100644 --- a/ApplicationLibCode/UserInterface/RiuSummaryMultiPlotPage.cpp +++ b/ApplicationLibCode/UserInterface/RiuSummaryMultiPlotPage.cpp @@ -73,6 +73,8 @@ void RiuSummaryMultiPlotPage::reinsertPlotWidgets() QList> legends = this->legendsForVisiblePlots(); QList> plotWidgets = this->visiblePlotWidgets(); + m_visibleIndexToPositionMapping.clear(); + int visibleIndex = 0; int phIndex = 0; @@ -90,6 +92,8 @@ void RiuSummaryMultiPlotPage::reinsertPlotWidgets() continue; } + m_visibleIndexToPositionMapping[visibleIndex] = std::make_pair( row, col ); + auto plotWidget = plotWidgets[visibleIndex]; int expectedColSpan = plotWidget->colSpan(); int colSpan = std::min( expectedColSpan, cols - col ); diff --git a/ApplicationLibCode/UserInterface/RiuWellLogPlot.cpp b/ApplicationLibCode/UserInterface/RiuWellLogPlot.cpp index c24427b4ec..caf9ad6658 100644 --- a/ApplicationLibCode/UserInterface/RiuWellLogPlot.cpp +++ b/ApplicationLibCode/UserInterface/RiuWellLogPlot.cpp @@ -160,4 +160,5 @@ void RiuWellLogPlot::performUpdate( RiaDefines::MultiPlotPageUpdateType /* whatT reinsertScrollbar(); int axisShift = alignCanvasTops(); alignScrollbar( axisShift ); + alignAxes(); }