Avoid duplicate plots when appending wells and keep legend order same as project tree

Skip appending plots for wells, groups and networks already present in the multi plot. Reattach curves in project tree order only when the attached order differs.
This commit is contained in:
Magne Sjaastad committed 2026-10-24 13:14:41 +02:00
1 parent 186c4795f9
commit cb60a8b9ae
4 files changed
+101

No files matched your search

@@ -64,11 +64,61 @@ void RicAppendSummaryPlotsForObjectsFeature::appendPlots( RimSummaryMultiPlot*
caf::ProgressInfo info( sumAddressCollections.size(), "Appending plots..." );
// Objects that already have a plot of their own are skipped to avoid duplicated plots. Plots showing several objects of the
// selected type do not count, as they are not a plot for each single object. Objects appended in this call are added to the set.
std::set<std::string> existingObjects;
for ( auto sourcePlot : sourcePlots )
{
RiaSummaryAddressAnalyzer analyzer;
analyzer.appendAddresses( RiaSummaryAddressModifier::allSummaryAddressesY( sourcePlot ) );
std::set<std::string> names;
switch ( selectionType )
{
case RimSummaryAddressCollection::CollectionContentType::WELL:
names = analyzer.wellNames();
break;
case RimSummaryAddressCollection::CollectionContentType::GROUP:
names = analyzer.groupNames();
break;
case RimSummaryAddressCollection::CollectionContentType::NETWORK:
names = analyzer.networkNames();
break;
case RimSummaryAddressCollection::CollectionContentType::REGION:
for ( int regionNumber : analyzer.regionNumbers() )
{
names.insert( std::to_string( regionNumber ) );
}
break;
default:
break;
}
if ( names.size() == 1 ) existingObjects.insert( *names.begin() );
}
auto isDeduplicatedType = []( RimSummaryAddressCollection::CollectionContentType type )
{
using CollectionContentType = RimSummaryAddressCollection::CollectionContentType;
return type == CollectionContentType::WELL || type == CollectionContentType::GROUP || type == CollectionContentType::NETWORK ||
type == CollectionContentType::REGION;
};
summaryMultiPlot->startBatchAddOperation();
RiaPlotWindowRedrawScheduler::instance()->blockUpdate( true );
for ( auto summaryAdrCollection : sumAddressCollections )
{
if ( isDeduplicatedType( summaryAdrCollection->contentType() ) )
{
const auto objectName = summaryAdrCollection->name().toStdString();
if ( !existingObjects.insert( objectName ).second )
{
RiaLogging::info( "Skipped appending plots for '" + objectName + "', as it is already present." );
info.incrementProgress();
continue;
}
}
auto duplicatedPlots = RiaSummaryPlotTools::duplicateSummaryPlots( plotsForOneInstance );
for ( auto duplicatedPlot : duplicatedPlots )
@@ -2316,6 +2316,21 @@ void RimSummaryPlot::onLoadDataAndUpdate()
if ( plotWidget() )
{
// Curves can be attached in a different order than the order in the project tree, and the
// legend follows the order of the attached plot items. Reattaching is costly for many curves,
// so only do it when the order differs.
auto* qwtPlotWidget = dynamic_cast<RiuQwtPlotWidget*>( plotWidget() );
if ( m_summaryCurveCollection && qwtPlotWidget )
{
std::vector<RimPlotCurve*> treeOrderCurves;
for ( auto curve : m_summaryCurveCollection->curves() )
{
treeOrderCurves.push_back( curve );
}
if ( !qwtPlotWidget->isCurveOrderConsistentWith( treeOrderCurves ) ) m_summaryCurveCollection->updateCurveOrder();
}
if ( m_showPlotLegends && !isSubPlot() )
{
plotWidget()->insertLegend( m_legendPosition );
@@ -1306,6 +1306,39 @@ std::vector<caf::PdmPointer<RimPlotCurve>> RiuQwtPlotWidget::highlightedCurves()
return m_highlightedCurves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuQwtPlotWidget::isCurveOrderConsistentWith( const std::vector<RimPlotCurve*>& expectedOrder ) const
{
std::map<const RimPlotCurve*, size_t> expectedIndex;
for ( size_t i = 0; i < expectedOrder.size(); i++ )
{
expectedIndex[expectedOrder[i]] = i;
}
// Plot items are sorted by z-value, and items with equal z-value are kept in attach order
bool hasPrevious = false;
double previousZ = 0.0;
size_t previousIdx = 0;
for ( const QwtPlotItem* plotItem : m_plot->itemList() )
{
auto* riuPlotCurve = dynamic_cast<const RiuQwtPlotCurve*>( plotItem );
if ( !riuPlotCurve ) continue;
auto it = expectedIndex.find( riuPlotCurve->ownerRimCurve() );
if ( it == expectedIndex.end() ) continue;
if ( hasPrevious && plotItem->z() == previousZ && it->second < previousIdx ) return false;
hasPrevious = true;
previousZ = plotItem->z();
previousIdx = it->second;
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -167,6 +167,9 @@ public:
void resetPlotItemHighlighting( bool doUpdateCurveOrder = true );
std::vector<caf::PdmPointer<RimPlotCurve>> highlightedCurves() const;
// True if curves with equal z-value are attached in the same relative order as in the given list
bool isCurveOrderConsistentWith( const std::vector<RimPlotCurve*>& expectedOrder ) const;
// Highlights the plot item closest to the given position, given in widget coordinates. Unlike a left-click, this
// only applies the visual highlight and does not change the project tree / selection manager selection.
void highlightClosestPlotItemAtPosition( const QPoint& widgetPos );