Further Summary Multiplot improvements (#8707)

* Create a specialized summary plot page for showing multi plots
* Make summary plots always show in grid of selected size.
* Allow dragging summary addresses into empty main window area
* Limit grid to 4x4 cells
This commit is contained in:
jonjenssen 2022-03-21 11:31:25 +01:00 committed by GitHub
parent 8d3f381b4f
commit e20adcdb69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 343 additions and 39 deletions

View File

@ -338,6 +338,30 @@ RimMultiPlot* RicSummaryPlotBuilder::createAndAppendMultiPlot( const std::vector
return plotWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryMultiPlot*
RicSummaryPlotBuilder::createAndAppendSummaryMultiPlot( const std::vector<caf::PdmObjectHandle*>& objects )
{
RimProject* project = RimProject::current();
RimSummaryMultiPlotCollection* plotCollection = project->mainPlotCollection()->summaryMultiPlotCollection();
auto* plotWindow = new RimSummaryMultiPlot;
plotWindow->setMultiPlotTitle( QString( "Multi Plot %1" ).arg( plotCollection->multiPlots().size() + 1 ) );
plotWindow->setAsPlotMdiWindow();
plotCollection->addSummaryMultiPlot( plotWindow );
plotWindow->addPlot( objects );
plotCollection->updateAllRequiredEditors();
plotWindow->loadDataAndUpdate();
RiuPlotMainWindowTools::selectAsCurrentItem( plotWindow, true );
return plotWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -369,7 +393,7 @@ RimSummaryMultiPlot* RicSummaryPlotBuilder::createAndAppendSummaryMultiPlot( con
auto* plotWindow = new RimSummaryMultiPlot();
plotWindow->setMultiPlotTitle( QString( "Multi Summary Plot %1" ).arg( plotCollection->multiPlots().size() + 1 ) );
plotWindow->setAsPlotMdiWindow();
plotCollection->addMultiSummaryPlot( plotWindow );
plotCollection->addSummaryMultiPlot( plotWindow );
appendPlotsToSummaryMultiPlot( plotWindow, plots );

View File

@ -31,7 +31,8 @@ class RimSummaryMultiPlot;
namespace caf
{
class PdmObject;
}
class PdmObjectHandle;
} // namespace caf
#include <set>
#include <vector>
@ -75,6 +76,7 @@ public:
static void appendPlotsToMultiPlot( RimMultiPlot* multiPlot, const std::vector<RimPlot*>& plots );
static RimSummaryMultiPlot* createAndAppendSummaryMultiPlot( const std::vector<RimSummaryPlot*>& plots );
static RimSummaryMultiPlot* createAndAppendSummaryMultiPlot( const std::vector<caf::PdmObjectHandle*>& objects );
static void appendPlotsToSummaryMultiPlot( RimSummaryMultiPlot* multiPlot, const std::vector<RimSummaryPlot*>& plots );
static RimSummaryPlot* createPlot( const std::set<RifEclipseSummaryAddress>& addresses,

View File

@ -46,7 +46,6 @@ void RimMultiPlot::ColumnCountEnum::setUp()
addItem( RimMultiPlot::ColumnCount::COLUMNS_2, "2", "2 Columns" );
addItem( RimMultiPlot::ColumnCount::COLUMNS_3, "3", "3 Columns" );
addItem( RimMultiPlot::ColumnCount::COLUMNS_4, "4", "4 Columns" );
addItem( RimMultiPlot::ColumnCount::COLUMNS_UNLIMITED, "UNLIMITED", "Unlimited" );
setDefault( RimMultiPlot::ColumnCount::COLUMNS_2 );
}
template <>

View File

@ -75,7 +75,7 @@ std::vector<RimSummaryMultiPlot*> RimSummaryMultiPlotCollection::multiPlots() co
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryMultiPlotCollection::addMultiSummaryPlot( RimSummaryMultiPlot* plot )
void RimSummaryMultiPlotCollection::addSummaryMultiPlot( RimSummaryMultiPlot* plot )
{
m_summaryMultiPlots().push_back( plot );
plot->duplicatePlot.connect( this, &RimSummaryMultiPlotCollection::onDuplicatePlot );
@ -108,7 +108,7 @@ void RimSummaryMultiPlotCollection::onDuplicatePlot( const caf::SignalEmitter* e
auto plotCopy = dynamic_cast<RimSummaryMultiPlot*>(
plotToDuplicate->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
addMultiSummaryPlot( plotCopy );
addSummaryMultiPlot( plotCopy );
plotCopy->resolveReferencesRecursively();
plotCopy->initAfterReadRecursively();

View File

@ -42,7 +42,7 @@ public:
std::vector<RimSummaryMultiPlot*> multiPlots() const;
void addMultiSummaryPlot( RimSummaryMultiPlot* plot );
void addSummaryMultiPlot( RimSummaryMultiPlot* plot );
protected:
void onDuplicatePlot( const caf::SignalEmitter* emitter, RimSummaryMultiPlot* plotToDuplicate );

View File

@ -86,10 +86,5 @@ QString RimSummaryNameHelper::aggregatedPlotTitle( const RimSummaryNameHelper& o
RiuSummaryQuantityNameInfoProvider::instance()->longNameFromQuantityName( quantity, true ) );
}
if ( title.isEmpty() )
{
title = "Plot Title";
}
return title;
}

View File

@ -154,6 +154,11 @@ RimSummaryPlot::RimSummaryPlot( bool isCrossPlot )
m_sourceStepping.uiCapability()->setUiTreeChildrenHidden( true );
m_sourceStepping.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_alternatePlotName, "AlternateName", "AlternateName" );
m_alternatePlotName.uiCapability()->setUiReadOnly( true );
m_alternatePlotName.uiCapability()->setUiHidden( true );
m_alternatePlotName.xmlCapability()->disableIO();
setPlotInfoLabel( "Filters Active" );
// Obsolete axis fields
@ -1361,6 +1366,10 @@ void RimSummaryPlot::addAsciiDataCruve( RimAsciiDataCurve* curve )
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimSummaryPlot::userDescriptionField()
{
if ( m_description().isEmpty() )
{
return &m_alternatePlotName;
}
return &m_description;
}
@ -2103,7 +2112,6 @@ void RimSummaryPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
{
mainOptions->add( &m_useAutoPlotTitle );
mainOptions->add( &m_description );
mainOptions->add( &m_rowSpan );
mainOptions->add( &m_colSpan );
}
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle );
@ -2349,11 +2357,19 @@ void RimSummaryPlot::deleteAllPlotCurves()
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::updateCurveNames()
{
m_alternatePlotName = "";
QStringList shortCurveNames;
if ( m_summaryCurveCollection->isCurvesVisible() )
{
for ( auto c : summaryCurves() )
{
if ( c->isCurveVisible() ) c->updateCurveNameNoLegendUpdate();
if ( c->isCurveVisible() )
{
c->updateCurveNameNoLegendUpdate();
shortCurveNames.append( QString::fromStdString( c->summaryAddressY().quantityName() ) );
}
}
}
@ -2361,6 +2377,8 @@ void RimSummaryPlot::updateCurveNames()
{
curveSet->updateEnsembleLegendItem();
}
m_alternatePlotName = shortCurveNames.join( "," );
}
//--------------------------------------------------------------------------------------------------

View File

@ -31,6 +31,7 @@
#include "cafPdmChildArrayField.h"
#include "cafPdmObjectHandle.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmPtrArrayField.h"
#include "cafPdmPtrField.h"
@ -294,6 +295,7 @@ private:
caf::PdmField<bool> m_useAutoPlotTitle;
caf::PdmField<QString> m_description;
caf::PdmField<QString> m_alternatePlotName;
caf::PdmChildArrayField<RimGridTimeHistoryCurve*> m_gridTimeHistoryCurves;
caf::PdmChildField<RimSummaryCurveCollection*> m_summaryCurveCollection;

View File

@ -54,6 +54,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuPickItemInfo.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryMultiPlotPage.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotPage.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotBook.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotWidget.h
@ -155,6 +156,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiuPickItemInfo.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryMultiPlotPage.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotPage.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotBook.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotWidget.cpp
@ -255,6 +257,7 @@ list(
${CMAKE_CURRENT_LIST_DIR}/RiuTreeViewEventFilter.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryMultiPlotPage.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotPage.h
${CMAKE_CURRENT_LIST_DIR}/RiuMultiPlotBook.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.h

View File

@ -32,6 +32,7 @@
#include "RiuPlotMainWindow.h"
#include "RiuPlotObjectPicker.h"
#include "RiuPlotWidget.h"
#include "RiuSummaryMultiPlotPage.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafSelectionManager.h"
@ -551,7 +552,18 @@ const QList<QPointer<RiuMultiPlotPage>>& RiuMultiPlotBook::pages() const
//--------------------------------------------------------------------------------------------------
RiuMultiPlotPage* RiuMultiPlotBook::createPage()
{
RiuMultiPlotPage* page = new RiuMultiPlotPage( m_plotDefinition, this );
RiuMultiPlotPage* page;
RimSummaryMultiPlot* sumMultPlot = dynamic_cast<RimSummaryMultiPlot*>( m_plotDefinition.p() );
if ( sumMultPlot )
{
page = new RiuSummaryMultiPlotPage( sumMultPlot, this );
}
else
{
page = new RiuMultiPlotPage( m_plotDefinition, this );
}
// Reapply plot settings
page->setPlotTitle( m_plotTitle );

View File

@ -572,43 +572,23 @@ void RiuMultiPlotPage::reinsertPlotWidgets()
{
clearGridLayout();
auto titleFont = m_plotTitle->font();
titleFont.setPixelSize( m_titleFontPixelSize );
m_plotTitle->setFont( titleFont );
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
if ( m_plotWidgets[tIdx] )
{
m_plotWidgets[tIdx]->hide();
}
if ( m_legends[tIdx] )
{
m_legends[tIdx]->hide();
}
if ( m_subTitles[tIdx] )
{
m_subTitles[tIdx]->hide();
}
}
QList<QPointer<QLabel>> subTitles = this->subTitlesForVisiblePlots();
QList<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
QList<QPointer<RiuPlotWidget>> plotWidgets = this->visiblePlotWidgets();
if ( !plotWidgets.empty() )
{
auto rowAndColumnCount = this->rowAndColumnCount( plotWidgets.size() );
auto [rowCount, columnCount] = this->rowAndColumnCount( plotWidgets.size() );
int row = 0;
int column = 0;
for ( int visibleIndex = 0; visibleIndex < plotWidgets.size(); ++visibleIndex )
{
int expectedColSpan = static_cast<int>( plotWidgets[visibleIndex]->colSpan() );
int colSpan = std::min( expectedColSpan, rowAndColumnCount.second );
int colSpan = std::min( expectedColSpan, columnCount );
int rowSpan = plotWidgets[visibleIndex]->rowSpan();
std::tie( row, column ) = findAvailableRowAndColumn( row, column, colSpan, rowAndColumnCount.second );
std::tie( row, column ) = findAvailableRowAndColumn( row, column, colSpan, columnCount );
m_gridLayout->addWidget( subTitles[visibleIndex], 3 * row, column, 1, colSpan );
if ( legends[visibleIndex] )
@ -745,6 +725,22 @@ void RiuMultiPlotPage::clearGridLayout()
delete m_gridLayout;
m_gridLayout = new QGridLayout( m_plotWidgetFrame );
}
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
if ( m_plotWidgets[tIdx] )
{
m_plotWidgets[tIdx]->hide();
}
if ( m_legends[tIdx] )
{
m_legends[tIdx]->hide();
}
if ( m_subTitles[tIdx] )
{
m_subTitles[tIdx]->hide();
}
}
}
//--------------------------------------------------------------------------------------------------
@ -860,3 +856,13 @@ void RiuMultiPlotPage::applyLook()
setGraphicsEffect( nullptr );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMultiPlotPage::updateTitleFont()
{
auto titleFont = m_plotTitle->font();
titleFont.setPixelSize( m_titleFontPixelSize );
m_plotTitle->setFont( titleFont );
}

View File

@ -112,8 +112,11 @@ protected:
virtual bool showYAxis( int row, int column ) const;
void reinsertPlotWidgets();
int alignCanvasTops();
virtual void reinsertPlotWidgets();
void updateTitleFont();
int alignCanvasTops();
void clearGridLayout();
@ -124,6 +127,7 @@ protected:
std::pair<int, int> findAvailableRowAndColumn( int startRow, int startColumn, int columnSpan, int columnCount ) const;
void applyLook();
private slots:
virtual void performUpdate();
void onLegendUpdated();

View File

@ -26,12 +26,16 @@
#include "RiaRegressionTestRunner.h"
#include "RiaSummaryTools.h"
#include "PlotBuilderCommands/RicSummaryPlotBuilder.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimMainPlotCollection.h"
#include "RimMultiPlot.h"
#include "RimProject.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryCurveCollection.h"
#include "RimSummaryMultiPlot.h"
#include "RimSummaryMultiPlotCollection.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimSummaryPlotFilterTextCurveSetEditor.h"
@ -46,6 +50,7 @@
#include "SummaryPlotCommands/RicSummaryPlotEditorDialog.h"
#include "RiuDockWidgetTools.h"
#include "RiuDragDrop.h"
#include "RiuMdiSubWindow.h"
#include "RiuMessagePanel.h"
#include "RiuMultiPlotPage.h"
@ -86,6 +91,8 @@ RiuPlotMainWindow::RiuPlotMainWindow()
createToolBars();
createDockPanels();
setAcceptDrops( true );
// Store the layout so we can offer reset option
m_initialDockAndToolbarLayout = saveState( 0 );
@ -1154,3 +1161,26 @@ bool RiuPlotMainWindow::isAnyMdiSubWindowVisible()
{
return m_mdiArea->subWindowList().size() > 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotMainWindow::dragEnterEvent( QDragEnterEvent* event )
{
QPoint curpos = m_mdiArea->mapFromGlobal( QCursor::pos() );
if ( m_mdiArea->rect().contains( curpos ) ) event->acceptProposedAction();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotMainWindow::dropEvent( QDropEvent* event )
{
std::vector<caf::PdmObjectHandle*> objects;
if ( RiuDragDrop::handleGenericDropEvent( event, objects ) )
{
RicSummaryPlotBuilder::createAndAppendSummaryMultiPlot( objects );
}
}

View File

@ -98,6 +98,8 @@ public:
protected:
void closeEvent( QCloseEvent* event ) override;
void keyPressEvent( QKeyEvent* ) override;
void dragEnterEvent( QDragEnterEvent* event ) override;
void dropEvent( QDropEvent* event ) override;
private:
void setPdmRoot( caf::PdmObject* pdmRoot );

View File

@ -0,0 +1,163 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuSummaryMultiPlotPage.h"
#include "RimSummaryMultiPlot.h"
#include "RiuPlotWidget.h"
#include "RiuQwtPlotLegend.h"
#include <QLabel>
#include <QWidget>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryMultiPlotPage::RiuSummaryMultiPlotPage( RimSummaryMultiPlot* plotDefinition, QWidget* parent )
: RiuMultiPlotPage( plotDefinition, parent )
, m_summaryMultiPlot( plotDefinition )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryMultiPlotPage::~RiuSummaryMultiPlotPage()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryMultiPlotPage::reinsertPlotWidgets()
{
if ( m_gridLayout )
{
for ( int phIdx = 0; phIdx < m_placeholderWidgets.size(); phIdx++ )
{
m_gridLayout->removeWidget( m_placeholderWidgets[phIdx] );
m_placeholderWidgets[phIdx]->hide();
}
}
clearGridLayout();
updateTitleFont();
int cols = m_summaryMultiPlot->columnCount();
int rows = m_summaryMultiPlot->rowsPerPage();
int nPlots = visiblePlotWidgets().size();
int nCells = cols * rows;
reservePlaceholders( nCells - nPlots );
QList<QPointer<QLabel>> subTitles = this->subTitlesForVisiblePlots();
QList<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
QList<QPointer<RiuPlotWidget>> plotWidgets = this->visiblePlotWidgets();
int visibleIndex = 0;
int phIndex = 0;
for ( int row = 0; row < rows; row++ )
{
for ( int col = 0; col < cols; col++ )
{
if ( visibleIndex >= nPlots )
{
m_gridLayout->addWidget( m_placeholderWidgets[phIndex], row * 3 + 2, col );
m_gridLayout->setRowStretch( row * 3 + 2, 1 );
m_gridLayout->setColumnStretch( col, 6 );
m_placeholderWidgets[phIndex]->show();
phIndex++;
continue;
}
int expectedColSpan = plotWidgets[visibleIndex]->colSpan();
int colSpan = std::min( expectedColSpan, cols - col );
m_gridLayout->addWidget( subTitles[visibleIndex], 3 * row, col, 1, colSpan );
if ( legends[visibleIndex] )
{
m_gridLayout->addWidget( legends[visibleIndex], 3 * row + 1, col, 1, colSpan, Qt::AlignHCenter | Qt::AlignBottom );
}
m_gridLayout->addWidget( plotWidgets[visibleIndex], 3 * row + 2, col, 1, colSpan );
subTitles[visibleIndex]->setVisible( m_showSubTitles );
QFont subTitleFont = subTitles[visibleIndex]->font();
subTitleFont.setPixelSize( m_subTitleFontPixelSize );
subTitles[visibleIndex]->setFont( subTitleFont );
plotWidgets[visibleIndex]->setAxisLabelsAndTicksEnabled( RiuPlotAxis::defaultLeft(),
showYAxis( row, col ),
showYAxis( row, col ) );
plotWidgets[visibleIndex]->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), showYAxis( row, col ) );
plotWidgets[visibleIndex]->setAxesFontsAndAlignment( m_axisTitleFontSize, m_axisValueFontSize );
// Adjust the space below a graph to make sure the heading of the row below is closest to the
// corresponding graph
auto margins = plotWidgets[visibleIndex]->contentsMargins();
margins.setBottom( 40 );
plotWidgets[visibleIndex]->setContentsMargins( margins );
plotWidgets[visibleIndex]->show();
if ( legends[visibleIndex] )
{
if ( m_plotDefinition->legendsVisible() )
{
int legendColumns = 1;
if ( m_plotDefinition->legendsHorizontal() )
{
legendColumns = 0; // unlimited
}
legends[visibleIndex]->setMaxColumns( legendColumns );
QFont legendFont = legends[visibleIndex]->font();
legendFont.setPixelSize( m_legendFontPixelSize );
legends[visibleIndex]->setFont( legendFont );
legends[visibleIndex]->show();
}
else
{
legends[visibleIndex]->hide();
}
}
// Set basic row and column stretches
m_gridLayout->setRowStretch( 3 * row + 2, 1 );
for ( int c = col; c < col + colSpan; c++ )
{
int colStretch = 6; // Empirically chosen to try to counter the width of the axis on the first track
if ( showYAxis( row, col ) ) colStretch += 1;
m_gridLayout->setColumnStretch( c, std::max( colStretch, m_gridLayout->columnStretch( c ) ) );
}
visibleIndex++;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryMultiPlotPage::reservePlaceholders( int count )
{
while ( m_placeholderWidgets.size() < count )
{
m_placeholderWidgets.push_back( new QWidget( this ) );
}
}

View File

@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuMultiPlotPage.h"
class RimSummaryMultiPlot;
#include <QList>
#include <QPointer>
#include <QWidget>
class RiuSummaryMultiPlotPage : public RiuMultiPlotPage
{
Q_OBJECT
public:
RiuSummaryMultiPlotPage( RimSummaryMultiPlot* plotDefinition, QWidget* parent = nullptr );
~RiuSummaryMultiPlotPage() override;
protected:
void reinsertPlotWidgets() override;
void reservePlaceholders( int count );
private:
RimSummaryMultiPlot* m_summaryMultiPlot;
QList<QPointer<QWidget>> m_placeholderWidgets;
};