mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#5539 Initial AnalysisPlot objects and barchart builder
This commit is contained in:
parent
86fa10fd13
commit
a1410ca118
@ -70,10 +70,12 @@ include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Intersections
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Surfaces
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/UserInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/UserInterface/AnalysisPlots
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CommandFileInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CommandFileInterface/Core
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/AnalysisPlots
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Annotations
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Completions
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Flow
|
||||
@ -139,6 +141,7 @@ list( APPEND REFERENCED_CMAKE_FILES
|
||||
FileInterface/CMakeLists_files.cmake
|
||||
|
||||
ProjectDataModel/CMakeLists_files.cmake
|
||||
ProjectDataModel/AnalysisPlots/CMakeLists_files.cmake
|
||||
ProjectDataModel/GridCrossPlots/CMakeLists_files.cmake
|
||||
ProjectDataModel/GridCrossPlots/CellFilters/CMakeLists_files.cmake
|
||||
ProjectDataModel/Summary/CMakeLists_files.cmake
|
||||
@ -158,8 +161,10 @@ list( APPEND REFERENCED_CMAKE_FILES
|
||||
ModelVisualization/WindowEdgeAxesOverlayItem/CMakeLists_files.cmake
|
||||
|
||||
UserInterface/CMakeLists_files.cmake
|
||||
UserInterface/AnalysisPlots/CMakeLists_files.cmake
|
||||
|
||||
Commands/CMakeLists_files.cmake
|
||||
Commands/AnalysisPlotCommands/CMakeLists_files.cmake
|
||||
Commands/ApplicationCommands/CMakeLists_files.cmake
|
||||
Commands/AnnotationCommands/CMakeLists_files.cmake
|
||||
Commands/CompletionCommands/CMakeLists_files.cmake
|
||||
|
@ -0,0 +1,18 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewAnalysisPlotFeature.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewAnalysisPlotFeature.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
source_group( "CommandFeature\\AnalysisPlotCommands" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
@ -0,0 +1,81 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- 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 "RicNewAnalysisPlotFeature.h"
|
||||
|
||||
#include "RimAnalysisPlot.h"
|
||||
#include "RimAnalysisPlotCollection.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewAnalysisPlotFeature, "RicNewAnalysisPlotFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicNewAnalysisPlotFeature::isCommandEnabled()
|
||||
{
|
||||
RimAnalysisPlotCollection* analysisPlotColl = nullptr;
|
||||
|
||||
caf::PdmObject* selObj = dynamic_cast<caf::PdmObject*>( caf::SelectionManager::instance()->selectedItem() );
|
||||
if ( selObj )
|
||||
{
|
||||
selObj->firstAncestorOrThisOfType( analysisPlotColl );
|
||||
}
|
||||
|
||||
if ( analysisPlotColl ) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewAnalysisPlotFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
RimAnalysisPlotCollection* analysisPlotColl = nullptr;
|
||||
|
||||
caf::PdmObject* selObj = dynamic_cast<caf::PdmObject*>( caf::SelectionManager::instance()->selectedItem() );
|
||||
if ( selObj )
|
||||
{
|
||||
selObj->firstAncestorOrThisOfType( analysisPlotColl );
|
||||
}
|
||||
|
||||
if ( !analysisPlotColl ) return;
|
||||
|
||||
auto newPlot = analysisPlotColl->createAnalysisPlot();
|
||||
newPlot->loadDataAndUpdate();
|
||||
|
||||
analysisPlotColl->updateConnectedEditors();
|
||||
|
||||
RiuPlotMainWindowTools::setExpanded( newPlot );
|
||||
RiuPlotMainWindowTools::selectAsCurrentItem( newPlot );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewAnalysisPlotFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "New Analysis Plot" );
|
||||
actionToSetup->setIcon( QIcon( ":/Histogram16x16.png" ) );
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- 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 "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicNewAnalysisPlotFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotDataEntry.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotCollection.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotDataEntry.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotCollection.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
list(APPEND QT_MOC_HEADERS
|
||||
)
|
||||
|
||||
source_group( "ProjectDataModel\\AnalysisPlots" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
@ -0,0 +1,385 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 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 "RimAnalysisPlot.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
#include "RimAnalysisPlotDataEntry.h"
|
||||
#include "RiuGroupedBarChartBuilder.h"
|
||||
#include "RiuSummaryQwtPlot.h"
|
||||
|
||||
#include "qwt_column_symbol.h"
|
||||
#include "qwt_legend.h"
|
||||
#include "qwt_painter.h"
|
||||
#include "qwt_plot_barchart.h"
|
||||
#include "qwt_scale_draw.h"
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void caf::AppEnum<RimAnalysisPlot::SortGroupType>::setUp()
|
||||
{
|
||||
addItem( RimAnalysisPlot::SUMMARY_ITEM, "SUMMARY_ITEM", "Summary Item" );
|
||||
addItem( RimAnalysisPlot::CASE, "CASE", "Case" );
|
||||
addItem( RimAnalysisPlot::ENSEMBLE, "ENSEMBLE", "Ensemble" );
|
||||
addItem( RimAnalysisPlot::VALUE, "VALUE", "Value" );
|
||||
addItem( RimAnalysisPlot::ABS_VALUE, "ABS_VALUE", "abs(Value)" );
|
||||
addItem( RimAnalysisPlot::OTHER_VALUE, "OTHER_VALUE", "Other Value" );
|
||||
addItem( RimAnalysisPlot::ABS_OTHER_VALUE, "ABS_OTHER_VALUE", "abs(Other Value)" );
|
||||
addItem( RimAnalysisPlot::TIME_STEP, "TIME_STEP", "Time Step" );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimAnalysisPlot, "AnalysisPlot" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlot::RimAnalysisPlot()
|
||||
: RimPlot()
|
||||
{
|
||||
CAF_PDM_InitObject( "Analysis Plot", ":/Histogram16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_showPlotTitle, "ShowPlotTitle", true, "Plot Title", "", "", "" );
|
||||
m_showPlotTitle.xmlCapability()->setIOWritable( false );
|
||||
|
||||
CAF_PDM_InitField( &m_useAutoPlotTitle, "IsUsingAutoName", true, "Auto Title", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_description, "PlotDescription", QString( "Summary Plot" ), "Name", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_data, "AnalysisPlotData", "", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "TimeSteps", "", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_sortGroupSortingOrder, "sortingOrder", "Sort Order", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_sortGroupsToGroup, "grouping", "Grouping", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_sortGroupForLegend, "groupForLegend", "Legend Using", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlot::~RimAnalysisPlot()
|
||||
{
|
||||
removeMdiWindowFromMdiArea();
|
||||
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::cleanupBeforeClose()
|
||||
{
|
||||
detachAllCurves();
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->setParent( nullptr );
|
||||
delete m_plotWidget;
|
||||
m_plotWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimAnalysisPlot::showPlotTitle() const
|
||||
{
|
||||
return m_showPlotTitle;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::setShowPlotTitle( bool showTitle )
|
||||
{
|
||||
m_showPlotTitle = showTitle;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::detachAllCurves() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::reattachAllCurves() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::updateAxes() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* RimAnalysisPlot::viewWidget()
|
||||
{
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtPlotWidget* RimAnalysisPlot::viewer()
|
||||
{
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimAnalysisPlot::asciiDataForPlotExport() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::updateLegend() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimAnalysisPlot::hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimAnalysisPlot::applyFontSize( RiaDefines::FontSettingType fontSettingType,
|
||||
int oldFontSize,
|
||||
int fontSize,
|
||||
bool forceChange /*= false */ )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::setAutoScaleXEnabled( bool enabled ) {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::setAutoScaleYEnabled( bool enabled ) {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::zoomAll() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::updateZoomInQwt() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::updateZoomFromQwt() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmObject* RimAnalysisPlot::findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::onAxisSelected( int axis, bool toggle ) {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::deleteViewWidget()
|
||||
{
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimAnalysisPlot::description() const
|
||||
{
|
||||
return m_description();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::updateCaseNameHasChanged()
|
||||
{
|
||||
// Todo
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtPlotWidget* RimAnalysisPlot::doCreatePlotViewWidget( QWidget* mainWindowParent /*= nullptr */ )
|
||||
{
|
||||
if ( !m_plotWidget )
|
||||
{
|
||||
m_plotWidget = new RiuQwtPlotWidget( this, mainWindowParent );
|
||||
|
||||
this->connect( m_plotWidget, SIGNAL( plotZoomed() ), SLOT( onPlotZoomed() ) );
|
||||
|
||||
// updatePlotTitle();
|
||||
}
|
||||
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::doUpdateLayout() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::doRemoveFromCollection() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QImage RimAnalysisPlot::snapshotWindowContent()
|
||||
{
|
||||
QImage image;
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
QPixmap pix = m_plotWidget->grab();
|
||||
image = pix.toImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimAnalysisPlot::userDescriptionField()
|
||||
{
|
||||
return &m_description;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= "" */ ) {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
updateMdiWindowVisibility();
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
RiuGroupedBarChartBuilder chartBuilder( Qt::Horizontal );
|
||||
|
||||
chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R1", 0.5 );
|
||||
chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R2", 0.55 );
|
||||
chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R1", 0.7 );
|
||||
chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R2", 0.75 );
|
||||
chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R1", 1.05 );
|
||||
chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R2", 1.0 );
|
||||
|
||||
chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R1", 1.5 );
|
||||
chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R2", 1.5 );
|
||||
chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R1", 2.0 );
|
||||
chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R2", 2.0 );
|
||||
|
||||
chartBuilder.addBarEntry( "T3", "W1", "1", std::numeric_limits<double>::infinity(), "R1", 1.5 );
|
||||
chartBuilder.addBarEntry( "T3", "W1", "2", std::numeric_limits<double>::infinity(), "R2", 1.5 );
|
||||
chartBuilder.addBarEntry( "T3", "W2", "3", std::numeric_limits<double>::infinity(), "R1", 2.0 );
|
||||
chartBuilder.addBarEntry( "T3", "W2", "4", std::numeric_limits<double>::infinity(), "R1", 2.0 );
|
||||
chartBuilder.addBarEntry( "T3", "W2", "5", std::numeric_limits<double>::infinity(), "R1", 2.0 );
|
||||
|
||||
chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", 1.5 );
|
||||
chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", 1.5 );
|
||||
chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", 2.0 );
|
||||
chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", 2.0 );
|
||||
chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", 1.6 );
|
||||
chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", 1.6 );
|
||||
chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", 2.6 );
|
||||
chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", -0.3 );
|
||||
|
||||
chartBuilder.addBarEntry( "T5", "", "G1", 1.5, "R3", 1.5 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G2", 1.5, "R3", 1.5 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G3", 2.0, "R3", 2.0 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G4", 2.0, "R3", 2.0 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G5", 1.6, "R3", 1.6 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G6", 1.6, "R3", 1.6 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G7", 2.6, "R3", 2.6 );
|
||||
chartBuilder.addBarEntry( "T5", "", "G8", -0.3, "R3", -0.3 );
|
||||
|
||||
chartBuilder.addBarEntry( "", "", "", 1.2, "", 1.2 );
|
||||
chartBuilder.addBarEntry( "", "", "", 1.5, "", 1.5 );
|
||||
chartBuilder.addBarEntry( "", "", "", 2.3, "", 2.3 );
|
||||
chartBuilder.addBarEntry( "", "", "", 2.0, "", 2.0 );
|
||||
chartBuilder.addBarEntry( "", "", "", 1.6, "", 1.6 );
|
||||
chartBuilder.addBarEntry( "", "", "", 2.4, "", -2.4 );
|
||||
|
||||
chartBuilder.addBarChartToPlot( m_plotWidget );
|
||||
|
||||
if ( m_showPlotLegends && m_plotWidget->legend() == nullptr )
|
||||
{
|
||||
QwtLegend* legend = new QwtLegend( m_plotWidget );
|
||||
m_plotWidget->insertLegend( legend, QwtPlot::RightLegend );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plotWidget->insertLegend( nullptr );
|
||||
}
|
||||
|
||||
// m_plotWidget->setLegendFontSize( m_legendFontSize() );
|
||||
m_plotWidget->updateLegend();
|
||||
}
|
||||
|
||||
this->updateAxes();
|
||||
}
|
124
ApplicationCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.h
Normal file
124
ApplicationCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.h
Normal file
@ -0,0 +1,124 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 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 "RimPlot.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class RiuSummaryQwtPlot;
|
||||
class RimAnalysisPlotDataEntry;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimAnalysisPlot : public RimPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimAnalysisPlot();
|
||||
~RimAnalysisPlot() override;
|
||||
|
||||
bool showPlotTitle() const;
|
||||
void setShowPlotTitle( bool showTitle );
|
||||
|
||||
void detachAllCurves() override;
|
||||
void reattachAllCurves() override;
|
||||
|
||||
void updateAxes() override;
|
||||
QWidget* viewWidget() override;
|
||||
RiuQwtPlotWidget* viewer() override;
|
||||
|
||||
QString asciiDataForPlotExport() const override;
|
||||
|
||||
void updateLegend() override;
|
||||
|
||||
bool hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const override;
|
||||
bool applyFontSize( RiaDefines::FontSettingType fontSettingType,
|
||||
int oldFontSize,
|
||||
int fontSize,
|
||||
bool forceChange = false ) override;
|
||||
|
||||
void setAutoScaleXEnabled( bool enabled ) override;
|
||||
void setAutoScaleYEnabled( bool enabled ) override;
|
||||
|
||||
void zoomAll() override;
|
||||
void updateZoomInQwt() override;
|
||||
void updateZoomFromQwt() override;
|
||||
|
||||
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
|
||||
|
||||
void onAxisSelected( int axis, bool toggle ) override;
|
||||
|
||||
// RimViewWindow overrides
|
||||
void deleteViewWidget() override;
|
||||
|
||||
enum SortGroupType
|
||||
{
|
||||
SUMMARY_ITEM,
|
||||
CASE,
|
||||
ENSEMBLE,
|
||||
VALUE,
|
||||
ABS_VALUE,
|
||||
OTHER_VALUE,
|
||||
ABS_OTHER_VALUE,
|
||||
TIME_STEP,
|
||||
};
|
||||
|
||||
QString description() const override;
|
||||
|
||||
void updateCaseNameHasChanged();
|
||||
|
||||
private:
|
||||
RiuQwtPlotWidget* doCreatePlotViewWidget( QWidget* mainWindowParent = nullptr ) override;
|
||||
void cleanupBeforeClose();
|
||||
|
||||
void doUpdateLayout() override;
|
||||
|
||||
void doRemoveFromCollection() override;
|
||||
|
||||
QImage snapshotWindowContent() override;
|
||||
|
||||
// Overridden PDM methods
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue ) override;
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
private:
|
||||
QPointer<RiuQwtPlotWidget> m_plotWidget;
|
||||
|
||||
caf::PdmField<bool> m_showPlotTitle;
|
||||
caf::PdmField<bool> m_useAutoPlotTitle;
|
||||
caf::PdmField<QString> m_description;
|
||||
|
||||
caf::PdmChildArrayField<RimAnalysisPlotDataEntry*> m_data;
|
||||
|
||||
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
|
||||
|
||||
caf::PdmField<std::vector<caf::AppEnum<SortGroupType>>> m_sortGroupSortingOrder;
|
||||
caf::PdmField<std::vector<caf::AppEnum<SortGroupType>>> m_sortGroupsToGroup;
|
||||
|
||||
caf::PdmField<caf::AppEnum<SortGroupType>> m_sortGroupForLegend;
|
||||
};
|
@ -0,0 +1,80 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- 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 "RimAnalysisPlotCollection.h"
|
||||
|
||||
#include "RimAnalysisPlot.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimAnalysisPlotCollection, "AnalysisPlotCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotCollection::RimAnalysisPlotCollection()
|
||||
{
|
||||
CAF_PDM_InitObject( "Analysis Plots", ":/Histograms16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_analysisPlots, "AnalysisPlots", "Analysis Plots", "", "", "" );
|
||||
m_analysisPlots.uiCapability()->setUiHidden( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotCollection::~RimAnalysisPlotCollection() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlot* RimAnalysisPlotCollection::createAnalysisPlot()
|
||||
{
|
||||
RimAnalysisPlot* plot = new RimAnalysisPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
|
||||
// plot->enableAutoPlotTitle( true );
|
||||
m_analysisPlots.push_back( plot );
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::updateSummaryNameHasChanged()
|
||||
{
|
||||
for ( RimAnalysisPlot* plot : m_analysisPlots )
|
||||
{
|
||||
plot->updateCaseNameHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::removeSummaryPlot( RimAnalysisPlot* analysisPlot )
|
||||
{
|
||||
m_analysisPlots.removeChildObject( analysisPlot );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::deleteAllChildObjects()
|
||||
{
|
||||
m_analysisPlots.deleteAllChildObjects();
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- 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 "cafPdmChildArrayField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
class RimAnalysisPlot;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimAnalysisPlotCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimAnalysisPlotCollection();
|
||||
~RimAnalysisPlotCollection() override;
|
||||
|
||||
RimAnalysisPlot* createAnalysisPlot();
|
||||
void updateSummaryNameHasChanged();
|
||||
void removeSummaryPlot( RimAnalysisPlot* analysisPlot );
|
||||
|
||||
void deleteAllChildObjects();
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimAnalysisPlot*> m_analysisPlots;
|
||||
};
|
@ -0,0 +1,78 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 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 "RimAnalysisPlotDataEntry.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimAnalysisPlotDataEntry, "AnalysisPlotDataEntry" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotDataEntry::RimAnalysisPlotDataEntry()
|
||||
{
|
||||
CAF_PDM_InitObject( "Data Entry", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryCase, "SummaryCase", "Case", "", "", "" );
|
||||
m_summaryCase.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_summaryCase.uiCapability()->setAutoAddingOptionFromValue( false );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryAddress, "SummaryAddress", "Summary Address", "", "", "" );
|
||||
m_summaryAddress.uiCapability()->setUiHidden( true );
|
||||
m_summaryAddress.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_summaryAddress = new RimSummaryAddress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotDataEntry::~RimAnalysisPlotDataEntry() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotDataEntry::setSummaryCase( RimSummaryCase* sumCase )
|
||||
{
|
||||
m_summaryCase = sumCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCase* RimAnalysisPlotDataEntry::summaryCase() const
|
||||
{
|
||||
return m_summaryCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotDataEntry::setSummaryAddress( const RifEclipseSummaryAddress& address )
|
||||
{
|
||||
m_summaryAddress->setAddress( address );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseSummaryAddress RimAnalysisPlotDataEntry::summaryAddress() const
|
||||
{
|
||||
return m_summaryAddress->address();
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 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 "RifEclipseSummaryAddress.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimSummaryCase;
|
||||
class RimSummaryAddress;
|
||||
|
||||
class RimAnalysisPlotDataEntry : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimAnalysisPlotDataEntry();
|
||||
~RimAnalysisPlotDataEntry() override;
|
||||
|
||||
void setSummaryCase( RimSummaryCase* sumCase );
|
||||
RimSummaryCase* summaryCase() const;
|
||||
|
||||
void setSummaryAddress( const RifEclipseSummaryAddress& address );
|
||||
RifEclipseSummaryAddress summaryAddress() const;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimSummaryCase*> m_summaryCase;
|
||||
caf::PdmChildField<RimSummaryAddress*> m_summaryAddress;
|
||||
};
|
@ -148,6 +148,8 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "RimAnalysisPlot.h"
|
||||
#include "RimAnalysisPlotCollection.h"
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -511,6 +513,14 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicShowSummaryCurveCalculatorFeature";
|
||||
}
|
||||
else if ( dynamic_cast<RimAnalysisPlotCollection*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder << "RicNewAnalysisPlotFeature";
|
||||
}
|
||||
else if ( dynamic_cast<RimAnalysisPlot*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder << "RicNewAnalysisPlotFeature";
|
||||
}
|
||||
else if ( dynamic_cast<RimSummaryCrossPlotCollection*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder << "RicPasteSummaryCrossPlotFeature";
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
#include "RiuProjectPropertyView.h"
|
||||
#include "RimAnalysisPlotCollection.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimMainPlotCollection, "MainPlotCollection" );
|
||||
|
||||
@ -65,6 +66,9 @@ RimMainPlotCollection::RimMainPlotCollection()
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryPlotCollection, "SummaryPlotCollection", "Summary Plots", "", "", "" );
|
||||
m_summaryPlotCollection.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_analysisPlotCollection, "AnalysisPlotCollection", "Analysis Plots", "", "", "" );
|
||||
m_analysisPlotCollection.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryCrossPlotCollection, "SummaryCrossPlotCollection", "Summary Cross Plots", "", "", "" );
|
||||
m_summaryCrossPlotCollection.uiCapability()->setUiHidden( true );
|
||||
|
||||
@ -94,6 +98,7 @@ RimMainPlotCollection::RimMainPlotCollection()
|
||||
m_gridCrossPlotCollection = new RimGridCrossPlotCollection;
|
||||
m_saturationPressurePlotCollection = new RimSaturationPressurePlotCollection;
|
||||
m_multiPlotCollection = new RimMultiPlotCollection;
|
||||
m_analysisPlotCollection = new RimAnalysisPlotCollection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -192,6 +197,14 @@ RimMultiPlotCollection* RimMainPlotCollection::multiPlotCollection()
|
||||
return m_multiPlotCollection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotCollection* RimMainPlotCollection::analysisPlotCollection()
|
||||
{
|
||||
return m_analysisPlotCollection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -206,6 +219,7 @@ void RimMainPlotCollection::deleteAllContainedObjects()
|
||||
m_flowPlotCollection()->closeDefaultPlotWindowAndDeletePlots();
|
||||
m_saturationPressurePlotCollection()->deleteAllChildObjects();
|
||||
m_multiPlotCollection()->deleteAllChildObjects();
|
||||
m_analysisPlotCollection()->deleteAllChildObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <QDockWidget>
|
||||
#include <QPointer>
|
||||
|
||||
class RimAnalysisPlotCollection;
|
||||
class RimWellLogPlotCollection;
|
||||
class RimRftPlotCollection;
|
||||
class RimPltPlotCollection;
|
||||
@ -56,6 +57,7 @@ public:
|
||||
RimPltPlotCollection* pltPlotCollection();
|
||||
RimSummaryPlotCollection* summaryPlotCollection();
|
||||
RimSummaryCrossPlotCollection* summaryCrossPlotCollection();
|
||||
RimAnalysisPlotCollection* analysisPlotCollection();
|
||||
RimFlowPlotCollection* flowPlotCollection();
|
||||
RimGridCrossPlotCollection* gridCrossPlotCollection();
|
||||
RimSaturationPressurePlotCollection* saturationPressurePlotCollection();
|
||||
@ -80,6 +82,7 @@ private:
|
||||
caf::PdmChildField<RimPltPlotCollection*> m_pltPlotCollection;
|
||||
caf::PdmChildField<RimSummaryPlotCollection*> m_summaryPlotCollection;
|
||||
caf::PdmChildField<RimSummaryCrossPlotCollection*> m_summaryCrossPlotCollection;
|
||||
caf::PdmChildField<RimAnalysisPlotCollection*> m_analysisPlotCollection;
|
||||
caf::PdmChildField<RimFlowPlotCollection*> m_flowPlotCollection;
|
||||
caf::PdmChildField<RimGridCrossPlotCollection*> m_gridCrossPlotCollection;
|
||||
caf::PdmChildField<RimSaturationPressurePlotCollection*> m_saturationPressurePlotCollection;
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "PlotTemplates/RimPlotTemplateFolderItem.h"
|
||||
#include "RimAdvancedSnapshotExportDefinition.h"
|
||||
#include "RimAnalysisPlotCollection.h"
|
||||
#include "RimAnnotationCollection.h"
|
||||
#include "RimAnnotationInViewCollection.h"
|
||||
#include "RimCalcScript.h"
|
||||
@ -1320,6 +1321,11 @@ void RimProject::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, Q
|
||||
itemCollection->add( mainPlotCollection->summaryPlotCollection() );
|
||||
}
|
||||
|
||||
if ( mainPlotCollection->analysisPlotCollection() )
|
||||
{
|
||||
itemCollection->add( mainPlotCollection->analysisPlotCollection() );
|
||||
}
|
||||
|
||||
if ( mainPlotCollection->summaryCrossPlotCollection() )
|
||||
{
|
||||
itemCollection->add( mainPlotCollection->summaryCrossPlotCollection() );
|
||||
|
@ -0,0 +1,26 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuGroupedBarChartBuilder.h
|
||||
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuGroupedBarChartBuilder.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
list(APPEND QT_MOC_HEADERS
|
||||
|
||||
)
|
||||
|
||||
list(APPEND QT_UI_FILES
|
||||
)
|
||||
|
||||
source_group( "UserInterface/AnalysisPlots" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
@ -0,0 +1,470 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 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 "RiuGroupedBarChartBuilder.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
|
||||
#include "qwt_column_symbol.h"
|
||||
#include "qwt_legend.h"
|
||||
#include "qwt_painter.h"
|
||||
#include "qwt_plot.h"
|
||||
#include "qwt_plot_barchart.h"
|
||||
#include "qwt_scale_draw.h"
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Overriding to avoid one-pixel overlap of bars.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiuAvoidPixelOverlapColumnSymbol : public QwtColumnSymbol
|
||||
{
|
||||
public:
|
||||
RiuAvoidPixelOverlapColumnSymbol( Style style )
|
||||
: QwtColumnSymbol( style )
|
||||
{
|
||||
}
|
||||
|
||||
void draw( QPainter* painter, const QwtColumnRect& rect ) const override
|
||||
{
|
||||
painter->save();
|
||||
|
||||
switch ( this->style() )
|
||||
{
|
||||
case QwtColumnSymbol::Box:
|
||||
{
|
||||
switch ( this->frameStyle() )
|
||||
{
|
||||
case QwtColumnSymbol::NoFrame:
|
||||
{
|
||||
QRectF r = rect.toRect();
|
||||
if ( QwtPainter::roundingAlignment( painter ) )
|
||||
{
|
||||
r.setLeft( qRound( r.left() ) );
|
||||
r.setRight( qRound( r.right() ) );
|
||||
r.setTop( qRound( r.top() ) );
|
||||
r.setBottom( qRound( r.bottom() ) );
|
||||
}
|
||||
|
||||
painter->fillRect( r,
|
||||
this->palette()
|
||||
.window() ); // This line here is the difference. Qwt adds a 1 to width and height.
|
||||
}
|
||||
break;
|
||||
default:
|
||||
QwtColumnSymbol::drawBox( painter, rect );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Overridden ScaleDraw to add labels for med and min ticks, and to add newlines to get the
|
||||
/// tick texts on different height according to tick level
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiuBarChartScaleDraw : public QwtScaleDraw
|
||||
{
|
||||
public:
|
||||
RiuBarChartScaleDraw( const std::map<double, std::pair<QwtScaleDiv::TickType, QString>>& posTickTypeAndTexts )
|
||||
: m_posTickTypeAndTexts( posTickTypeAndTexts )
|
||||
{
|
||||
}
|
||||
|
||||
/// Override to add new lines to the labels according to the tick level
|
||||
|
||||
QwtText label( double v ) const override
|
||||
{
|
||||
auto posTypeTextPairIt = m_posTickTypeAndTexts.find( v );
|
||||
if ( posTypeTextPairIt != m_posTickTypeAndTexts.end() )
|
||||
{
|
||||
if ( this->alignment() == BottomScale )
|
||||
{
|
||||
if ( posTypeTextPairIt->second.first == QwtScaleDiv::MediumTick )
|
||||
{
|
||||
return "\n" + posTypeTextPairIt->second.second;
|
||||
}
|
||||
else if ( posTypeTextPairIt->second.first == QwtScaleDiv::MajorTick )
|
||||
{
|
||||
return "\n\n" + posTypeTextPairIt->second.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return posTypeTextPairIt->second.second;
|
||||
}
|
||||
}
|
||||
else if ( this->alignment() == LeftScale )
|
||||
{
|
||||
if ( posTypeTextPairIt->second.first == QwtScaleDiv::MediumTick )
|
||||
{
|
||||
return posTypeTextPairIt->second.second + " ";
|
||||
}
|
||||
else if ( posTypeTextPairIt->second.first == QwtScaleDiv::MajorTick )
|
||||
{
|
||||
return posTypeTextPairIt->second.second + " ";
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return posTypeTextPairIt->second.second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return posTypeTextPairIt->second.second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "X"; // Just for debugging
|
||||
}
|
||||
}
|
||||
|
||||
// Override to draw text labels at medium and minor ticks also
|
||||
|
||||
void draw( QPainter* painter, const QPalette& palette ) const override
|
||||
{
|
||||
QwtScaleDraw::draw( painter, palette );
|
||||
|
||||
if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen( palette.color( QPalette::Text ) );
|
||||
|
||||
const QList<double>& mediumTicks = scaleDiv().ticks( QwtScaleDiv::MediumTick );
|
||||
|
||||
for ( int i = 0; i < mediumTicks.count(); i++ )
|
||||
{
|
||||
const double v = mediumTicks[i];
|
||||
if ( scaleDiv().contains( v ) ) drawLabel( painter, mediumTicks[i] );
|
||||
}
|
||||
|
||||
const QList<double>& minorTicks = scaleDiv().ticks( QwtScaleDiv::MinorTick );
|
||||
|
||||
for ( int i = 0; i < minorTicks.count(); i++ )
|
||||
{
|
||||
const double v = minorTicks[i];
|
||||
if ( scaleDiv().contains( v ) ) drawLabel( painter, minorTicks[i] );
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<double, std::pair<QwtScaleDiv::TickType, QString>> m_posTickTypeAndTexts;
|
||||
bool m_hasMinorTickText;
|
||||
bool m_hasMediumTickText;
|
||||
|
||||
protected:
|
||||
virtual void drawBackbone( QPainter* ) const override {}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuGroupedBarChartBuilder::RiuGroupedBarChartBuilder( Qt::Orientation orientation )
|
||||
: m_orientation( orientation )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGroupedBarChartBuilder::addBarEntry( const QString& majorTickText,
|
||||
const QString& midTickText,
|
||||
const QString& minTickText,
|
||||
const double sortValue,
|
||||
const QString& legendText,
|
||||
const double value )
|
||||
{
|
||||
m_sortedBarEntries.insert( BarEntry( majorTickText, midTickText, minTickText, sortValue, legendText, value ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
|
||||
{
|
||||
const double majGroupSpacing = 1.6;
|
||||
const double midGroupSpacing = 0.5;
|
||||
const double minGroupSpacing = 0.2;
|
||||
|
||||
std::set<QString> majTickTexts;
|
||||
std::set<QString> midTickTexts;
|
||||
std::set<QString> minTickTexts;
|
||||
|
||||
double currentBarPosition = 1.0;
|
||||
double currentMajGroupStartPos = 1.0;
|
||||
double currentMidGroupStartPos = 1.0;
|
||||
double currentMinGroupStartPos = 1.0;
|
||||
|
||||
QString previousMajText;
|
||||
QString previousMidText;
|
||||
QString previousMinText;
|
||||
|
||||
std::map<QString, QVector<QPointF>> legendToBarPointsMap;
|
||||
|
||||
std::map<double, std::pair<QwtScaleDiv::TickType, QString>> positionedAxisTexts;
|
||||
|
||||
QList<double> majTickPoss;
|
||||
QList<double> midTickPoss;
|
||||
QList<double> minTickPoss;
|
||||
|
||||
// clang-format off
|
||||
auto addGroupTickText = [&]( double groupStartPos, QString tickText, QList<double>& groupTickPosList )
|
||||
{
|
||||
if( tickText.isEmpty() ) return;
|
||||
|
||||
double tickPos = midPoint( groupStartPos, currentBarPosition );
|
||||
|
||||
QwtScaleDiv::TickType ttyp = &groupTickPosList == &majTickPoss
|
||||
? QwtScaleDiv::MajorTick
|
||||
: &groupTickPosList == &midTickPoss ? QwtScaleDiv::MediumTick
|
||||
: QwtScaleDiv::MinorTick;
|
||||
|
||||
// Make sure we do not get ticks of different level exactly at the same spot,
|
||||
// so that the drawing is able to distinguish
|
||||
|
||||
if( ttyp == QwtScaleDiv::MinorTick ) tickPos += 2e-4;
|
||||
if( ttyp == QwtScaleDiv::MediumTick ) tickPos += 1e-4;
|
||||
|
||||
positionedAxisTexts[tickPos] = { ttyp, tickText };
|
||||
|
||||
groupTickPosList.push_back( tickPos );
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
for ( const BarEntry& barDef : m_sortedBarEntries )
|
||||
{
|
||||
auto majInsertResult = majTickTexts.insert( barDef.m_majTickText );
|
||||
bool isStartingNewMajGroup = majInsertResult.second;
|
||||
bool isFinishingMajGroup = isStartingNewMajGroup && !previousMajText.isEmpty();
|
||||
|
||||
if ( isFinishingMajGroup )
|
||||
{
|
||||
addGroupTickText( currentMajGroupStartPos, previousMajText, majTickPoss );
|
||||
addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPoss );
|
||||
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss );
|
||||
|
||||
currentBarPosition += majGroupSpacing;
|
||||
}
|
||||
|
||||
if ( isStartingNewMajGroup )
|
||||
{
|
||||
previousMajText = barDef.m_majTickText;
|
||||
previousMidText = "";
|
||||
previousMinText = "";
|
||||
|
||||
midTickTexts.clear();
|
||||
minTickTexts.clear();
|
||||
|
||||
currentMajGroupStartPos = currentBarPosition;
|
||||
currentMidGroupStartPos = currentBarPosition;
|
||||
currentMinGroupStartPos = currentBarPosition;
|
||||
}
|
||||
|
||||
auto midInsertResult = midTickTexts.insert( barDef.m_midTickText );
|
||||
bool isStartingNewMidGroup = midInsertResult.second;
|
||||
bool isFinishingMidGroup = isStartingNewMidGroup && !previousMidText.isEmpty();
|
||||
|
||||
if ( isFinishingMidGroup )
|
||||
{
|
||||
addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPoss );
|
||||
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss );
|
||||
|
||||
currentBarPosition += midGroupSpacing;
|
||||
}
|
||||
|
||||
if ( isStartingNewMidGroup )
|
||||
{
|
||||
previousMidText = barDef.m_midTickText;
|
||||
previousMinText = "";
|
||||
|
||||
minTickTexts.clear();
|
||||
|
||||
currentMidGroupStartPos = currentBarPosition;
|
||||
currentMinGroupStartPos = currentBarPosition;
|
||||
}
|
||||
|
||||
auto minInsertResult = minTickTexts.insert( barDef.m_minTickText );
|
||||
bool isStartingNewMinGroup = minInsertResult.second;
|
||||
bool isFinishingMinGroup = minInsertResult.second && !previousMinText.isEmpty();
|
||||
|
||||
if ( isFinishingMinGroup )
|
||||
{
|
||||
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss );
|
||||
|
||||
currentBarPosition += minGroupSpacing;
|
||||
}
|
||||
|
||||
if ( isStartingNewMinGroup )
|
||||
{
|
||||
previousMinText = barDef.m_minTickText;
|
||||
currentMinGroupStartPos = currentBarPosition;
|
||||
}
|
||||
|
||||
// Insert bar value in correct set of colored bars
|
||||
|
||||
auto legendToBarPointsPair = legendToBarPointsMap.find( barDef.m_legendText );
|
||||
|
||||
QVector<QPointF>* barPoints = nullptr;
|
||||
|
||||
if ( legendToBarPointsPair == legendToBarPointsMap.end() )
|
||||
{
|
||||
barPoints = &( legendToBarPointsMap[barDef.m_legendText] );
|
||||
}
|
||||
else
|
||||
{
|
||||
barPoints = &( legendToBarPointsPair->second );
|
||||
}
|
||||
|
||||
barPoints->push_back( {currentBarPosition, barDef.m_value} );
|
||||
|
||||
// Increment the bar position for the next bar
|
||||
currentBarPosition += 1.0;
|
||||
}
|
||||
|
||||
// Add group tick texts for the last groups
|
||||
|
||||
if ( !previousMajText.isEmpty() )
|
||||
{
|
||||
addGroupTickText( currentMajGroupStartPos, previousMajText, majTickPoss );
|
||||
}
|
||||
|
||||
if ( !previousMidText.isEmpty() )
|
||||
{
|
||||
addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPoss );
|
||||
}
|
||||
|
||||
if ( !previousMinText.isEmpty() )
|
||||
{
|
||||
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss );
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for ( const auto& legendToBarPointsPair : legendToBarPointsMap )
|
||||
{
|
||||
addQwtBarChart( plot,
|
||||
legendToBarPointsPair.second,
|
||||
legendToBarPointsPair.first,
|
||||
RiaColorTables::summaryCurveDefaultPaletteColors().cycledQColor( idx ) );
|
||||
idx++;
|
||||
}
|
||||
|
||||
QwtPlot::Axis axis = QwtPlot::xBottom;
|
||||
RiuBarChartScaleDraw* scaleDrawer = new RiuBarChartScaleDraw( positionedAxisTexts );
|
||||
|
||||
if ( m_orientation == Qt::Horizontal )
|
||||
{
|
||||
axis = QwtPlot::yLeft;
|
||||
}
|
||||
|
||||
plot->setAxisScaleDraw( axis, scaleDrawer );
|
||||
|
||||
QwtScaleDiv scaleDiv( 0, currentBarPosition );
|
||||
|
||||
if ( majTickPoss.size() ) scaleDiv.setTicks( QwtScaleDiv::MajorTick, majTickPoss );
|
||||
if ( midTickPoss.size() ) scaleDiv.setTicks( QwtScaleDiv::MediumTick, midTickPoss );
|
||||
if ( minTickPoss.size() ) scaleDiv.setTicks( QwtScaleDiv::MinorTick, minTickPoss );
|
||||
|
||||
if ( m_orientation == Qt::Horizontal )
|
||||
{
|
||||
scaleDiv.invert();
|
||||
}
|
||||
|
||||
plot->setAxisScaleDiv( axis, scaleDiv );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGroupedBarChartBuilder::addQwtBarChart( QwtPlot* plot,
|
||||
const QVector<QPointF>& posAndValue,
|
||||
const QString& legendText,
|
||||
const QColor& barColor )
|
||||
{
|
||||
QPalette palette;
|
||||
palette.setColor( QPalette::Window, barColor );
|
||||
palette.setColor( QPalette::Dark, barColor );
|
||||
|
||||
RiuAvoidPixelOverlapColumnSymbol* barStyle = new RiuAvoidPixelOverlapColumnSymbol( QwtColumnSymbol::Box );
|
||||
barStyle->setPalette( palette );
|
||||
barStyle->setFrameStyle( QwtColumnSymbol::NoFrame );
|
||||
barStyle->setLineWidth( 0 );
|
||||
|
||||
QwtPlotBarChart* barChart = new QwtPlotBarChart( legendText );
|
||||
barChart->setSamples( posAndValue );
|
||||
barChart->setLegendMode( QwtPlotBarChart::LegendChartTitle );
|
||||
barChart->setLayoutPolicy( QwtPlotAbstractBarChart::ScaleSamplesToAxes );
|
||||
barChart->setLayoutHint( 1.0 );
|
||||
barChart->setSymbol( barStyle );
|
||||
barChart->setOrientation( m_orientation );
|
||||
barChart->attach( plot );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuGroupedBarChartBuilder::BarEntry::BarEntry()
|
||||
: m_sortValue( std::numeric_limits<double>::infinity() )
|
||||
, m_value( std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuGroupedBarChartBuilder::BarEntry::BarEntry( QString majorTickText,
|
||||
QString midTickText,
|
||||
QString minTickText,
|
||||
double sortValue,
|
||||
QString legendText,
|
||||
double value )
|
||||
: m_majTickText( majorTickText )
|
||||
, m_midTickText( midTickText )
|
||||
, m_minTickText( minTickText )
|
||||
, m_sortValue( sortValue )
|
||||
, m_legendText( legendText )
|
||||
, m_value( value )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiuGroupedBarChartBuilder::BarEntry::operator<( const BarEntry& other ) const
|
||||
{
|
||||
if ( m_majTickText != other.m_majTickText ) return m_majTickText < other.m_majTickText;
|
||||
if ( m_midTickText != other.m_midTickText ) return m_midTickText < other.m_midTickText;
|
||||
if ( m_minTickText != other.m_minTickText ) return m_minTickText < other.m_minTickText;
|
||||
|
||||
if ( m_sortValue != other.m_sortValue )
|
||||
{
|
||||
return m_sortValue > other.m_sortValue;
|
||||
}
|
||||
|
||||
if ( m_legendText != other.m_legendText ) return m_legendText < other.m_legendText;
|
||||
|
||||
return false;
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 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 <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include <set>
|
||||
|
||||
class QwtPlot;
|
||||
class QColor;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiuGroupedBarChartBuilder
|
||||
{
|
||||
public:
|
||||
RiuGroupedBarChartBuilder( Qt::Orientation orientation );
|
||||
|
||||
void addBarEntry( const QString& majorTickText,
|
||||
const QString& midTickText,
|
||||
const QString& minTickText,
|
||||
const double sortValue,
|
||||
const QString& legendText,
|
||||
const double value );
|
||||
|
||||
void addBarChartToPlot( QwtPlot* plot );
|
||||
|
||||
private:
|
||||
double midPoint( double v1, double v2 )
|
||||
{
|
||||
return v1 + 0.5 * ( v2 - 1.0 - v1 );
|
||||
}
|
||||
|
||||
void addQwtBarChart( QwtPlot* plot,
|
||||
const QVector<QPointF>& posAndValue,
|
||||
const QString& legendText,
|
||||
const QColor& barColor );
|
||||
|
||||
struct BarEntry
|
||||
{
|
||||
BarEntry();
|
||||
|
||||
BarEntry( QString majorTickText,
|
||||
QString midTickText,
|
||||
QString minTickText,
|
||||
double sortValue,
|
||||
QString legendText,
|
||||
double value );
|
||||
|
||||
QString m_majTickText;
|
||||
QString m_midTickText;
|
||||
QString m_minTickText;
|
||||
double m_sortValue;
|
||||
QString m_legendText;
|
||||
|
||||
double m_value;
|
||||
|
||||
bool operator<( const BarEntry& other ) const;
|
||||
};
|
||||
|
||||
std::multiset<BarEntry> m_sortedBarEntries;
|
||||
Qt::Orientation m_orientation;
|
||||
};
|
Loading…
Reference in New Issue
Block a user