mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
3d Cross Plot: First implementation (#4127)
* First cross plot commit
* Made cross plot deal with "all time steps" and categorise curves based on time step
* Support STATIC vs DYNAMIC plotting
* #4115 Avoid updating plots in RimEclipseCase::computeCachedData()
* Make sure loading of Cross plot from file works
* Show Legend in Cross Plot
* Uncheck / Check curves to disable/enable
* Axis titles and checkable data set
* Name config and setting of common plot look
* Fix category indentation in GeoMech results
* Support name configuration for Grid Cross Plot
* Support adding new curve sets
* Improve colors and symbols with better cycling
* Moved GridCrossPlot files to sub directory in ProjectDataModel and Commands
* #4111 3D calculations : Always show difference options
* Whitespace
* #4111 Move resultDefinition field to private
* Whitespace
* #4087 Ensemble : When importing and ensemble, show by default an ensemble plot
* #4085 3D view: Improve overlay item colors
* #4106 Crash on Linux
Temporary workaround to avoid crash
* #4106 Stop trying to do recursive setting tab order widget
* The double pointer was handled wrongly and shift-tab order isn't working anyway.
* #4114 Regression Test : Remove cached pointer to eclipse case
* Revert "#4114 Regression Test : Remove cached pointer to eclipse case"
This reverts commit f2146c6007
.
* #4114 Regression Test : Missing data for flow diag property filter
* #4085 3D view: Add check box for version info text
* Whtespace
* Improve labelling of static results
* Fix update of result property when changing type
This commit is contained in:
@@ -50,6 +50,8 @@
|
||||
#include "RimGeoMechCellColors.h"
|
||||
#include "RimGeoMechModels.h"
|
||||
#include "RimGeoMechView.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimObservedData.h"
|
||||
@@ -653,6 +655,7 @@ void RiaApplication::loadAndUpdatePlotData()
|
||||
RimFlowPlotCollection* flowColl = nullptr;
|
||||
RimRftPlotCollection* rftColl = nullptr;
|
||||
RimPltPlotCollection* pltColl = nullptr;
|
||||
RimGridCrossPlotCollection* gcpColl = nullptr;
|
||||
|
||||
if (m_project->mainPlotCollection() && m_project->mainPlotCollection()->wellLogPlotCollection())
|
||||
{
|
||||
@@ -678,6 +681,10 @@ void RiaApplication::loadAndUpdatePlotData()
|
||||
{
|
||||
pltColl = m_project->mainPlotCollection()->pltPlotCollection();
|
||||
}
|
||||
if (m_project->mainPlotCollection() && m_project->mainPlotCollection()->gridCrossPlotCollection())
|
||||
{
|
||||
gcpColl = m_project->mainPlotCollection()->gridCrossPlotCollection();
|
||||
}
|
||||
|
||||
size_t plotCount = 0;
|
||||
plotCount += wlpColl ? wlpColl->wellLogPlots().size() : 0;
|
||||
@@ -686,6 +693,7 @@ void RiaApplication::loadAndUpdatePlotData()
|
||||
plotCount += flowColl ? flowColl->plotCount() : 0;
|
||||
plotCount += rftColl ? rftColl->rftPlots().size() : 0;
|
||||
plotCount += pltColl ? pltColl->pltPlots().size() : 0;
|
||||
plotCount += gcpColl ? gcpColl->gridCrossPlots().size() : 0;
|
||||
|
||||
if (plotCount > 0)
|
||||
{
|
||||
@@ -741,6 +749,15 @@ void RiaApplication::loadAndUpdatePlotData()
|
||||
plotProgress.incrementProgress();
|
||||
}
|
||||
}
|
||||
|
||||
if (gcpColl)
|
||||
{
|
||||
for (const auto& gcpPlot : gcpColl->gridCrossPlots())
|
||||
{
|
||||
gcpPlot->loadDataAndUpdate();
|
||||
plotProgress.incrementProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -163,6 +163,16 @@ const caf::ColorTable& RiaColorTables::categoryPaletteColors()
|
||||
return colorTable;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const caf::ColorTable& RiaColorTables::contrastCategoryPaletteColors()
|
||||
{
|
||||
static caf::ColorTable colorTable = caf::ColorTable(contrastCategoryColors());
|
||||
|
||||
return colorTable;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -563,6 +573,42 @@ std::vector<cvf::Color3ub> RiaColorTables::categoryColors()
|
||||
return colors;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<cvf::Color3ub> RiaColorTables::contrastCategoryColors()
|
||||
{
|
||||
// Based on http://stackoverflow.com/questions/470690/how-to-automatically-generate-n-distinct-colors
|
||||
// and Kelly Colors and sorted by hue
|
||||
// See also http://www.w3schools.com/colors/ for palettes etc.
|
||||
|
||||
static std::vector<cvf::Color3ub> colors{
|
||||
cvf::Color3ub(244, 200, 0), // hwb( 49, 0%, 4%) vivid_greenish_yellow
|
||||
cvf::Color3ub(128, 62, 117), // hwb(310, 24%, 50%) strong_purple
|
||||
cvf::Color3ub(255, 104, 0), // hwb( 24, 0%, 0%) vivid_orange
|
||||
cvf::Color3ub(166, 189, 215), // hwb(212, 65%, 16%) very_light_blue
|
||||
cvf::Color3ub(193, 0, 32), // hwb(350, 0%, 24%) vivid_red
|
||||
cvf::Color3ub(206, 162, 98), // hwb( 36, 38%, 19%) grayish_yellow
|
||||
cvf::Color3ub(129, 112, 102), // hwb( 22, 40%, 49%) medium_gray
|
||||
cvf::Color3ub(0, 125, 52), // hwb(145, 0%, 51%) vivid_green
|
||||
cvf::Color3ub(246, 118, 142), // hwb(349, 46%, 4%) strong_purplish_pink
|
||||
cvf::Color3ub(0, 83, 138), // hwb(204, 0%, 46%) strong_blue
|
||||
cvf::Color3ub(255, 122, 92), // hwb( 11, 36%, 0%) strong_yellowish_pink
|
||||
cvf::Color3ub(212, 28, 132), // hwb(326, 11%, 17%) strong_purplish_red
|
||||
cvf::Color3ub(255, 142, 0), // hwb( 33, 0%, 0%) vivid_orange_yellow
|
||||
cvf::Color3ub(59, 84, 23), // hwb( 85, 9%, 67%) dark_olive_green
|
||||
cvf::Color3ub(127, 24, 13), // hwb( 6, 5%, 50%) strong_reddish_brown
|
||||
cvf::Color3ub(54, 125, 123), // hwb(178, 21%, 51%) vivid_blueish_green
|
||||
cvf::Color3ub(241, 58, 19), // hwb( 11, 7%, 5%) vivid_reddish_orange
|
||||
cvf::Color3ub(147, 170, 0), // hwb( 68, 0%, 33%) vivid_yellowish_green
|
||||
cvf::Color3ub(46, 76, 224), // hwb(230, 18%, 12%) medium_blue
|
||||
cvf::Color3ub(89, 51, 21), // hwb( 26, 8%, 65%) deep_yellowish_brown
|
||||
cvf::Color3ub(0, 0, 0) // hwb(0, 0%, 100%) black
|
||||
};
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -40,6 +40,7 @@ public:
|
||||
static const caf::ColorTable& blueWhiteRedPaletteColors();
|
||||
static const caf::ColorTable& redWhiteBluePaletteColors();
|
||||
static const caf::ColorTable& categoryPaletteColors();
|
||||
static const caf::ColorTable& contrastCategoryPaletteColors();
|
||||
static const caf::ColorTable& tensorWhiteGrayBlackPaletteColors();
|
||||
static const caf::ColorTable& tensorOrangeBlueWhitePaletteColors();
|
||||
static const caf::ColorTable& tensorsMagentaBrownGrayPaletteColors();
|
||||
@@ -65,5 +66,6 @@ public:
|
||||
|
||||
private:
|
||||
static std::vector<cvf::Color3ub> categoryColors();
|
||||
static std::vector<cvf::Color3ub> contrastCategoryColors();
|
||||
static std::vector<cvf::Color3ub> invertedCategoryColors();
|
||||
};
|
||||
|
@@ -57,6 +57,7 @@ include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Annotations
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Completions
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Flow
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/GridCrossPlots
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Measurement
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Summary
|
||||
|
||||
@@ -107,6 +108,7 @@ list( APPEND REFERENCED_CMAKE_FILES
|
||||
FileInterface/CMakeLists_files.cmake
|
||||
|
||||
ProjectDataModel/CMakeLists_files.cmake
|
||||
ProjectDataModel/GridCrossPlots/CMakeLists_files.cmake
|
||||
ProjectDataModel/Summary/CMakeLists_files.cmake
|
||||
ProjectDataModel/Flow/CMakeLists_files.cmake
|
||||
ProjectDataModel/Annotations/CMakeLists_files.cmake
|
||||
@@ -132,6 +134,7 @@ list( APPEND REFERENCED_CMAKE_FILES
|
||||
Commands/EclipseCommands/EclipseWell/CMakeLists_files.cmake
|
||||
Commands/ExportCommands/CMakeLists_files.cmake
|
||||
Commands/FlowCommands/CMakeLists_files.cmake
|
||||
Commands/GridCrossPlotCommands/CMakeLists_files.cmake
|
||||
Commands/HoloLensCommands/CMakeLists_files.cmake
|
||||
Commands/IntersectionBoxCommands/CMakeLists_files.cmake
|
||||
Commands/IntersectionViewCommands/CMakeLists_files.cmake
|
||||
|
@@ -0,0 +1,19 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicCreateGridCrossPlotFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicCreateGridCrossPlotCurveSetFeature.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicCreateGridCrossPlotFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicCreateGridCrossPlotCurveSetFeature.cpp)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
source_group( "CommandFeature\\GridCrossPlot" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
@@ -0,0 +1,64 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RicCreateGridCrossPlotCurveSetFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCurveSet.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicCreateGridCrossPlotCurveSetFeature, "RicCreateGridCrossPlotCurveSetFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicCreateGridCrossPlotCurveSetFeature::isCommandEnabled()
|
||||
{
|
||||
return caf::SelectionManager::instance()->selectedItemOfType<RimGridCrossPlot>() != nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicCreateGridCrossPlotCurveSetFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RimGridCrossPlot* crossPlot = caf::SelectionManager::instance()->selectedItemOfType<RimGridCrossPlot>();
|
||||
|
||||
RimGridCrossPlotCurveSet* curveSet = crossPlot->createCurveSet();
|
||||
curveSet->loadDataAndUpdate(true);
|
||||
|
||||
RiaApplication::instance()->project()->updateConnectedEditors();
|
||||
RiaApplication::instance()->getOrCreateMainPlotWindow();
|
||||
RiuPlotMainWindowTools::selectAsCurrentItem(curveSet);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicCreateGridCrossPlotCurveSetFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("New Cross Plot Curve Set");
|
||||
actionToSetup->setIcon(QIcon(":/WellLogCurve16x16.png"));
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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"
|
||||
|
||||
#include <vector>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicCreateGridCrossPlotCurveSetFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -0,0 +1,67 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RicCreateGridCrossPlotFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicCreateGridCrossPlotFeature, "RicCreateGridCrossPlotFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicCreateGridCrossPlotFeature::isCommandEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicCreateGridCrossPlotFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RimProject* project = RiaApplication::instance()->project();
|
||||
RimGridCrossPlotCollection* collection = project->mainPlotCollection()->gridCrossPlotCollection();
|
||||
RimGridCrossPlot* plot = collection->createGridCrossPlot();
|
||||
|
||||
plot->loadDataAndUpdate();
|
||||
plot->updateConnectedEditors();
|
||||
|
||||
RiaApplication::instance()->project()->updateConnectedEditors();
|
||||
RiaApplication::instance()->getOrCreateMainPlotWindow();
|
||||
RiuPlotMainWindowTools::selectAsCurrentItem(plot);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicCreateGridCrossPlotFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("New Grid Cross Plot");
|
||||
actionToSetup->setIcon(QIcon(":/SummaryXPlotsLight16x16.png"));
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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"
|
||||
|
||||
#include <vector>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicCreateGridCrossPlotFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
||||
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#include "RimGeoMechPropertyFilter.h"
|
||||
#include "RimGeoMechView.h"
|
||||
#include "RimGridTimeHistoryCurve.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCurveSet.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimIntersection.h"
|
||||
#include "RimIntersectionBox.h"
|
||||
@@ -131,6 +133,8 @@ bool isDeletable(caf::PdmUiItem* uiItem)
|
||||
if (dynamic_cast<RimTextAnnotation*>(uiItem)) return true;
|
||||
if (dynamic_cast<RimReachCircleAnnotation*>(uiItem)) return true;
|
||||
if (dynamic_cast<RimPolylinesAnnotation*>(uiItem)) return true;
|
||||
if (dynamic_cast<RimGridCrossPlot*>(uiItem)) return true;
|
||||
if (dynamic_cast<RimGridCrossPlotCurveSet*>(uiItem)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,23 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlotCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlotCurve.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlotCurveSet.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlotCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlotCurve.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGridCrossPlotCurveSet.cpp)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
source_group( "ProjectDataModel\\GridCrossPlots" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
@@ -0,0 +1,371 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RimGridCrossPlot.h"
|
||||
|
||||
#include "RiuQwtPlotTools.h"
|
||||
|
||||
#include "RimGridCrossPlotCurveSet.h"
|
||||
|
||||
#include "cafPdmUiCheckBoxEditor.h"
|
||||
#include "cvfAssert.h"
|
||||
|
||||
#include "qwt_legend.h"
|
||||
#include "qwt_plot.h"
|
||||
#include "qwt_plot_curve.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlot, "RimGridCrossPlot");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlot::RimGridCrossPlot()
|
||||
{
|
||||
CAF_PDM_InitObject("Grid Cross Plot", ":/SummaryXPlotLight16x16.png", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Show Legend", "", "", "");
|
||||
CAF_PDM_InitField(&m_legendFontSize, "LegendFontSize", 10, "Legend Font Size", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "Name Config", "", "", "");
|
||||
m_nameConfig.uiCapability()->setUiTreeHidden(true);
|
||||
m_nameConfig.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_crossPlotCurveSets, "CrossPlotCurve", "Cross Plot Data Set", "", "", "");
|
||||
m_crossPlotCurveSets.uiCapability()->setUiHidden(true);
|
||||
|
||||
m_nameConfig = new RimGridCrossPlotNameConfig(this);
|
||||
|
||||
createCurveSet();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCurveSet* RimGridCrossPlot::createCurveSet()
|
||||
{
|
||||
RimGridCrossPlotCurveSet* curveSet = new RimGridCrossPlotCurveSet();
|
||||
m_crossPlotCurveSets.push_back(curveSet);
|
||||
return curveSet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimGridCrossPlot::indexOfCurveSet(const RimGridCrossPlotCurveSet* curveSet) const
|
||||
{
|
||||
for (size_t i = 0; i < m_crossPlotCurveSets.size(); ++i)
|
||||
{
|
||||
if (curveSet == m_crossPlotCurveSets[i])
|
||||
{
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* RimGridCrossPlot::viewWidget()
|
||||
{
|
||||
return m_qwtPlot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QImage RimGridCrossPlot::snapshotWindowContent()
|
||||
{
|
||||
QImage image;
|
||||
|
||||
if (m_qwtPlot)
|
||||
{
|
||||
QPixmap pix = QPixmap::grabWidget(m_qwtPlot);
|
||||
image = pix.toImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::zoomAll()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::calculateZoomRangeAndUpdateQwt()
|
||||
{
|
||||
// this->calculateXZoomRange();
|
||||
m_qwtPlot->replot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::reattachCurvesToQwtAndReplot()
|
||||
{
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
curveSet->setParentQwtPlotNoReplot(m_qwtPlot);
|
||||
}
|
||||
m_qwtPlot->replot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlot::createAutoName() const
|
||||
{
|
||||
QStringList autoName;
|
||||
if (!m_nameConfig->customName().isEmpty())
|
||||
{
|
||||
autoName += m_nameConfig->customName();
|
||||
}
|
||||
|
||||
if (m_nameConfig->addDataSetNames())
|
||||
{
|
||||
QStringList dataSets;
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
dataSets += curveSet->createAutoName();
|
||||
}
|
||||
if (!dataSets.isEmpty())
|
||||
{
|
||||
autoName += QString("(%1)").arg(dataSets.join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
return autoName.join(" ");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimGridCrossPlot::userDescriptionField()
|
||||
{
|
||||
return m_nameConfig->nameField();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* RimGridCrossPlot::createViewWidget(QWidget* mainWindowParent)
|
||||
{
|
||||
if (!m_qwtPlot)
|
||||
{
|
||||
m_qwtPlot = new QwtPlot(QString("Grid Cross Plot"), mainWindowParent);
|
||||
}
|
||||
|
||||
return m_qwtPlot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::deleteViewWidget()
|
||||
{
|
||||
if (m_qwtPlot)
|
||||
{
|
||||
m_qwtPlot->deleteLater();
|
||||
m_qwtPlot = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
updateMdiWindowVisibility();
|
||||
CVF_ASSERT(m_qwtPlot);
|
||||
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
curveSet->loadDataAndUpdate(false);
|
||||
curveSet->setParentQwtPlotNoReplot(m_qwtPlot);
|
||||
}
|
||||
|
||||
performAutoNameUpdate();
|
||||
|
||||
m_qwtPlot->setAxisAutoScale(QwtPlot::xBottom);
|
||||
m_qwtPlot->setAxisAutoScale(QwtPlot::yLeft);
|
||||
m_qwtPlot->setAxisTitle(QwtPlot::xBottom, QwtText(xAxisParameterString()));
|
||||
m_qwtPlot->setAxisTitle(QwtPlot::yLeft, QwtText(yAxisParameterString()));
|
||||
|
||||
RiuQwtPlotTools::setCommonPlotBehaviour(m_qwtPlot);
|
||||
RiuQwtPlotTools::setDefaultAxes(m_qwtPlot);
|
||||
if (m_showLegend())
|
||||
{
|
||||
// Will be released in plot destructor or when a new legend is set
|
||||
QwtLegend* legend = new QwtLegend(m_qwtPlot);
|
||||
|
||||
auto font = legend->font();
|
||||
font.setPixelSize(m_legendFontSize());
|
||||
legend->setFont(font);
|
||||
m_qwtPlot->insertLegend(legend, QwtPlot::BottomLegend);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_qwtPlot->insertLegend(nullptr);
|
||||
}
|
||||
|
||||
m_qwtPlot->replot();
|
||||
m_qwtPlot->show();
|
||||
this->updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&m_showLegend);
|
||||
|
||||
if (m_showLegend())
|
||||
{
|
||||
uiOrdering.add(&m_legendFontSize);
|
||||
}
|
||||
|
||||
caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Name Configuration");
|
||||
m_nameConfig->uiOrdering(uiConfigName, *nameGroup);
|
||||
|
||||
uiOrdering.skipRemainingFields(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue)
|
||||
{
|
||||
onLoadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimGridCrossPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if (fieldNeedingOptions == &m_legendFontSize)
|
||||
{
|
||||
std::vector<int> fontSizes;
|
||||
fontSizes.push_back(8);
|
||||
fontSizes.push_back(10);
|
||||
fontSizes.push_back(12);
|
||||
fontSizes.push_back(14);
|
||||
fontSizes.push_back(16);
|
||||
|
||||
|
||||
for (int value : fontSizes)
|
||||
{
|
||||
QString text = QString("%1").arg(value);
|
||||
options.push_back(caf::PdmOptionItemInfo(text, value));
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::performAutoNameUpdate()
|
||||
{
|
||||
if (m_qwtPlot)
|
||||
{
|
||||
m_qwtPlot->setTitle(this->createAutoName());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlot::xAxisParameterString() const
|
||||
{
|
||||
QStringList xAxisParams;
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
xAxisParams.push_back(curveSet->xAxisName());
|
||||
}
|
||||
|
||||
xAxisParams.removeDuplicates();
|
||||
|
||||
if (xAxisParams.size() > 5)
|
||||
{
|
||||
return QString("%1 parameters").arg(xAxisParams.size());
|
||||
}
|
||||
|
||||
return xAxisParams.join(", ");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlot::yAxisParameterString() const
|
||||
{
|
||||
QStringList yAxisParams;
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
yAxisParams.push_back(curveSet->yAxisName());
|
||||
}
|
||||
|
||||
yAxisParams.removeDuplicates();
|
||||
|
||||
if (yAxisParams.size() > 5)
|
||||
{
|
||||
return QString("%1 parameters").arg(yAxisParams.size());
|
||||
}
|
||||
|
||||
return yAxisParams.join(", ");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Name Configuration
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlotNameConfig, "RimGridCrossPlotNameConfig");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotNameConfig::RimGridCrossPlotNameConfig(RimNameConfigHolderInterface* holder /*= nullptr*/)
|
||||
: RimNameConfig(holder)
|
||||
{
|
||||
CAF_PDM_InitObject("Cross Plot Name Generator", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&addDataSetNames, "AddDataSetNames", true, "Add Data Set Names", "", "", "");
|
||||
|
||||
setCustomName("Cross Plot");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotNameConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
RimNameConfig::defineUiOrdering(uiConfigName, uiOrdering);
|
||||
uiOrdering.add(&addDataSetNames);
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "cafPdmChildField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "RimNameConfig.h"
|
||||
#include "RimViewWindow.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
class RimGridCrossPlotCurveSet;
|
||||
class QwtPlot;
|
||||
|
||||
class RimGridCrossPlotNameConfig : public RimNameConfig
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimGridCrossPlotNameConfig(RimNameConfigHolderInterface* holder = nullptr);
|
||||
public:
|
||||
caf::PdmField<bool> addDataSetNames;
|
||||
|
||||
protected:
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
|
||||
};
|
||||
|
||||
class RimGridCrossPlot : public RimViewWindow, public RimNameConfigHolderInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimGridCrossPlot();
|
||||
~RimGridCrossPlot() = default;
|
||||
|
||||
RimGridCrossPlotCurveSet* createCurveSet();
|
||||
int indexOfCurveSet(const RimGridCrossPlotCurveSet* curveSet) const;
|
||||
|
||||
QWidget* viewWidget() override;
|
||||
QImage snapshotWindowContent() override;
|
||||
void zoomAll() override;
|
||||
void calculateZoomRangeAndUpdateQwt();
|
||||
void reattachCurvesToQwtAndReplot();
|
||||
QString createAutoName() const override;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
protected:
|
||||
QWidget* createViewWidget(QWidget* mainWindowParent) override;
|
||||
void deleteViewWidget() override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly) override;
|
||||
|
||||
void performAutoNameUpdate() override;
|
||||
|
||||
QString xAxisParameterString() const;
|
||||
QString yAxisParameterString() const;
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showLegend;
|
||||
caf::PdmField<int> m_legendFontSize;
|
||||
caf::PdmChildField<RimGridCrossPlotNameConfig*> m_nameConfig;
|
||||
|
||||
caf::PdmChildArrayField<RimGridCrossPlotCurveSet*> m_crossPlotCurveSets;
|
||||
|
||||
QPointer<QwtPlot> m_qwtPlot;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -0,0 +1,75 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RimGridCrossPlotCollection.h"
|
||||
|
||||
#include "RimGridCrossPlot.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlotCollection, "RimGridCrossPlotCollection");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCollection::RimGridCrossPlotCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("Grid Cross Plots", ":/SummaryXPlotsLight16x16.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_gridCrossPlots, "GridCrossPlots", "Grid Cross Plots", "", "", "");
|
||||
m_gridCrossPlots.uiCapability()->setUiHidden(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCollection::~RimGridCrossPlotCollection() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCollection::deleteAllChildObjects()
|
||||
{
|
||||
m_gridCrossPlots.deleteAllChildObjectsAsync();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimGridCrossPlot*> RimGridCrossPlotCollection::gridCrossPlots() const
|
||||
{
|
||||
return m_gridCrossPlots.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlot* RimGridCrossPlotCollection::createGridCrossPlot()
|
||||
{
|
||||
RimGridCrossPlot* plot = new RimGridCrossPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
|
||||
//plot->setDescription(QString("Summary Cross Plot %1").arg(m_gridCrossPlots.size()));
|
||||
addGridCrossPlot(plot);
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCollection::addGridCrossPlot(RimGridCrossPlot* plot)
|
||||
{
|
||||
m_gridCrossPlots().push_back(plot);
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 RimGridCrossPlot;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimGridCrossPlotCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGridCrossPlotCollection();
|
||||
~RimGridCrossPlotCollection() override;
|
||||
|
||||
void deleteAllChildObjects();
|
||||
|
||||
std::vector<RimGridCrossPlot*> gridCrossPlots() const;
|
||||
RimGridCrossPlot* createGridCrossPlot();
|
||||
void addGridCrossPlot(RimGridCrossPlot* plot);
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimGridCrossPlot*> m_gridCrossPlots;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
|
@@ -0,0 +1,135 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RimGridCrossPlotCurve.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
|
||||
#include "RigCaseCellResultCalculator.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPointF>
|
||||
#include <QVector>
|
||||
|
||||
#include "qwt_plot.h"
|
||||
#include "qwt_plot_curve.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlotCurve, "GridCrossPlotCurve");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::determineColorAndSymbol(int curveSetIndex, int categoryIndex, bool contrastColors)
|
||||
{
|
||||
const caf::ColorTable& colors = RiaColorTables::contrastCategoryPaletteColors();
|
||||
int colorIndex = categoryIndex + curveSetIndex; // Offset cycle for each curve set
|
||||
setColor(colors.cycledColor3f(colorIndex));
|
||||
int numColors = (int) colors.size();
|
||||
|
||||
// Retain same symbol until we've gone full cycle in colors
|
||||
int symbolIndex = categoryIndex / numColors;
|
||||
|
||||
RiuQwtSymbol::PointSymbolEnum symbol = RiuQwtSymbol::cycledSymbolStyle(curveSetIndex, symbolIndex);
|
||||
setSymbol(symbol);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCurve::RimGridCrossPlotCurve()
|
||||
{
|
||||
CAF_PDM_InitObject("Cross Plot Points", ":/WellLogCurve16x16.png", "", "");
|
||||
|
||||
setLineStyle(RiuQwtPlotCurve::STYLE_NONE);
|
||||
setSymbolSize(6);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::setSamples(const QVector<QPointF>& samples)
|
||||
{
|
||||
m_qwtPlotCurve->setSamples(samples);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::updateZoomInParentPlot()
|
||||
{
|
||||
RimGridCrossPlot* plot;
|
||||
this->firstAncestorOrThisOfTypeAsserted(plot);
|
||||
plot->calculateZoomRangeAndUpdateQwt();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::updateLegendsInPlot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlotCurve::createCurveAutoName()
|
||||
{
|
||||
return m_customCurveName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
{
|
||||
if (updateParentPlot)
|
||||
{
|
||||
RimGridCrossPlot* crossPlot;
|
||||
firstAncestorOrThisOfTypeAsserted(crossPlot);
|
||||
crossPlot->reattachCurvesToQwtAndReplot();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance");
|
||||
RimPlotCurve::appearanceUiOrdering(*appearanceGroup);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimGridCrossPlotCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
return options;
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RimPlotCurve.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <QPointF>
|
||||
#include <QVector>
|
||||
|
||||
class RimCase;
|
||||
class RimEclipseResultDefinition;
|
||||
class QwtPlotCurve;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimGridCrossPlotCurve : public RimPlotCurve
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGridCrossPlotCurve();
|
||||
~RimGridCrossPlotCurve() override = default;
|
||||
void determineColorAndSymbol(int curveSetIndex, int categoryIndex, bool contrastColors = false);
|
||||
void setSamples(const QVector<QPointF>& samples);
|
||||
|
||||
protected:
|
||||
void updateZoomInParentPlot() override;
|
||||
void updateLegendsInPlot() override;
|
||||
QString createCurveAutoName() override;
|
||||
void onLoadDataAndUpdate(bool updateParentPlot) override;
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
||||
};
|
||||
|
@@ -0,0 +1,401 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RimGridCrossPlotCurveSet.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigActiveCellsResultAccessor.h"
|
||||
#include "RigCaseCellResultCalculator.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCurve.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlotCurveSet, "GridCrossPlotCurveSet");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCurveSet::RimGridCrossPlotCurveSet()
|
||||
{
|
||||
CAF_PDM_InitObject("Cross Plot Data Set", ":/WellLogCurve16x16.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_case, "Case", "Case", "", "", "");
|
||||
m_case.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
CAF_PDM_InitField(&m_timeStep, "TimeStep", -1, "Time Step", "", "", "");
|
||||
m_timeStep.uiCapability()->setUiEditorTypeName(caf::PdmUiComboBoxEditor::uiEditorTypeName());
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_xAxisProperty, "XAxisProperty", "X-Axis Property", "", "", "");
|
||||
m_xAxisProperty = new RimEclipseResultDefinition;
|
||||
m_xAxisProperty.uiCapability()->setUiHidden(true);
|
||||
m_xAxisProperty.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_yAxisProperty, "YAxisProperty", "Y-Axis Property", "", "", "");
|
||||
m_yAxisProperty = new RimEclipseResultDefinition;
|
||||
m_yAxisProperty.uiCapability()->setUiHidden(true);
|
||||
m_yAxisProperty.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "Name", "", "", "");
|
||||
m_nameConfig = new RimGridCrossPlotCurveSetNameConfig(this);
|
||||
m_nameConfig.uiCapability()->setUiTreeHidden(true);
|
||||
m_nameConfig.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_crossPlotCurves, "CrossPlotCurves", "Curves", "", "", "");
|
||||
m_crossPlotCurves.uiCapability()->setUiTreeHidden(true);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::loadDataAndUpdate(bool updateParentPlot)
|
||||
{
|
||||
onLoadDataAndUpdate(updateParentPlot);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::setParentQwtPlotNoReplot(QwtPlot* parent)
|
||||
{
|
||||
for (auto& curve : m_crossPlotCurves())
|
||||
{
|
||||
curve->setParentQwtPlotNoReplot(m_isChecked() ? parent : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlotCurveSet::xAxisName() const
|
||||
{
|
||||
return m_xAxisProperty->resultVariableUiShortName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlotCurveSet::yAxisName() const
|
||||
{
|
||||
return m_yAxisProperty->resultVariableUiShortName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimGridCrossPlotCurveSet::indexInPlot() const
|
||||
{
|
||||
RimGridCrossPlot* parent;
|
||||
this->firstAncestorOrThisOfTypeAsserted(parent);
|
||||
return parent->indexOfCurveSet(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlotCurveSet::createAutoName() const
|
||||
{
|
||||
if (m_case() == nullptr)
|
||||
{
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
QStringList nameTags;
|
||||
if (!m_nameConfig->customName().isEmpty())
|
||||
{
|
||||
nameTags += m_nameConfig->customName();
|
||||
}
|
||||
|
||||
if (m_nameConfig->addCaseName())
|
||||
{
|
||||
nameTags += m_case->caseUserDescription();
|
||||
}
|
||||
|
||||
if (m_nameConfig->addAxisVariables())
|
||||
{
|
||||
nameTags += QString("%1 x %2").arg(xAxisName(), yAxisName());
|
||||
}
|
||||
|
||||
if (m_nameConfig->addTimestep())
|
||||
{
|
||||
if (m_timeStep() == -1)
|
||||
{
|
||||
nameTags += "All Time Steps";
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList timeStepNames = m_case->timeStepStrings();
|
||||
nameTags += timeStepNames[m_timeStep()];
|
||||
}
|
||||
}
|
||||
|
||||
return nameTags.join(", ");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::initAfterRead()
|
||||
{
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case());
|
||||
if (eclipseCase)
|
||||
{
|
||||
m_xAxisProperty->setEclipseCase(eclipseCase);
|
||||
m_yAxisProperty->setEclipseCase(eclipseCase);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
{
|
||||
performAutoNameUpdate();
|
||||
|
||||
m_crossPlotCurves.deleteAllChildObjects();
|
||||
|
||||
std::map<int, QVector<QPointF>> samples;
|
||||
|
||||
if (m_case())
|
||||
{
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case.value());
|
||||
if (eclipseCase)
|
||||
{
|
||||
RigCaseCellResultsData* resultData = eclipseCase->results(RiaDefines::MATRIX_MODEL);
|
||||
|
||||
RigEclipseResultAddress xAddress(m_xAxisProperty->resultType(), m_xAxisProperty->resultVariable());
|
||||
RigEclipseResultAddress yAddress(m_yAxisProperty->resultType(), m_yAxisProperty->resultVariable());
|
||||
|
||||
if (xAddress.isValid() && yAddress.isValid())
|
||||
{
|
||||
RigActiveCellInfo* activeCellInfo = resultData->activeCellInfo();
|
||||
const RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
|
||||
resultData->ensureKnownResultLoaded(xAddress);
|
||||
resultData->ensureKnownResultLoaded(yAddress);
|
||||
|
||||
const std::vector<std::vector<double>>& xValuesForAllSteps = resultData->cellScalarResults(xAddress);
|
||||
const std::vector<std::vector<double>>& yValuesForAllSteps = resultData->cellScalarResults(yAddress);
|
||||
|
||||
std::set<int> timeStepsToInclude;
|
||||
if (m_timeStep() == -1)
|
||||
{
|
||||
size_t nStepsInData = std::max(xValuesForAllSteps.size(), yValuesForAllSteps.size());
|
||||
CVF_ASSERT(xValuesForAllSteps.size() == 1u || xValuesForAllSteps.size() == nStepsInData);
|
||||
CVF_ASSERT(yValuesForAllSteps.size() == 1u || yValuesForAllSteps.size() == nStepsInData);
|
||||
for (size_t i = 0; i < nStepsInData; ++i)
|
||||
{
|
||||
timeStepsToInclude.insert((int) i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timeStepsToInclude.insert(static_cast<size_t>(m_timeStep()));
|
||||
}
|
||||
|
||||
for (int timeStep : timeStepsToInclude)
|
||||
{
|
||||
int xIndex = timeStep >= (int) xValuesForAllSteps.size() ? 0 : timeStep;
|
||||
int yIndex = timeStep >= (int) yValuesForAllSteps.size() ? 0 : timeStep;
|
||||
|
||||
RigActiveCellsResultAccessor xAccessor(mainGrid, &xValuesForAllSteps[xIndex], activeCellInfo);
|
||||
RigActiveCellsResultAccessor yAccessor(mainGrid, &yValuesForAllSteps[yIndex], activeCellInfo);
|
||||
for (size_t j = 0; j < activeCellInfo->reservoirCellCount(); ++j)
|
||||
{
|
||||
double xValue = xAccessor.cellScalarGlobIdx(j);
|
||||
double yValue = yAccessor.cellScalarGlobIdx(j);
|
||||
if (xValue != HUGE_VAL && yValue != HUGE_VAL)
|
||||
{
|
||||
samples[timeStep].push_back(QPointF(xValue, yValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList timeStepNames;
|
||||
|
||||
if (m_case)
|
||||
{
|
||||
timeStepNames = m_case->timeStepStrings();
|
||||
}
|
||||
|
||||
int curveSetIndex = indexInPlot();
|
||||
|
||||
for (const auto& sampleCategory : samples)
|
||||
{
|
||||
RimGridCrossPlotCurve* curve = new RimGridCrossPlotCurve();
|
||||
QString timeStepName = QString::number(sampleCategory.first);
|
||||
if (sampleCategory.first < timeStepNames.size())
|
||||
{
|
||||
timeStepName = timeStepNames[sampleCategory.first];
|
||||
}
|
||||
bool staticResultsOnly = staticResultsOnly = m_xAxisProperty->hasStaticResult() && m_yAxisProperty->hasStaticResult();
|
||||
if (staticResultsOnly)
|
||||
{
|
||||
curve->setCustomName(createAutoName());
|
||||
}
|
||||
else
|
||||
{
|
||||
curve->setCustomName(QString("%1 : %2").arg(createAutoName()).arg(timeStepName));
|
||||
}
|
||||
curve->determineColorAndSymbol(curveSetIndex, sampleCategory.first);
|
||||
curve->setSamples(sampleCategory.second);
|
||||
curve->updateCurveAppearance();
|
||||
curve->updateCurveNameAndUpdatePlotLegendAndTitle();
|
||||
m_crossPlotCurves.push_back(curve);
|
||||
}
|
||||
|
||||
if (updateParentPlot)
|
||||
{
|
||||
triggerReplotAndTreeRebuild();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&m_case);
|
||||
if (m_case)
|
||||
{
|
||||
uiOrdering.add(&m_timeStep);
|
||||
|
||||
caf::PdmUiGroup* xAxisGroup = uiOrdering.addNewGroup("X-Axis Property");
|
||||
m_xAxisProperty->uiOrdering(uiConfigName, *xAxisGroup);
|
||||
|
||||
caf::PdmUiGroup* yAxisGroup = uiOrdering.addNewGroup("Y-Axis Property");
|
||||
m_yAxisProperty->uiOrdering(uiConfigName, *yAxisGroup);
|
||||
}
|
||||
caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Name Configuration");
|
||||
m_nameConfig->uiOrdering(uiConfigName, *nameGroup);
|
||||
|
||||
uiOrdering.skipRemainingFields(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &m_case)
|
||||
{
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case.value());
|
||||
if (eclipseCase)
|
||||
{
|
||||
m_xAxisProperty->setEclipseCase(eclipseCase);
|
||||
m_yAxisProperty->setEclipseCase(eclipseCase);
|
||||
m_xAxisProperty->updateConnectedEditors();
|
||||
m_yAxisProperty->updateConnectedEditors();
|
||||
triggerReplotAndTreeRebuild();
|
||||
}
|
||||
}
|
||||
else if (changedField == &m_timeStep)
|
||||
{
|
||||
triggerReplotAndTreeRebuild();
|
||||
}
|
||||
else if (changedField == &m_isChecked)
|
||||
{
|
||||
triggerReplotAndTreeRebuild();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimGridCrossPlotCurveSet::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if (fieldNeedingOptions == &m_case)
|
||||
{
|
||||
RimTools::caseOptionItems(&options);
|
||||
options.push_front(caf::PdmOptionItemInfo("None", nullptr));
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_timeStep)
|
||||
{
|
||||
QStringList timeStepNames;
|
||||
|
||||
if (m_case)
|
||||
{
|
||||
timeStepNames = m_case->timeStepStrings();
|
||||
}
|
||||
options.push_back(caf::PdmOptionItemInfo("All Time Steps", -1));
|
||||
for (int i = 0; i < timeStepNames.size(); i++)
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i));
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::triggerReplotAndTreeRebuild()
|
||||
{
|
||||
RimGridCrossPlot* parent;
|
||||
this->firstAncestorOrThisOfTypeAsserted(parent);
|
||||
parent->loadDataAndUpdate();
|
||||
parent->updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::performAutoNameUpdate()
|
||||
{
|
||||
this->setName(createAutoName());
|
||||
}
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlotCurveSetNameConfig, "RimGridCrossPlotCurveSetNameConfig");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCurveSetNameConfig::RimGridCrossPlotCurveSetNameConfig(RimNameConfigHolderInterface* parent)
|
||||
: RimNameConfig(parent)
|
||||
{
|
||||
CAF_PDM_InitObject("Cross Plot Curve Set NameGenerator", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&addCaseName, "AddCaseName", false, "Add Case Name", "", "", "");
|
||||
CAF_PDM_InitField(&addAxisVariables, "AddAxisVariables", true, "Add Axis Variables", "", "", "");
|
||||
CAF_PDM_InitField(&addTimestep, "AddTimeStep", false, "Add Time Step", "", "", "");
|
||||
|
||||
setCustomName("");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSetNameConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&addCaseName);
|
||||
uiOrdering.add(&addAxisVariables);
|
||||
uiOrdering.add(&addTimestep);
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RimCheckableNamedObject.h"
|
||||
#include "RimNameConfig.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimCase;
|
||||
class RimGridCrossPlotCurve;
|
||||
class RimEclipseResultDefinition;
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
|
||||
class RimGridCrossPlotCurveSetNameConfig : public RimNameConfig
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGridCrossPlotCurveSetNameConfig(RimNameConfigHolderInterface* parent = nullptr);
|
||||
|
||||
caf::PdmField<bool> addCaseName;
|
||||
caf::PdmField<bool> addAxisVariables;
|
||||
caf::PdmField<bool> addTimestep;
|
||||
|
||||
protected:
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimGridCrossPlotCurveSet : public RimCheckableNamedObject, public RimNameConfigHolderInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGridCrossPlotCurveSet();
|
||||
~RimGridCrossPlotCurveSet() = default;
|
||||
|
||||
void loadDataAndUpdate(bool updateParentPlot);
|
||||
void setParentQwtPlotNoReplot(QwtPlot* parent);
|
||||
QString xAxisName() const;
|
||||
QString yAxisName() const;
|
||||
|
||||
int indexInPlot() const;
|
||||
QString createAutoName() const override;
|
||||
|
||||
protected:
|
||||
void initAfterRead() override;
|
||||
void onLoadDataAndUpdate(bool updateParentPlot);
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly) override;
|
||||
void triggerReplotAndTreeRebuild();
|
||||
void performAutoNameUpdate() override;
|
||||
|
||||
private:
|
||||
|
||||
caf::PdmPtrField<RimCase*> m_case;
|
||||
caf::PdmField<int> m_timeStep;
|
||||
caf::PdmChildField<RimEclipseResultDefinition*> m_xAxisProperty;
|
||||
caf::PdmChildField<RimEclipseResultDefinition*> m_yAxisProperty;
|
||||
|
||||
caf::PdmChildField<RimGridCrossPlotCurveSetNameConfig*> m_nameConfig;
|
||||
|
||||
caf::PdmChildArrayField<RimGridCrossPlotCurve*> m_crossPlotCurves;
|
||||
};
|
@@ -900,7 +900,7 @@ void Rim3dView::applyBackgroundColor()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim3dView::performHolderUpdate()
|
||||
void Rim3dView::performAutoNameUpdate()
|
||||
{
|
||||
updateMdiWindowTitle();
|
||||
}
|
||||
|
@@ -180,7 +180,7 @@ protected:
|
||||
void applyBackgroundColor();
|
||||
|
||||
// Implementation of RimNameConfigHolderInterface
|
||||
void performHolderUpdate() override;
|
||||
void performAutoNameUpdate() override;
|
||||
|
||||
// Abstract methods to implement in subclasses
|
||||
|
||||
|
@@ -58,6 +58,8 @@
|
||||
#include "RimGeoMechPropertyFilterCollection.h"
|
||||
#include "RimGeoMechView.h"
|
||||
#include "RimGridCollection.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimIntersection.h"
|
||||
#include "RimIntersectionBox.h"
|
||||
@@ -461,6 +463,14 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
{
|
||||
menuBuilder << "RicPasteWellLogCurveFeature";
|
||||
}
|
||||
else if (dynamic_cast<RimGridCrossPlotCollection*>(uiItem))
|
||||
{
|
||||
menuBuilder << "RicCreateGridCrossPlotFeature";
|
||||
}
|
||||
else if (dynamic_cast<RimGridCrossPlot*>(uiItem))
|
||||
{
|
||||
menuBuilder << "RicCreateGridCrossPlotCurveSetFeature";
|
||||
}
|
||||
else if (dynamic_cast<RimSummaryPlot*>(uiItem)) // This is also the definition for RimSummaryCrossPlot
|
||||
{
|
||||
RimSummaryCrossPlot* summaryCrossPlot = dynamic_cast<RimSummaryCrossPlot*>(uiItem);
|
||||
|
@@ -39,6 +39,8 @@
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimFlowDiagSolution.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCurveSet.h"
|
||||
#include "RimGridTimeHistoryCurve.h"
|
||||
#include "RimIntersectionCollection.h"
|
||||
#include "RimPlotCurve.h"
|
||||
@@ -365,6 +367,13 @@ void RimEclipseResultDefinition::updateAnyFieldHasChanged()
|
||||
cellColors->updateConnectedEditors();
|
||||
}
|
||||
|
||||
RimGridCrossPlotCurveSet* crossPlotCurveSet = nullptr;
|
||||
this->firstAncestorOrThisOfType(crossPlotCurveSet);
|
||||
if (crossPlotCurveSet)
|
||||
{
|
||||
crossPlotCurveSet->updateConnectedEditors();
|
||||
}
|
||||
|
||||
RimPlotCurve* curve = nullptr;
|
||||
this->firstAncestorOrThisOfType(curve);
|
||||
if (curve)
|
||||
@@ -473,6 +482,13 @@ void RimEclipseResultDefinition::loadDataAndUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
RimGridCrossPlot* crossPlot = nullptr;
|
||||
this->firstAncestorOrThisOfType(crossPlot);
|
||||
if (crossPlot)
|
||||
{
|
||||
crossPlot->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
RimPlotCurve* curve = nullptr;
|
||||
this->firstAncestorOrThisOfType(curve);
|
||||
if (curve)
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "RimMainPlotCollection.h"
|
||||
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimFlowCharacteristicsPlot.h"
|
||||
#include "RimFlowPlotCollection.h"
|
||||
#include "RimPltPlotCollection.h"
|
||||
@@ -65,13 +67,16 @@ RimMainPlotCollection::RimMainPlotCollection()
|
||||
CAF_PDM_InitFieldNoDefault(&m_flowPlotCollection, "FlowPlotCollection", "Flow Diagnostics Plots", "", "", "");
|
||||
m_flowPlotCollection.uiCapability()->setUiHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_gridCrossPlotCollection, "Rim3dCrossPlotCollection", "3d Cross Plots", "", "", "");
|
||||
m_gridCrossPlotCollection.uiCapability()->setUiHidden(true);
|
||||
|
||||
m_wellLogPlotCollection = new RimWellLogPlotCollection();
|
||||
m_rftPlotCollection = new RimRftPlotCollection();
|
||||
m_pltPlotCollection = new RimPltPlotCollection();
|
||||
m_summaryPlotCollection = new RimSummaryPlotCollection();
|
||||
m_summaryCrossPlotCollection = new RimSummaryCrossPlotCollection();
|
||||
m_flowPlotCollection = new RimFlowPlotCollection();
|
||||
|
||||
m_gridCrossPlotCollection = new RimGridCrossPlotCollection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -79,13 +84,6 @@ RimMainPlotCollection::RimMainPlotCollection()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimMainPlotCollection::~RimMainPlotCollection()
|
||||
{
|
||||
if (m_wellLogPlotCollection()) delete m_wellLogPlotCollection();
|
||||
if (m_rftPlotCollection()) delete m_rftPlotCollection();
|
||||
if (m_pltPlotCollection()) delete m_pltPlotCollection();
|
||||
if (m_summaryPlotCollection()) delete m_summaryPlotCollection();
|
||||
if (m_summaryCrossPlotCollection()) delete m_summaryCrossPlotCollection();
|
||||
if (m_flowPlotCollection()) delete m_flowPlotCollection();
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -152,6 +150,14 @@ RimFlowPlotCollection* RimMainPlotCollection::flowPlotCollection()
|
||||
return m_flowPlotCollection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotCollection* RimMainPlotCollection::gridCrossPlotCollection()
|
||||
{
|
||||
return m_gridCrossPlotCollection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -162,7 +168,7 @@ void RimMainPlotCollection::deleteAllContainedObjects()
|
||||
m_pltPlotCollection()->deleteAllPlots();
|
||||
m_summaryPlotCollection()->summaryPlots.deleteAllChildObjects();
|
||||
m_summaryCrossPlotCollection()->deleteAllChildObjects();
|
||||
|
||||
m_gridCrossPlotCollection->deleteAllChildObjects();
|
||||
m_flowPlotCollection()->closeDefaultPlotWindowAndDeletePlots();
|
||||
}
|
||||
|
||||
@@ -208,6 +214,14 @@ void RimMainPlotCollection::updatePlotsWithFormations()
|
||||
{
|
||||
m_flowPlotCollection->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
if (m_gridCrossPlotCollection)
|
||||
{
|
||||
for (RimGridCrossPlot* crossPlot : m_gridCrossPlotCollection->gridCrossPlots())
|
||||
{
|
||||
crossPlot->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -30,6 +30,7 @@
|
||||
class RimWellLogPlotCollection;
|
||||
class RimRftPlotCollection;
|
||||
class RimPltPlotCollection;
|
||||
class RimGridCrossPlotCollection;
|
||||
class RimSummaryPlotCollection;
|
||||
class RimSummaryCrossPlotCollection;
|
||||
class RimSummaryPlot;
|
||||
@@ -55,6 +56,7 @@ public:
|
||||
RimSummaryPlotCollection* summaryPlotCollection();
|
||||
RimSummaryCrossPlotCollection* summaryCrossPlotCollection();
|
||||
RimFlowPlotCollection* flowPlotCollection();
|
||||
RimGridCrossPlotCollection* gridCrossPlotCollection();
|
||||
|
||||
void deleteAllContainedObjects();
|
||||
void updateCurrentTimeStepInPlots();
|
||||
@@ -74,6 +76,7 @@ private:
|
||||
caf::PdmChildField<RimSummaryPlotCollection*> m_summaryPlotCollection;
|
||||
caf::PdmChildField<RimSummaryCrossPlotCollection*> m_summaryCrossPlotCollection;
|
||||
caf::PdmChildField<RimFlowPlotCollection*> m_flowPlotCollection;
|
||||
caf::PdmChildField<RimGridCrossPlotCollection*> m_gridCrossPlotCollection;
|
||||
|
||||
caf::PdmField<bool> m_show;
|
||||
};
|
||||
|
@@ -30,10 +30,10 @@ class RimNameConfigHolderInterface
|
||||
{
|
||||
public:
|
||||
virtual QString createAutoName() const = 0;
|
||||
void updateHolder() { performHolderUpdate(); }
|
||||
void updateHolder() { performAutoNameUpdate(); }
|
||||
|
||||
protected:
|
||||
virtual void performHolderUpdate() {}
|
||||
virtual void performAutoNameUpdate() {}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
void uiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering);
|
||||
|
||||
protected:
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
QString autoName() const;
|
||||
virtual void updateAllSettings();
|
||||
|
@@ -287,6 +287,10 @@ void RimPlotCurve::setParentQwtPlotNoReplot(QwtPlot* plot)
|
||||
{
|
||||
m_qwtPlotCurve->attach(m_parentQwtPlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_qwtPlotCurve->detach();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -418,6 +422,14 @@ void RimPlotCurve::updateLegendsInPlot()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
throw std::logic_error("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -93,12 +93,14 @@ protected:
|
||||
virtual QString createCurveAutoName() = 0;
|
||||
virtual void updateZoomInParentPlot() = 0;
|
||||
virtual void onLoadDataAndUpdate(bool updateParentPlot) = 0;
|
||||
void initAfterRead() override;
|
||||
void initAfterRead() override;
|
||||
void updateCurvePresentation(bool updatePlotLegendAndTitle);
|
||||
|
||||
void updateOptionSensitivity();
|
||||
void updatePlotTitle();
|
||||
virtual void updateLegendsInPlot();
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
|
||||
protected:
|
||||
|
||||
// Overridden PDM methods
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "RimFormationNamesCollection.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimFractureTemplateCollection.h"
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimValveTemplate.h"
|
||||
#include "RimValveTemplateCollection.h"
|
||||
#include "RimGeoMechCase.h"
|
||||
@@ -1240,6 +1241,11 @@ void RimProject::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QS
|
||||
{
|
||||
itemCollection->add(mainPlotCollection->flowPlotCollection());
|
||||
}
|
||||
|
||||
if (mainPlotCollection->gridCrossPlotCollection())
|
||||
{
|
||||
itemCollection->add(mainPlotCollection->gridCrossPlotCollection());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@@ -32,6 +32,8 @@
|
||||
#include "RimEclipseContourMapViewCollection.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimFlowPlotCollection.h"
|
||||
#include "RimGridCrossPlot.h"
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCaseMainCollection.h"
|
||||
@@ -160,6 +162,15 @@ void RimReloadCaseTools::updateAllPlots()
|
||||
}
|
||||
}
|
||||
|
||||
RimGridCrossPlotCollection* gridCrossPlotCollection = project->mainPlotCollection()->gridCrossPlotCollection();
|
||||
if (gridCrossPlotCollection)
|
||||
{
|
||||
for (RimGridCrossPlot* crossPlot : gridCrossPlotCollection->gridCrossPlots())
|
||||
{
|
||||
crossPlot->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
RimFlowPlotCollection* flowPlotCollection = project->mainPlotCollection()->flowPlotCollection();
|
||||
if (flowPlotCollection)
|
||||
{
|
||||
|
@@ -698,7 +698,7 @@ QString RimWellLogPlot::createAutoName() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogPlot::performHolderUpdate()
|
||||
void RimWellLogPlot::performAutoNameUpdate()
|
||||
{
|
||||
this->m_commonDataSource->updateDefaultOptions();
|
||||
this->updatePlotTitle();
|
||||
|
@@ -127,7 +127,7 @@ public:
|
||||
void handleKeyPressEvent(QKeyEvent* keyEvent);
|
||||
RimWellLogCurveCommonDataSource* commonDataSource() const;
|
||||
protected:
|
||||
void performHolderUpdate() override;
|
||||
void performAutoNameUpdate() override;
|
||||
|
||||
// Overridden PDM methods
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
|
@@ -0,0 +1,41 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RigEclipseCrossPlotDataExtractor.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseResultAddress.h"
|
||||
#include "RigActiveCellInfo.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<double, double>> RigEclipseCrossPlotDataExtractor::extract(RigEclipseCaseData* caseData,
|
||||
int timeStep,
|
||||
const RigEclipseResultAddress& xAxisProperty,
|
||||
const RigEclipseResultAddress& yAxisProperty)
|
||||
{
|
||||
RigCaseCellResultsData* resultData = caseData->results(RiaDefines::MATRIX_MODEL);
|
||||
std::vector<double> xValues = resultData->cellScalarResults(xAxisProperty)[timeStep];
|
||||
std::vector<double> yValues = resultData->cellScalarResults(xAxisProperty)[timeStep];
|
||||
size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex);
|
||||
size_t resultValueIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex);
|
||||
if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL;
|
||||
|
||||
if (resultValueIndex < m_reservoirResultValues->size()) return m_reservoirResultValues->at(resultValueIndex);
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 <utility>
|
||||
#include <vector>
|
||||
|
||||
class RigEclipseCaseData;
|
||||
class RigEclipseResultAddress;
|
||||
|
||||
class RigEclipseCrossPlotDataExtractor
|
||||
{
|
||||
static std::vector<std::pair<double, double>> extract(RigEclipseCaseData* caseData,
|
||||
int timeStep,
|
||||
const RigEclipseResultAddress& xAxisProperty,
|
||||
const RigEclipseResultAddress& yAxisProperty);
|
||||
};
|
||||
|
@@ -75,6 +75,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindowTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/Riu3DMainWindowTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuDockWidgetTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMeasurementViewEventFilter.h
|
||||
)
|
||||
@@ -152,6 +153,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindowTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/Riu3DMainWindowTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuDockWidgetTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.cpp
|
||||
)
|
||||
|
||||
|
@@ -325,7 +325,7 @@ void RiuQwtPlotCurve::setAppearance(LineStyleEnum lineStyle,
|
||||
const QColor& curveColor)
|
||||
{
|
||||
QwtPlotCurve::CurveStyle curveStyle = QwtPlotCurve::NoCurve;
|
||||
Qt::PenStyle penStyle = Qt::SolidLine;
|
||||
Qt::PenStyle penStyle = Qt::NoPen;
|
||||
|
||||
if (lineStyle != STYLE_NONE)
|
||||
{
|
||||
|
102
ApplicationCode/UserInterface/RiuQwtPlotTools.cpp
Normal file
102
ApplicationCode/UserInterface/RiuQwtPlotTools.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RiuQwtPlotTools.h"
|
||||
|
||||
#include "qwt_plot.h"
|
||||
#include "qwt_plot_grid.h"
|
||||
#include "qwt_plot_layout.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotTools::setCommonPlotBehaviour(QwtPlot* plot)
|
||||
{
|
||||
// Plot background and frame look
|
||||
|
||||
QPalette newPalette(plot->palette());
|
||||
newPalette.setColor(QPalette::Background, Qt::white);
|
||||
plot->setPalette(newPalette);
|
||||
|
||||
plot->setAutoFillBackground(true);
|
||||
plot->setCanvasBackground(Qt::white);
|
||||
|
||||
QFrame* canvasFrame = dynamic_cast<QFrame*>(plot->canvas());
|
||||
if (canvasFrame)
|
||||
{
|
||||
canvasFrame->setFrameShape(QFrame::NoFrame);
|
||||
}
|
||||
|
||||
// Grid
|
||||
|
||||
QwtPlotGrid* grid = new QwtPlotGrid;
|
||||
grid->attach(plot);
|
||||
QPen gridPen(Qt::SolidLine);
|
||||
gridPen.setColor(Qt::lightGray);
|
||||
grid->setPen(gridPen);
|
||||
|
||||
// Axis number font
|
||||
QFont axisFont = plot->axisFont(QwtPlot::xBottom);
|
||||
axisFont.setPixelSize(11);
|
||||
|
||||
plot->setAxisFont(QwtPlot::xBottom, axisFont);
|
||||
plot->setAxisFont(QwtPlot::xTop, axisFont);
|
||||
plot->setAxisFont(QwtPlot::yLeft, axisFont);
|
||||
plot->setAxisFont(QwtPlot::yRight, axisFont);
|
||||
|
||||
// Axis title font
|
||||
std::vector<QwtPlot::Axis> axes = { QwtPlot::xBottom, QwtPlot::xTop, QwtPlot::yLeft, QwtPlot::yRight };
|
||||
|
||||
for (QwtPlot::Axis axis : axes)
|
||||
{
|
||||
QwtText axisTitle = plot->axisTitle(axis);
|
||||
QFont axisTitleFont = axisTitle.font();
|
||||
axisTitleFont.setPixelSize(11);
|
||||
axisTitleFont.setBold(false);
|
||||
axisTitle.setFont(axisTitleFont);
|
||||
axisTitle.setRenderFlags(Qt::AlignRight);
|
||||
|
||||
plot->setAxisTitle(axis, axisTitle);
|
||||
}
|
||||
|
||||
// Set a focus policy to allow it taking key press events.
|
||||
// This is not strictly necessary since this widget inherit QwtPlot
|
||||
// which already has a focus policy.
|
||||
// However, for completeness we still do it here.
|
||||
plot->setFocusPolicy(Qt::WheelFocus);
|
||||
|
||||
// Enable mousetracking and event filter
|
||||
plot->canvas()->setMouseTracking(true);
|
||||
plot->canvas()->installEventFilter(plot);
|
||||
plot->plotLayout()->setAlignCanvasToScales(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotTools::setDefaultAxes(QwtPlot* plot)
|
||||
{
|
||||
plot->enableAxis(QwtPlot::xBottom, true);
|
||||
plot->enableAxis(QwtPlot::yLeft, true);
|
||||
plot->enableAxis(QwtPlot::xTop, false);
|
||||
plot->enableAxis(QwtPlot::yRight, false);
|
||||
|
||||
plot->setAxisMaxMinor(QwtPlot::xBottom, 2);
|
||||
plot->setAxisMaxMinor(QwtPlot::yLeft, 3);
|
||||
}
|
28
ApplicationCode/UserInterface/RiuQwtPlotTools.h
Normal file
28
ApplicationCode/UserInterface/RiuQwtPlotTools.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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
|
||||
|
||||
class QwtPlot;
|
||||
|
||||
class RiuQwtPlotTools
|
||||
{
|
||||
public:
|
||||
static void setCommonPlotBehaviour(QwtPlot* plot);
|
||||
static void setDefaultAxes(QwtPlot* plot);
|
||||
};
|
||||
|
@@ -102,6 +102,18 @@ RiuQwtSymbol::RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, Label
|
||||
setPinPoint(QPointF(0, 10));
|
||||
}
|
||||
break;
|
||||
case SYMBOL_UP_TRIANGLE:
|
||||
style = QwtSymbol::UTriangle;
|
||||
break;
|
||||
case SYMBOL_STAR1:
|
||||
style = QwtSymbol::Star1;
|
||||
break;
|
||||
case SYMBOL_STAR2:
|
||||
style = QwtSymbol::Star2;
|
||||
break;
|
||||
case SYMBOL_HEXAGON:
|
||||
style = QwtSymbol::Hexagon;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -144,6 +156,27 @@ void RiuQwtSymbol::setLabelPosition(LabelPosition labelPosition)
|
||||
m_labelPosition = labelPosition;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtSymbol::PointSymbolEnum RiuQwtSymbol::cycledSymbolStyle(int indexLevel1, int indexLevel2)
|
||||
{
|
||||
std::vector<std::vector<PointSymbolEnum>> categorisedStyles =
|
||||
{
|
||||
{SYMBOL_ELLIPSE, SYMBOL_RECT, SYMBOL_DIAMOND},
|
||||
{SYMBOL_TRIANGLE, SYMBOL_DOWN_TRIANGLE, SYMBOL_UP_TRIANGLE},
|
||||
{SYMBOL_LEFT_TRIANGLE, SYMBOL_RIGHT_TRIANGLE},
|
||||
{SYMBOL_LEFT_ANGLED_TRIANGLE, SYMBOL_RIGHT_ANGLED_TRIANGLE},
|
||||
{SYMBOL_CROSS, SYMBOL_XCROSS},
|
||||
{SYMBOL_STAR1, SYMBOL_STAR2},
|
||||
};
|
||||
|
||||
int level1Category = indexLevel1 % int(categorisedStyles.size());
|
||||
int level2Category = indexLevel2 % int(categorisedStyles[level1Category].size());
|
||||
|
||||
return categorisedStyles[level1Category][level2Category];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -44,22 +44,28 @@ public:
|
||||
SYMBOL_RECT,
|
||||
SYMBOL_DIAMOND,
|
||||
SYMBOL_TRIANGLE,
|
||||
SYMBOL_DOWN_TRIANGLE,
|
||||
SYMBOL_CROSS,
|
||||
SYMBOL_XCROSS,
|
||||
SYMBOL_DOWN_TRIANGLE,
|
||||
SYMBOL_LEFT_TRIANGLE,
|
||||
SYMBOL_RIGHT_TRIANGLE,
|
||||
SYMBOL_LEFT_ANGLED_TRIANGLE,
|
||||
SYMBOL_RIGHT_ANGLED_TRIANGLE
|
||||
SYMBOL_RIGHT_ANGLED_TRIANGLE,
|
||||
SYMBOL_UP_TRIANGLE,
|
||||
SYMBOL_STAR1,
|
||||
SYMBOL_STAR2,
|
||||
SYMBOL_HEXAGON
|
||||
};
|
||||
|
||||
RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, LabelPosition labelPosition = LabelAboveSymbol);
|
||||
|
||||
|
||||
void renderSymbols(QPainter *painter, const QPointF *points, int numPoints) const override;
|
||||
void renderSymbolLabel(QPainter *painter, const QPointF& position) const;
|
||||
QString label() const { return m_label; }
|
||||
|
||||
void setLabelPosition(LabelPosition labelPosition);
|
||||
|
||||
static PointSymbolEnum cycledSymbolStyle(int indexLevel1, int indexLevel2);
|
||||
private:
|
||||
QRect labelBoundingRect(const QPainter* painter, const QRect& symbolRect) const;
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtCurvePointTracker.h"
|
||||
#include "RiuQwtPlotTools.h"
|
||||
#include "RiuQwtPlotWheelZoomer.h"
|
||||
#include "RiuQwtPlotZoomer.h"
|
||||
#include "RiuQwtScalePicker.h"
|
||||
@@ -305,17 +306,10 @@ QSize RiuSummaryQwtPlot::sizeHint() const
|
||||
void RiuSummaryQwtPlot::setDefaults()
|
||||
{
|
||||
setCommonPlotBehaviour(this);
|
||||
|
||||
enableAxis(QwtPlot::xBottom, true);
|
||||
enableAxis(QwtPlot::yLeft, true);
|
||||
enableAxis(QwtPlot::xTop, false);
|
||||
enableAxis(QwtPlot::yRight, false);
|
||||
RiuQwtPlotTools::setDefaultAxes(this);
|
||||
|
||||
useDateBasedTimeAxis();
|
||||
|
||||
setAxisMaxMinor(QwtPlot::xBottom, 2);
|
||||
setAxisMaxMinor(QwtPlot::yLeft, 3);
|
||||
|
||||
// The legend will be deleted in the destructor of the plot or when
|
||||
// another legend is inserted.
|
||||
QwtLegend* legend = new QwtLegend(this);
|
||||
@@ -324,62 +318,8 @@ void RiuSummaryQwtPlot::setDefaults()
|
||||
|
||||
void RiuSummaryQwtPlot::setCommonPlotBehaviour(QwtPlot* plot)
|
||||
{
|
||||
// Plot background and frame look
|
||||
|
||||
QPalette newPalette(plot->palette());
|
||||
newPalette.setColor(QPalette::Background, Qt::white);
|
||||
plot->setPalette(newPalette);
|
||||
|
||||
plot->setAutoFillBackground(true);
|
||||
plot->setCanvasBackground(Qt::white);
|
||||
|
||||
QFrame* canvasFrame = dynamic_cast<QFrame*>(plot->canvas());
|
||||
if (canvasFrame)
|
||||
{
|
||||
canvasFrame->setFrameShape(QFrame::NoFrame);
|
||||
}
|
||||
|
||||
// Grid
|
||||
|
||||
QwtPlotGrid* grid = new QwtPlotGrid;
|
||||
grid->attach(plot);
|
||||
QPen gridPen(Qt::SolidLine);
|
||||
gridPen.setColor(Qt::lightGray);
|
||||
grid->setPen(gridPen);
|
||||
|
||||
// Axis number font
|
||||
QFont axisFont = plot->axisFont(QwtPlot::xBottom);
|
||||
axisFont.setPixelSize(11);
|
||||
|
||||
plot->setAxisFont(QwtPlot::xBottom, axisFont);
|
||||
plot->setAxisFont(QwtPlot::xTop, axisFont);
|
||||
plot->setAxisFont(QwtPlot::yLeft, axisFont);
|
||||
plot->setAxisFont(QwtPlot::yRight, axisFont);
|
||||
|
||||
// Axis title font
|
||||
QwtText axisTitle = plot->axisTitle(QwtPlot::xBottom);
|
||||
QFont axisTitleFont = axisTitle.font();
|
||||
axisTitleFont.setPixelSize(11);
|
||||
axisTitleFont.setBold(false);
|
||||
axisTitle.setFont(axisTitleFont);
|
||||
axisTitle.setRenderFlags(Qt::AlignRight);
|
||||
|
||||
plot->setAxisTitle(QwtPlot::xBottom, axisTitle);
|
||||
plot->setAxisTitle(QwtPlot::xTop, axisTitle);
|
||||
plot->setAxisTitle(QwtPlot::yLeft, axisTitle);
|
||||
plot->setAxisTitle(QwtPlot::yRight, axisTitle);
|
||||
|
||||
// Set a focus policy to allow it taking key press events.
|
||||
// This is not strictly necessary since this widget inherit QwtPlot
|
||||
// which already has a focus policy.
|
||||
// However, for completeness we still do it here.
|
||||
plot->setFocusPolicy(Qt::WheelFocus);
|
||||
|
||||
// Enable mousetracking and event filter
|
||||
plot->canvas()->setMouseTracking(true);
|
||||
plot->canvas()->installEventFilter(plot);
|
||||
plot->plotLayout()->setAlignCanvasToScales(true);
|
||||
|
||||
RiuQwtPlotTools::setCommonPlotBehaviour(plot);
|
||||
|
||||
new RiuQwtCurvePointTracker(plot, true, &ensembleCurveInfoTextProvider);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user