#9093 MultiPlot: improve axis alignment by resizing scales

This commit is contained in:
Kristian Bendiksen 2022-08-10 13:52:30 +02:00
parent f8e19e68d2
commit 71d18b9e76
4 changed files with 116 additions and 10 deletions

View File

@ -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 <QDebug>
#include <QDesktopWidget>
@ -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<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
QList<QPointer<RiuPlotWidget>> 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<bool( int, int, int )> matchPosition )
{
auto rowAndColumnFromIdx = [this]( int idx ) {
auto hit = m_visibleIndexToPositionMapping.find( idx );
CAF_ASSERT( hit != m_visibleIndexToPositionMapping.end() );
return hit->second;
};
QList<QPointer<RiuPlotWidget>> 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<RiuQwtPlotWidget*>( 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<RiuQwtPlotWidget*>( plotWidget );
if ( riuQwtPlotWidget )
{
QwtPlot* p = riuQwtPlotWidget->qwtPlot();
if ( p )
{
QwtScaleWidget* scaleWidget = p->axisWidget( axis );
scaleWidget->scaleDraw()->setMinimumExtent( maxExtent );
}
}
}
}
}

View File

@ -24,6 +24,8 @@
#include "cafPdmPointer.h"
#include "cafSelectionChangedReceiver.h"
#include "qwt_axis_id.h"
#include <QFrame>
#include <QGridLayout>
#include <QHBoxLayout>
@ -31,6 +33,7 @@
#include <QPointer>
#include <QWidget>
#include <functional>
#include <map>
class RiaPlotWindowRedrawScheduler;
@ -105,6 +108,9 @@ protected:
std::pair<int, int> rowAndColumnCount( int plotWidgetCount ) const;
void alignAxes();
void alignAxis( QwtAxisId axis, int row, std::function<bool( int, int, int )> positionMatcher );
void onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels ) override;
virtual bool showYAxis( int row, int column ) const;
@ -128,15 +134,16 @@ private slots:
void onLegendUpdated();
protected:
QPointer<QVBoxLayout> m_layout;
QPointer<QHBoxLayout> m_plotLayout;
QPointer<QFrame> m_plotWidgetFrame;
QPointer<QGridLayout> m_gridLayout;
QPointer<QLabel> m_plotTitle;
QList<QPointer<QLabel>> m_subTitles;
QList<QPointer<RiuQwtPlotLegend>> m_legends;
QList<QPointer<RiuPlotWidget>> m_plotWidgets;
caf::PdmPointer<RimPlotWindow> m_plotDefinition;
QPointer<QVBoxLayout> m_layout;
QPointer<QHBoxLayout> m_plotLayout;
QPointer<QFrame> m_plotWidgetFrame;
QPointer<QGridLayout> m_gridLayout;
QPointer<QLabel> m_plotTitle;
QList<QPointer<QLabel>> m_subTitles;
QList<QPointer<RiuQwtPlotLegend>> m_legends;
QList<QPointer<RiuPlotWidget>> m_plotWidgets;
std::map<int, std::pair<int, int>> m_visibleIndexToPositionMapping;
caf::PdmPointer<RimPlotWindow> m_plotDefinition;
int m_titleFontPixelSize;
int m_subTitleFontPixelSize;

View File

@ -73,6 +73,8 @@ void RiuSummaryMultiPlotPage::reinsertPlotWidgets()
QList<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
QList<QPointer<RiuPlotWidget>> 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 );

View File

@ -160,4 +160,5 @@ void RiuWellLogPlot::performUpdate( RiaDefines::MultiPlotPageUpdateType /* whatT
reinsertScrollbar();
int axisShift = alignCanvasTops();
alignScrollbar( axisShift );
alignAxes();
}