Summary Plots: Support dragging wells, groups and regions into plots (#8550)

Support dropping wells, wellgroups and regions into summary plots.
This commit is contained in:
jonjenssen
2022-02-16 16:36:50 +01:00
committed by GitHub
parent 7fbff9d58b
commit 4a3d9470b4
7 changed files with 275 additions and 23 deletions

View File

@@ -253,3 +253,11 @@ bool RimSummaryAddress::isEnsemble() const
{
return m_ensembleId >= 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryAddress::canBeDragged() const
{
return !isEnsemble();
}

View File

@@ -57,6 +57,8 @@ public:
int ensembleId() const;
bool isEnsemble() const;
bool canBeDragged() const;
QString quantityName() const;
void ensureCalculationIdIsAssigned();

View File

@@ -24,6 +24,18 @@
#include "cafPdmUiTreeOrdering.h"
template <>
void caf::AppEnum<RimSummaryAddressCollection::CollectionContentType>::setUp()
{
addItem( RimSummaryAddressCollection::CollectionContentType::NOT_DEFINED, "NOT_DEFINED", "Not Defined" );
addItem( RimSummaryAddressCollection::CollectionContentType::WELL, "WELL", "Well" );
addItem( RimSummaryAddressCollection::CollectionContentType::WELL_GROUP, "WELL_GROUP", "Well Group" );
addItem( RimSummaryAddressCollection::CollectionContentType::REGION, "REGION", "Region" );
addItem( RimSummaryAddressCollection::CollectionContentType::MISC, "MISC", "Miscellaneous" );
addItem( RimSummaryAddressCollection::CollectionContentType::FIELD, "FIELD", "Field" );
setDefault( RimSummaryAddressCollection::CollectionContentType::NOT_DEFINED );
}
CAF_PDM_SOURCE_INIT( RimSummaryAddressCollection, "RimSummaryAddressCollection" );
//--------------------------------------------------------------------------------------------------
@@ -33,12 +45,23 @@ RimSummaryAddressCollection::RimSummaryAddressCollection()
{
CAF_PDM_InitObject( "Folder", ":/Folder.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_contentType, "ContentsType", "Contents" );
m_contentType = RimSummaryAddressCollection::CollectionContentType::NOT_DEFINED;
m_contentType.uiCapability()->setUiReadOnly( true );
m_contentType.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_adresses, "SummaryAddresses", "Addresses" );
m_adresses.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_subfolders, "AddressSubfolders", "Subfolders" );
m_subfolders.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitField( &m_caseId, "CaseId", -1, "CaseId" );
m_caseId.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_ensembleId, "EnsembleId", -1, "EnsembleId" );
m_ensembleId.uiCapability()->setUiHidden( true );
nameField()->uiCapability()->setUiHidden( true );
}
@@ -77,6 +100,8 @@ void RimSummaryAddressCollection::addAddress( const RifEclipseSummaryAddress& ad
if ( !hasDataVector( address.quantityName() ) )
{
m_adresses.push_back( RimSummaryAddress::wrapFileReaderAddress( address, caseId, ensembleId ) );
if ( m_caseId == -1 ) m_caseId = caseId;
if ( m_ensembleId == -1 ) m_ensembleId = ensembleId;
}
}
@@ -84,11 +109,12 @@ void RimSummaryAddressCollection::addAddress( const RifEclipseSummaryAddress& ad
///
//--------------------------------------------------------------------------------------------------
void RimSummaryAddressCollection::addToSubfolder( QString foldername,
CollectionContentType folderType,
const RifEclipseSummaryAddress& address,
int caseId,
int ensembleId )
{
RimSummaryAddressCollection* folder = getOrCreateSubfolder( foldername );
RimSummaryAddressCollection* folder = getOrCreateSubfolder( foldername, folderType );
folder->addAddress( address, caseId, ensembleId );
}
@@ -101,11 +127,11 @@ void RimSummaryAddressCollection::updateFolderStructure( const std::set<RifEclip
{
if ( addresses.size() == 0 ) return;
RimSummaryAddressCollection* misc = getOrCreateSubfolder( "Miscellaneous" );
RimSummaryAddressCollection* fields = getOrCreateSubfolder( "Field" );
RimSummaryAddressCollection* misc = getOrCreateSubfolder( "Miscellaneous", CollectionContentType::MISC );
RimSummaryAddressCollection* fields = getOrCreateSubfolder( "Field", CollectionContentType::FIELD );
RimSummaryAddressCollection* regions = getOrCreateSubfolder( "Regions" );
RimSummaryAddressCollection* wells = getOrCreateSubfolder( "Wells" );
RimSummaryAddressCollection* groups = getOrCreateSubfolder( "Groups" );
RimSummaryAddressCollection* groups = getOrCreateSubfolder( "Well Groups" );
for ( const auto& address : addresses )
{
@@ -120,15 +146,27 @@ void RimSummaryAddressCollection::updateFolderStructure( const std::set<RifEclip
break;
case RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_REGION:
regions->addToSubfolder( QString::number( address.regionNumber() ), address, caseId, ensembleId );
regions->addToSubfolder( QString::number( address.regionNumber() ),
CollectionContentType::REGION,
address,
caseId,
ensembleId );
break;
case RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL_GROUP:
groups->addToSubfolder( QString::fromStdString( address.wellGroupName() ), address, caseId, ensembleId );
groups->addToSubfolder( QString::fromStdString( address.wellGroupName() ),
CollectionContentType::WELL_GROUP,
address,
caseId,
ensembleId );
break;
case RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL:
wells->addToSubfolder( QString::fromStdString( address.wellName() ), address, caseId, ensembleId );
wells->addToSubfolder( QString::fromStdString( address.wellName() ),
CollectionContentType::WELL,
address,
caseId,
ensembleId );
break;
default:
@@ -140,7 +178,8 @@ void RimSummaryAddressCollection::updateFolderStructure( const std::set<RifEclip
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryAddressCollection* RimSummaryAddressCollection::getOrCreateSubfolder( const QString folderName )
RimSummaryAddressCollection* RimSummaryAddressCollection::getOrCreateSubfolder( const QString folderName,
CollectionContentType createFolderType )
{
for ( auto& folder : m_subfolders )
{
@@ -152,6 +191,7 @@ RimSummaryAddressCollection* RimSummaryAddressCollection::getOrCreateSubfolder(
RimSummaryAddressCollection* newFolder = new RimSummaryAddressCollection();
newFolder->setName( folderName );
newFolder->setContentType( createFolderType );
m_subfolders.push_back( newFolder );
return newFolder;
}
@@ -173,6 +213,20 @@ bool RimSummaryAddressCollection::isEmpty() const
return ( ( m_adresses.size() == 0 ) && ( m_subfolders.size() == 0 ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryAddressCollection::canBeDragged() const
{
bool ok = m_subfolders.size() == 0;
ok = ok && !isEnsemble();
ok = ok && ( m_contentType == CollectionContentType::WELL || m_contentType == CollectionContentType::WELL_GROUP ||
m_contentType == CollectionContentType::REGION );
return ok;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -188,3 +242,59 @@ void RimSummaryAddressCollection::updateUiTreeOrdering( caf::PdmUiTreeOrdering&
uiTreeOrdering.add( address );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryAddressCollection::setContentType( CollectionContentType content )
{
m_contentType = content;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryAddressCollection::CollectionContentType RimSummaryAddressCollection::contentType() const
{
return m_contentType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryAddressCollection::setEnsembleId( int ensembleId )
{
m_ensembleId = ensembleId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryAddressCollection::setCaseId( int caseId )
{
m_caseId = caseId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryAddressCollection::isEnsemble() const
{
return m_ensembleId >= 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimSummaryAddressCollection::ensembleId() const
{
return m_ensembleId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimSummaryAddressCollection::caseId() const
{
return m_caseId;
}

View File

@@ -32,28 +32,59 @@ class RimSummaryAddressCollection : public RimNamedObject
{
CAF_PDM_HEADER_INIT;
public:
enum class CollectionContentType
{
NOT_DEFINED,
WELL,
WELL_GROUP,
REGION,
FIELD,
MISC
};
public:
RimSummaryAddressCollection();
~RimSummaryAddressCollection() override;
void updateFolderStructure( const std::set<RifEclipseSummaryAddress>& addresses, int caseid, int ensembleId = -1 );
void updateFolderStructure( const std::set<RifEclipseSummaryAddress>& addresses, int caseId, int ensembleId = -1 );
void clear();
bool isEmpty() const;
bool isEnsemble() const;
bool canBeDragged() const;
void updateUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering ) const;
void setContentType( CollectionContentType content );
CollectionContentType contentType() const;
void setCaseId( int caseId );
int caseId() const;
void setEnsembleId( int ensembleId );
int ensembleId() const;
private:
RimSummaryAddressCollection* getOrCreateSubfolder( const QString folderName );
RimSummaryAddressCollection*
getOrCreateSubfolder( const QString folderName,
CollectionContentType createFolderType = CollectionContentType::NOT_DEFINED );
bool hasDataVector( const QString quantityName ) const;
bool hasDataVector( const std::string quantityName ) const;
void addAddress( const RifEclipseSummaryAddress& address, int caseId, int ensembleId = -1 );
void addToSubfolder( QString foldername, const RifEclipseSummaryAddress& address, int caseId, int ensembleId = -1 );
void addToSubfolder( QString foldername,
CollectionContentType folderType,
const RifEclipseSummaryAddress& address,
int caseId,
int ensembleId = -1 );
private:
caf::PdmChildArrayField<RimSummaryAddress*> m_adresses;
caf::PdmChildArrayField<RimSummaryAddressCollection*> m_subfolders;
caf::PdmField<caf::AppEnum<CollectionContentType>> m_contentType;
caf::PdmField<int> m_caseId;
caf::PdmField<int> m_ensembleId;
};

View File

@@ -44,6 +44,7 @@
#include "RimPlotAxisProperties.h"
#include "RimProject.h"
#include "RimSummaryAddress.h"
#include "RimSummaryAddressCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCurveCollection.h"
@@ -1793,36 +1794,121 @@ bool RimSummaryPlot::autoPlotTitle() const
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::handleDroppedObjects( const std::vector<caf::PdmObjectHandle*>& objects )
{
int newCurves = 0;
for ( auto obj : objects )
{
auto summaryAdr = dynamic_cast<RimSummaryAddress*>( obj );
if ( summaryAdr )
{
if ( summaryAdr->isEnsemble() )
if ( summaryAdr->isEnsemble() ) continue;
auto summaryCase = RiaSummaryTools::summaryCaseById( summaryAdr->caseId() );
if ( summaryCase )
{
// TODO: Add drop support for ensemble curves
addNewCurveY( summaryAdr->address(), summaryCase );
newCurves++;
}
else
continue;
}
auto addressCollection = dynamic_cast<RimSummaryAddressCollection*>( obj );
if ( addressCollection )
{
auto droppedName = addressCollection->name().toStdString();
if ( addressCollection->isEnsemble() ) continue;
auto summaryCase = RiaSummaryTools::summaryCaseById( addressCollection->caseId() );
if ( summaryCase )
{
auto summaryCase = RiaSummaryTools::summaryCaseById( summaryAdr->caseId() );
if ( summaryCase )
if ( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::WELL )
{
auto* newCurve = new RimSummaryCurve();
std::map<std::string, std::set<std::string>> dataVectorMap;
newCurve->setSummaryCaseY( summaryCase );
newCurve->setSummaryAddressYAndApplyInterpolation( summaryAdr->address() );
for ( auto& curve : summaryCurves() )
{
const auto curveAddress = curve->summaryAddressY();
if ( curveAddress.category() == RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL )
{
dataVectorMap[curveAddress.quantityName()].insert( curveAddress.wellName() );
}
}
addCurveNoUpdate( newCurve );
for ( auto& [vectorName, wellNames] : dataVectorMap )
{
if ( wellNames.count( droppedName ) > 0 ) continue;
newCurve->loadDataAndUpdate( true );
addNewCurveY( RifEclipseSummaryAddress::wellAddress( vectorName, droppedName ), summaryCase );
newCurves++;
}
}
else if ( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::WELL_GROUP )
{
std::map<std::string, std::set<std::string>> dataVectorMap;
for ( auto& curve : summaryCurves() )
{
const auto curveAddress = curve->summaryAddressY();
if ( curveAddress.category() == RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL_GROUP )
{
dataVectorMap[curveAddress.quantityName()].insert( curveAddress.wellGroupName() );
}
}
for ( auto& [vectorName, wellGroupNames] : dataVectorMap )
{
if ( wellGroupNames.count( droppedName ) > 0 ) continue;
addNewCurveY( RifEclipseSummaryAddress::wellGroupAddress( vectorName, droppedName ), summaryCase );
newCurves++;
}
}
else if ( addressCollection->contentType() == RimSummaryAddressCollection::CollectionContentType::REGION )
{
std::map<std::string, std::set<int>> dataVectorMap;
for ( auto& curve : summaryCurves() )
{
const auto curveAddress = curve->summaryAddressY();
if ( curveAddress.category() == RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_REGION )
{
dataVectorMap[curveAddress.quantityName()].insert( curveAddress.regionNumber() );
}
}
int droppedRegion = std::stoi( droppedName );
for ( auto& [vectorName, regionNumbers] : dataVectorMap )
{
if ( regionNumbers.count( droppedRegion ) > 0 ) continue;
addNewCurveY( RifEclipseSummaryAddress::regionAddress( vectorName, droppedRegion ), summaryCase );
newCurves++;
}
}
}
continue;
}
}
if ( newCurves > 0 ) applyDefaultCurveAppearances();
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::addNewCurveY( const RifEclipseSummaryAddress& address, RimSummaryCase* summaryCase )
{
RimSummaryCurve* newCurve = new RimSummaryCurve();
newCurve->setSummaryCaseY( summaryCase );
newCurve->setSummaryAddressYAndApplyInterpolation( address );
addCurveNoUpdate( newCurve );
newCurve->loadDataAndUpdate( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -263,6 +263,8 @@ private:
void assignPlotAxis( RimSummaryCurve* curve );
void addNewCurveY( const RifEclipseSummaryAddress& address, RimSummaryCase* summaryCase );
private:
#ifdef USE_QTCHARTS
caf::PdmField<bool> m_useQtChartsPlot;

View File

@@ -34,6 +34,7 @@
#include "RimMultiPlot.h"
#include "RimPlot.h"
#include "RimSummaryAddress.h"
#include "RimSummaryAddressCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCaseMainCollection.h"
@@ -251,11 +252,23 @@ Qt::ItemFlags RiuDragDrop::flags( const QModelIndex& index ) const
if ( dynamic_cast<RimEclipseCase*>( uiItem ) || dynamic_cast<RimWellLogCurve*>( uiItem ) ||
dynamic_cast<RimWellLogFileChannel*>( uiItem ) || dynamic_cast<RimPlot*>( uiItem ) ||
dynamic_cast<RimSummaryCase*>( uiItem ) || dynamic_cast<RimSummaryCurve*>( uiItem ) ||
dynamic_cast<RimSurface*>( uiItem ) || dynamic_cast<RimSummaryAddress*>( uiItem ) )
dynamic_cast<RimSurface*>( uiItem ) )
{
// TODO: Remember to handle reservoir holding the main grid
itemflags |= Qt::ItemIsDragEnabled;
}
else
{
auto sumAdrColl = dynamic_cast<RimSummaryAddressCollection*>( uiItem );
if ( sumAdrColl && sumAdrColl->canBeDragged() )
{
itemflags |= Qt::ItemIsDragEnabled;
}
auto sumAdr = dynamic_cast<RimSummaryAddress*>( uiItem );
if ( sumAdr && sumAdr->canBeDragged() )
{
itemflags |= Qt::ItemIsDragEnabled;
}
}
if ( m_dragItems.empty() ) return itemflags;