mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4157 Grid Cross Plot: Make categorisation legend more like ensemble legend
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "RiaGridCrossPlotCurveNameHelper.h"
|
||||
|
||||
#include "RiuSummaryQwtPlot.h"
|
||||
#include "RiuGridCrossQwtPlot.h"
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtPlotTools.h"
|
||||
|
||||
@@ -106,6 +106,14 @@ int RimGridCrossPlot::indexOfCurveSet(const RimGridCrossPlotCurveSet* curveSet)
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimGridCrossPlotCurveSet*> RimGridCrossPlot::curveSets() const
|
||||
{
|
||||
return m_crossPlotCurveSets.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -168,7 +176,7 @@ void RimGridCrossPlot::reattachCurvesToQwtAndReplot()
|
||||
curveSet->setParentQwtPlotNoReplot(m_qwtPlot);
|
||||
}
|
||||
}
|
||||
m_qwtPlot->replot();
|
||||
updateAxisDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +196,10 @@ QString RimGridCrossPlot::createAutoName() const
|
||||
QStringList dataSets;
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
dataSets += curveSet->createAutoName();
|
||||
if (curveSet->isChecked())
|
||||
{
|
||||
dataSets += curveSet->createAutoName();
|
||||
}
|
||||
}
|
||||
if (!dataSets.isEmpty())
|
||||
{
|
||||
@@ -298,7 +309,7 @@ QWidget* RimGridCrossPlot::createViewWidget(QWidget* mainWindowParent)
|
||||
{
|
||||
if (!m_qwtPlot)
|
||||
{
|
||||
m_qwtPlot = new RiuQwtPlot(this, mainWindowParent);
|
||||
m_qwtPlot = new RiuGridCrossQwtPlot(this, mainWindowParent);
|
||||
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
@@ -468,6 +479,14 @@ void RimGridCrossPlot::updateCurveNamesAndPlotTitle()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuGridCrossQwtPlot* RimGridCrossPlot::qwtPlot() const
|
||||
{
|
||||
return m_qwtPlot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -476,7 +495,10 @@ QString RimGridCrossPlot::xAxisParameterString() const
|
||||
QStringList xAxisParams;
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
xAxisParams.push_back(curveSet->xAxisName());
|
||||
if (curveSet->isChecked())
|
||||
{
|
||||
xAxisParams.push_back(curveSet->xAxisName());
|
||||
}
|
||||
}
|
||||
|
||||
xAxisParams.removeDuplicates();
|
||||
@@ -497,7 +519,10 @@ QString RimGridCrossPlot::yAxisParameterString() const
|
||||
QStringList yAxisParams;
|
||||
for (auto curveSet : m_crossPlotCurveSets)
|
||||
{
|
||||
yAxisParams.push_back(curveSet->yAxisName());
|
||||
if (curveSet->isChecked())
|
||||
{
|
||||
yAxisParams.push_back(curveSet->yAxisName());
|
||||
}
|
||||
}
|
||||
|
||||
yAxisParams.removeDuplicates();
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
class RimPlotAxisProperties;
|
||||
class RimGridCrossPlotCurveSet;
|
||||
class RiuQwtPlot;
|
||||
class RiuGridCrossQwtPlot;
|
||||
|
||||
class RimGridCrossPlotNameConfig : public RimNameConfig
|
||||
{
|
||||
@@ -56,6 +56,8 @@ public:
|
||||
|
||||
RimGridCrossPlotCurveSet* createCurveSet();
|
||||
int indexOfCurveSet(const RimGridCrossPlotCurveSet* curveSet) const;
|
||||
|
||||
std::vector<RimGridCrossPlotCurveSet*> curveSets() const;
|
||||
|
||||
QWidget* viewWidget() override;
|
||||
QImage snapshotWindowContent() override;
|
||||
@@ -69,6 +71,7 @@ public:
|
||||
void performAutoNameUpdate() override;
|
||||
void updateCurveNamesAndPlotTitle();
|
||||
|
||||
RiuGridCrossQwtPlot* qwtPlot() const;
|
||||
public:
|
||||
// Rim2dPlotInterface overrides
|
||||
void updateAxisScaling() override;
|
||||
@@ -97,7 +100,7 @@ protected:
|
||||
|
||||
void updateAxisInQwt(RiaDefines::PlotAxis axisType);
|
||||
void updateAxisFromQwt(RiaDefines::PlotAxis axisType);
|
||||
std::pair<double, double> getAxisRangeFromData(RiaDefines::PlotAxis axisType);
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showLegend;
|
||||
caf::PdmField<int> m_legendFontSize;
|
||||
@@ -108,7 +111,7 @@ private:
|
||||
|
||||
caf::PdmChildArrayField<RimGridCrossPlotCurveSet*> m_crossPlotCurveSets;
|
||||
|
||||
QPointer<RiuQwtPlot> m_qwtPlot;
|
||||
QPointer<RiuGridCrossQwtPlot> m_qwtPlot;
|
||||
RiaGridCrossPlotCurveNameHelper m_curveNameHelper;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ CAF_PDM_SOURCE_INIT(RimGridCrossPlotCurve, "GridCrossPlotCurve");
|
||||
RimGridCrossPlotCurve::RimGridCrossPlotCurve()
|
||||
: m_curveSetIndex(0)
|
||||
, m_categoryIndex(0)
|
||||
, m_categoryCount(0)
|
||||
{
|
||||
CAF_PDM_InitObject("Cross Plot Points", ":/WellLogCurve16x16.png", "", "");
|
||||
|
||||
@@ -60,19 +59,10 @@ RimGridCrossPlotCurve::RimGridCrossPlotCurve()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::setCategoryInformation(int curveSetIndex, int categoryIndex, int categoryCount)
|
||||
void RimGridCrossPlotCurve::setCategoryInformation(int curveSetIndex, int categoryIndex)
|
||||
{
|
||||
m_curveSetIndex = curveSetIndex;
|
||||
m_categoryIndex = categoryIndex;
|
||||
m_categoryCount = categoryCount;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::setUseContrastColors(bool useContrastColors)
|
||||
{
|
||||
m_useContrastColors = useContrastColors;
|
||||
m_categoryIndex = categoryIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -90,7 +80,7 @@ void RimGridCrossPlotCurve::setSamples(const std::vector<double>& xValues, const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::updateCurveAppearance()
|
||||
{
|
||||
determineColorAndSymbol();
|
||||
determineSymbol();
|
||||
RimPlotCurve::updateCurveAppearance();
|
||||
}
|
||||
|
||||
@@ -105,30 +95,10 @@ int RimGridCrossPlotCurve::categoryIndex() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurve::determineColorAndSymbol()
|
||||
void RimGridCrossPlotCurve::determineSymbol()
|
||||
{
|
||||
if (m_useContrastColors)
|
||||
{
|
||||
const caf::ColorTable& colors = RiaColorTables::categoryPaletteColors();
|
||||
int colorIndex = m_categoryIndex + m_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 = m_categoryIndex / numColors;
|
||||
|
||||
RiuQwtSymbol::PointSymbolEnum symbol = RiuQwtSymbol::cycledSymbolStyle(m_curveSetIndex, symbolIndex);
|
||||
setSymbol(symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
const caf::ColorTable& colors = RiaColorTables::contrastCategoryPaletteColors();
|
||||
cvf::Color3ub cycledBaseColor = colors.cycledColor3ub(m_curveSetIndex);
|
||||
caf::ColorTable hueConstColTable = RiaColorTables::createBrightnessBasedColorTable(cycledBaseColor, m_categoryCount);
|
||||
setColor(hueConstColTable.cycledColor3f(m_categoryIndex));
|
||||
RiuQwtSymbol::PointSymbolEnum symbol = RiuQwtSymbol::cycledFilledSymbolStyle(m_curveSetIndex);
|
||||
setSymbol(symbol);
|
||||
}
|
||||
RiuQwtSymbol::PointSymbolEnum symbol = RiuQwtSymbol::cycledFilledSymbolStyle(m_curveSetIndex);
|
||||
setSymbol(symbol);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -40,15 +40,14 @@ class RimGridCrossPlotCurve : public RimPlotCurve
|
||||
public:
|
||||
RimGridCrossPlotCurve();
|
||||
~RimGridCrossPlotCurve() override = default;
|
||||
void setCategoryInformation(int curveSetIndex, int categoryIndex, int categoryCount);
|
||||
void setUseContrastColors(bool useContrastColors);
|
||||
void setCategoryInformation(int curveSetIndex, int categoryIndex);
|
||||
void setSamples(const std::vector<double>& xValues, const std::vector<double>& yValues);
|
||||
void updateCurveAppearance() override;
|
||||
int categoryIndex() const;
|
||||
|
||||
protected:
|
||||
|
||||
void determineColorAndSymbol();
|
||||
void determineSymbol();
|
||||
void updateZoomInParentPlot() override;
|
||||
void updateLegendsInPlot() override;
|
||||
QString createCurveAutoName() override;
|
||||
@@ -56,9 +55,7 @@ protected:
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
|
||||
private:
|
||||
int m_curveSetIndex;
|
||||
int m_categoryIndex;
|
||||
int m_categoryCount;
|
||||
bool m_useContrastColors;
|
||||
int m_curveSetIndex;
|
||||
int m_categoryIndex;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,16 +18,20 @@
|
||||
#include "RimGridCrossPlotCurveSet.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigActiveCellsResultAccessor.h"
|
||||
#include "RigCaseCellResultCalculator.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseCrossPlotDataExtractor.h"
|
||||
|
||||
#include "RigFormationNames.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RiuGridCrossQwtPlot.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseView.h"
|
||||
@@ -36,10 +40,14 @@
|
||||
#include "RimGridCrossPlotCurve.h"
|
||||
#include "RimGridView.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafColorTable.h"
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiSliderEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
@@ -89,9 +97,6 @@ RimGridCrossPlotCurveSet::RimGridCrossPlotCurveSet()
|
||||
m_categoryProperty.uiCapability()->setUiHidden(true);
|
||||
m_categoryProperty.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitField(&m_categoryBinCount, "CategoryBinCount", 2, "Number of Data Groups", "", "", "");
|
||||
m_categoryBinCount.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName());
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "Name", "", "", "");
|
||||
m_nameConfig = new RimGridCrossPlotCurveSetNameConfig(this);
|
||||
m_nameConfig.uiCapability()->setUiTreeHidden(true);
|
||||
@@ -100,6 +105,12 @@ RimGridCrossPlotCurveSet::RimGridCrossPlotCurveSet()
|
||||
CAF_PDM_InitFieldNoDefault(&m_crossPlotCurves, "CrossPlotCurves", "Curves", "", "", "");
|
||||
m_crossPlotCurves.uiCapability()->setUiTreeHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_legendConfig, "LegendConfig", "", "", "", "");
|
||||
m_legendConfig = new RimRegularLegendConfig();
|
||||
m_legendConfig->setColorRange(RimRegularLegendConfig::CATEGORY);
|
||||
m_legendConfig->setMappingMode(RimRegularLegendConfig::CATEGORY_INTEGER);
|
||||
m_legendConfig->setTickNumberFormat(RimRegularLegendConfig::AUTO);
|
||||
|
||||
setDefaults();
|
||||
}
|
||||
|
||||
@@ -189,23 +200,36 @@ QString RimGridCrossPlotCurveSet::createAutoName() const
|
||||
|
||||
if (m_nameConfig->addCategorization)
|
||||
{
|
||||
if (m_categorization() == TIME_CATEGORIZATION)
|
||||
{
|
||||
nameTags += QString("Grouped by Time");
|
||||
}
|
||||
else if (m_categorization() == FORMATION_CATEGORIZATION)
|
||||
{
|
||||
nameTags += QString("Grouped by formations");
|
||||
}
|
||||
else if (m_categorization() == RESULT_CATEGORIZATION && m_categoryProperty->hasResult())
|
||||
{
|
||||
nameTags += QString("Grouped by %1").arg(m_categoryProperty->resultVariableUiShortName());
|
||||
}
|
||||
QString catTitle = categoryTitle();
|
||||
if (!catTitle.isEmpty()) nameTags += catTitle;
|
||||
}
|
||||
|
||||
return nameTags.join(", ");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlotCurveSet::categoryTitle() const
|
||||
{
|
||||
if (hasCategoryResult())
|
||||
{
|
||||
if (m_categorization() == TIME_CATEGORIZATION)
|
||||
{
|
||||
return QString("Time Steps");
|
||||
}
|
||||
else if (m_categorization() == FORMATION_CATEGORIZATION)
|
||||
{
|
||||
return QString("Formations");
|
||||
}
|
||||
else if (m_categorization() == RESULT_CATEGORIZATION && m_categoryProperty->hasResult())
|
||||
{
|
||||
return QString("%1").arg(m_categoryProperty->resultVariableUiShortName());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -228,6 +252,14 @@ void RimGridCrossPlotCurveSet::cellFilterViewUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularLegendConfig* RimGridCrossPlotCurveSet::legendConfig()
|
||||
{
|
||||
return m_legendConfig;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -281,12 +313,12 @@ QString RimGridCrossPlotCurveSet::timeStepString() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> RimGridCrossPlotCurveSet::categoryStrings() const
|
||||
{
|
||||
std::vector<QString> categoryNames;
|
||||
for (auto categoryIndexNamePair : m_categoryNames)
|
||||
std::vector<QString> catStrings;
|
||||
for (auto curve : m_crossPlotCurves())
|
||||
{
|
||||
categoryNames.push_back(categoryIndexNamePair.second);
|
||||
catStrings.push_back(m_legendConfig->categoryNameFromCategoryValue(curve->categoryIndex()));
|
||||
}
|
||||
return categoryNames;
|
||||
return catStrings;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -338,28 +370,87 @@ void RimGridCrossPlotCurveSet::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
|
||||
std::map<int, cvf::UByteArray> timeStepCellVisibilityMap = calculateCellVisibility(eclipseCase);
|
||||
|
||||
updateLegend();
|
||||
|
||||
RigEclipseCrossPlotResult result = RigEclipseCrossPlotDataExtractor::extract(
|
||||
eclipseCase->eclipseCaseData(), m_timeStep(), xAddress, yAddress, m_categorization(), catAddress, m_categoryBinCount, timeStepCellVisibilityMap);
|
||||
eclipseCase->eclipseCaseData(), m_timeStep(), xAddress, yAddress, m_categorization(), catAddress, timeStepCellVisibilityMap);
|
||||
|
||||
m_categoryNames = result.categoryNameMap;
|
||||
for (const auto& sampleCategory : result.categorySamplesMap)
|
||||
{
|
||||
RimGridCrossPlotCurve* curve = new RimGridCrossPlotCurve();
|
||||
curve->setCategoryInformation(indexInPlot(), sampleCategory.first, (int)result.categorySamplesMap.size());
|
||||
curve->setUseContrastColors(m_categorization() == FORMATION_CATEGORIZATION);
|
||||
curve->setSamples(sampleCategory.second.first, sampleCategory.second.second);
|
||||
curve->updateCurveAppearance();
|
||||
curve->updateUiIconFromPlotSymbol();
|
||||
createCurves(result);
|
||||
|
||||
m_crossPlotCurves.push_back(curve);
|
||||
}
|
||||
|
||||
if (updateParentPlot)
|
||||
{
|
||||
triggerPlotNameUpdateAndReplot();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& result)
|
||||
{
|
||||
if (m_categorization == NO_CATEGORIZATION)
|
||||
{
|
||||
const caf::ColorTable& colors = RiaColorTables::contrastCategoryPaletteColors();
|
||||
int colorIndex = indexInPlot();
|
||||
|
||||
RimGridCrossPlotCurve* curve = new RimGridCrossPlotCurve();
|
||||
curve->setColor(colors.cycledColor3f(colorIndex));
|
||||
curve->setCategoryInformation(indexInPlot(), 0);
|
||||
curve->setSamples(result.xValues, result.yValues);
|
||||
curve->updateCurveAppearance();
|
||||
curve->updateUiIconFromPlotSymbol();
|
||||
m_crossPlotCurves.push_back(curve);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<int, std::pair<std::vector<double>, std::vector<double>>> categorizedResults;
|
||||
|
||||
std::vector<double> tickValues;
|
||||
|
||||
if (m_categorization == TIME_CATEGORIZATION || m_categorization == FORMATION_CATEGORIZATION)
|
||||
{
|
||||
for (size_t i = 0; i < result.xValues.size(); ++i)
|
||||
{
|
||||
categorizedResults[result.catValuesDiscrete[i]].first.push_back(result.xValues[i]);
|
||||
categorizedResults[result.catValuesDiscrete[i]].second.push_back(result.yValues[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_legendConfig->scalarMapper()->majorTickValues(&tickValues);
|
||||
|
||||
for (size_t i = 0; i < result.xValues.size(); ++i)
|
||||
{
|
||||
auto upperBoundIt = std::lower_bound(tickValues.begin(), tickValues.end(), result.catValuesContinuous[i]);
|
||||
int upperBoundIndex = static_cast<int>(upperBoundIt - tickValues.begin());
|
||||
int lowerBoundIndex = std::min((int) tickValues.size() - 2, std::max(0, upperBoundIndex - 1));
|
||||
categorizedResults[lowerBoundIndex].first.push_back(result.xValues[i]);
|
||||
categorizedResults[lowerBoundIndex].second.push_back(result.yValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = categorizedResults.rbegin(); it != categorizedResults.rend(); ++it)
|
||||
{
|
||||
RimGridCrossPlotCurve* curve = new RimGridCrossPlotCurve();
|
||||
curve->setCategoryInformation(indexInPlot(), it->first);
|
||||
if (m_categorization == RESULT_CATEGORIZATION)
|
||||
{
|
||||
curve->setColor(cvf::Color3f(m_legendConfig->scalarMapper()->mapToColor(tickValues[it->first])));
|
||||
}
|
||||
else
|
||||
{
|
||||
curve->setColor(cvf::Color3f(m_legendConfig->scalarMapper()->mapToColor(it->first)));
|
||||
}
|
||||
curve->setSamples(it->second.first, it->second.second);
|
||||
curve->showLegend(m_crossPlotCurves.empty());
|
||||
curve->setLegendEntryTitle(createAutoName());
|
||||
curve->updateCurveAppearance();
|
||||
curve->updateUiIconFromPlotSymbol();
|
||||
m_crossPlotCurves.push_back(curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -414,7 +505,6 @@ void RimGridCrossPlotCurveSet::defineUiOrdering(QString uiConfigName, caf::PdmUi
|
||||
{
|
||||
caf::PdmUiGroup* categoryGroup = uiOrdering.addNewGroup("Data Grouping Property");
|
||||
m_categoryProperty->uiOrdering(uiConfigName, *categoryGroup);
|
||||
categoryGroup->add(&m_categoryBinCount);
|
||||
}
|
||||
|
||||
caf::PdmUiGroup* xAxisGroup = uiOrdering.addNewGroup("X-Axis Property");
|
||||
@@ -457,8 +547,25 @@ void RimGridCrossPlotCurveSet::fieldChangedByUi(const caf::PdmFieldHandle* chang
|
||||
{
|
||||
loadDataAndUpdate(true);
|
||||
}
|
||||
else if (changedField == &m_categorization || changedField == &m_categoryBinCount)
|
||||
else if (changedField == &m_categorization)
|
||||
{
|
||||
if (m_categorization == TIME_CATEGORIZATION)
|
||||
{
|
||||
m_legendConfig->setColorRange(RimRegularLegendConfig::NORMAL);
|
||||
m_legendConfig->setMappingMode(RimRegularLegendConfig::CATEGORY_INTEGER);
|
||||
}
|
||||
else if (m_categorization == FORMATION_CATEGORIZATION)
|
||||
{
|
||||
m_legendConfig->setColorRange(RimRegularLegendConfig::CATEGORY);
|
||||
m_legendConfig->setMappingMode(RimRegularLegendConfig::CATEGORY_INTEGER);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_legendConfig->setColorRange(RimRegularLegendConfig::NORMAL);
|
||||
m_legendConfig->setMappingMode(RimRegularLegendConfig::LINEAR_DISCRETE);
|
||||
|
||||
}
|
||||
|
||||
loadDataAndUpdate(true);
|
||||
}
|
||||
else if (changedField == &m_cellFilterView)
|
||||
@@ -467,6 +574,7 @@ void RimGridCrossPlotCurveSet::fieldChangedByUi(const caf::PdmFieldHandle* chang
|
||||
}
|
||||
else if (changedField == &m_isChecked)
|
||||
{
|
||||
updateLegend();
|
||||
triggerPlotNameUpdateAndReplot();
|
||||
}
|
||||
}
|
||||
@@ -529,6 +637,96 @@ QList<caf::PdmOptionItemInfo> RimGridCrossPlotCurveSet::calculateValueOptions(co
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::updateLegend()
|
||||
{
|
||||
m_legendConfig->setTitle(categoryTitle());
|
||||
|
||||
RimGridCrossPlot* parent;
|
||||
this->firstAncestorOrThisOfTypeAsserted(parent);
|
||||
if (parent->qwtPlot())
|
||||
{
|
||||
if (m_categorization() != NO_CATEGORIZATION && m_case() && isChecked() && legendConfig()->showLegend())
|
||||
{
|
||||
if (m_categorization() == FORMATION_CATEGORIZATION)
|
||||
{
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case());
|
||||
RigFormationNames* formationNames = eclipseCase->eclipseCaseData()->activeFormationNames();
|
||||
|
||||
const std::vector<QString>& categoryNames = formationNames->formationNames();
|
||||
m_legendConfig->setNamedCategories(categoryNames);
|
||||
m_legendConfig->setAutomaticRanges(0, categoryNames.size() - 1, 0, categoryNames.size() - 1);
|
||||
}
|
||||
else if (m_categorization() == TIME_CATEGORIZATION)
|
||||
{
|
||||
QStringList timeStepNames = m_case->timeStepStrings();
|
||||
std::vector<QString> categoryNames;
|
||||
for (auto name : timeStepNames)
|
||||
{
|
||||
categoryNames.push_back(name);
|
||||
}
|
||||
m_legendConfig->setNamedCategories(categoryNames);
|
||||
m_legendConfig->setAutomaticRanges(0, categoryNames.size() - 1, 0, categoryNames.size() - 1);
|
||||
}
|
||||
else if (m_categoryProperty->eclipseResultAddress().isValid())
|
||||
{
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case());
|
||||
RigEclipseCaseData* caseData = eclipseCase->eclipseCaseData();
|
||||
CVF_ASSERT(caseData);
|
||||
if (!caseData) return;
|
||||
|
||||
RigCaseCellResultsData* cellResultsData = caseData->results(RiaDefines::MATRIX_MODEL);
|
||||
CVF_ASSERT(cellResultsData);
|
||||
|
||||
double globalMin, globalMax;
|
||||
double globalPosClosestToZero, globalNegClosestToZero;
|
||||
|
||||
cellResultsData->minMaxCellScalarValues(m_categoryProperty->eclipseResultAddress(), globalMin, globalMax);
|
||||
cellResultsData->posNegClosestToZero(
|
||||
m_categoryProperty->eclipseResultAddress(), globalPosClosestToZero, globalNegClosestToZero);
|
||||
|
||||
double localMin, localMax;
|
||||
double localPosClosestToZero, localNegClosestToZero;
|
||||
if (m_categoryProperty->hasDynamicResult() && m_timeStep != -1)
|
||||
{
|
||||
cellResultsData->minMaxCellScalarValues(m_categoryProperty->eclipseResultAddress(), m_timeStep, localMin, localMax);
|
||||
cellResultsData->posNegClosestToZero(
|
||||
m_categoryProperty->eclipseResultAddress(), m_timeStep, localPosClosestToZero, localNegClosestToZero);
|
||||
}
|
||||
else
|
||||
{
|
||||
localMin = globalMin;
|
||||
localMax = globalMax;
|
||||
|
||||
localPosClosestToZero = globalPosClosestToZero;
|
||||
localNegClosestToZero = globalNegClosestToZero;
|
||||
}
|
||||
|
||||
CVF_ASSERT(m_legendConfig);
|
||||
|
||||
m_legendConfig->setClosestToZeroValues(
|
||||
globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero);
|
||||
m_legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax);
|
||||
}
|
||||
parent->qwtPlot()->addOrUpdateCurveSetLegend(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->qwtPlot()->removeCurveSetLegend(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimGridCrossPlotCurveSet::hasCategoryResult() const
|
||||
{
|
||||
return m_categorization == FORMATION_CATEGORIZATION || m_categorization == TIME_CATEGORIZATION || m_categorization == RESULT_CATEGORIZATION;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -547,7 +745,7 @@ void RimGridCrossPlotCurveSet::triggerPlotNameUpdateAndReplot()
|
||||
void RimGridCrossPlotCurveSet::updateCurveNames(bool applyCaseName,
|
||||
bool applyAxisVariables,
|
||||
bool applyTimeStep,
|
||||
bool applyCategories)
|
||||
bool applyCategory)
|
||||
{
|
||||
for (auto curve : m_crossPlotCurves())
|
||||
{
|
||||
@@ -568,16 +766,30 @@ void RimGridCrossPlotCurveSet::updateCurveNames(bool applyCaseName,
|
||||
nameTags += timeStepString();
|
||||
}
|
||||
|
||||
if (applyCategories)
|
||||
if (applyCategory && m_categorization != NO_CATEGORIZATION)
|
||||
{
|
||||
QString categoryName = m_categoryNames[curve->categoryIndex()];
|
||||
if (!categoryName.isEmpty())
|
||||
if (m_categorization == RESULT_CATEGORIZATION)
|
||||
{
|
||||
nameTags += categoryName;
|
||||
std::vector<double> tickValues;
|
||||
m_legendConfig->scalarMapper()->majorTickValues(&tickValues);
|
||||
size_t catIndex = (size_t) curve->categoryIndex();
|
||||
double lowerLimit = tickValues[catIndex];
|
||||
double upperLimit = catIndex + 1u < tickValues.size()
|
||||
? tickValues[catIndex + 1u] : std::numeric_limits<double>::infinity();
|
||||
nameTags += QString("%1 [%2, %3]").arg(categoryTitle()).arg(lowerLimit).arg(upperLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
nameTags += m_legendConfig->categoryNameFromCategoryValue(curve->categoryIndex());
|
||||
}
|
||||
}
|
||||
|
||||
curve->setCustomName(nameTags.join(", "));
|
||||
if (m_categorization != NO_CATEGORIZATION)
|
||||
{
|
||||
curve->setLegendEntryTitle(createAutoName());
|
||||
}
|
||||
|
||||
curve->updateCurveNameAndUpdatePlotLegendAndTitle();
|
||||
}
|
||||
}
|
||||
@@ -631,15 +843,24 @@ void RimGridCrossPlotCurveSet::defineEditorAttribute(const caf::PdmFieldHandle*
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute)
|
||||
{
|
||||
if (field == &m_categoryBinCount)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlotCurveSet::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/)
|
||||
{
|
||||
if (m_categorization() != NO_CATEGORIZATION)
|
||||
{
|
||||
auto myAttr = dynamic_cast<caf::PdmUiSliderEditorAttribute*>(attribute);
|
||||
if (myAttr)
|
||||
{
|
||||
myAttr->m_minimum = 2;
|
||||
myAttr->m_maximum = 50;
|
||||
}
|
||||
uiTreeOrdering.add(m_legendConfig());
|
||||
}
|
||||
|
||||
for (auto curve : m_crossPlotCurves())
|
||||
{
|
||||
uiTreeOrdering.add(curve);
|
||||
}
|
||||
|
||||
uiTreeOrdering.skipRemainingChildren(true);
|
||||
}
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimGridCrossPlotCurveSetNameConfig, "RimGridCrossPlotCurveSetNameConfig");
|
||||
@@ -655,7 +876,7 @@ RimGridCrossPlotCurveSetNameConfig::RimGridCrossPlotCurveSetNameConfig(RimNameCo
|
||||
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", "", "", "");
|
||||
CAF_PDM_InitField(&addCategorization, "AddCategorization", false, "Add Data Categorization", "", "", "");
|
||||
CAF_PDM_InitField(&addCategorization, "AddCategorization", true, "Add Data Categorization", "", "", "");
|
||||
|
||||
setCustomName("");
|
||||
}
|
||||
|
||||
@@ -34,11 +34,13 @@
|
||||
#include <QList>
|
||||
#include <map>
|
||||
|
||||
struct RigEclipseCrossPlotResult;
|
||||
class RimCase;
|
||||
class RimGridCrossPlotCurve;
|
||||
class RimGridView;
|
||||
class RimEclipseCase;
|
||||
class RimEclipseResultDefinition;
|
||||
class RimRegularLegendConfig;
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class QString;
|
||||
@@ -83,8 +85,11 @@ public:
|
||||
|
||||
int indexInPlot() const;
|
||||
QString createAutoName() const override;
|
||||
QString categoryTitle() const;
|
||||
void detachAllCurves();
|
||||
void cellFilterViewUpdated();
|
||||
|
||||
RimRegularLegendConfig* legendConfig();
|
||||
|
||||
std::vector< RimGridCrossPlotCurve*> curves() const;
|
||||
|
||||
@@ -93,12 +98,16 @@ public:
|
||||
QString timeStepString() const;
|
||||
std::vector<QString> categoryStrings() const;
|
||||
|
||||
void updateCurveNames(bool applyCaseName, bool applyAxisVariables, bool applyTimeStep, bool applyCategories);
|
||||
|
||||
void updateCurveNames(bool applyCaseName, bool applyAxisVariables, bool applyTimeStep, bool applyCategory);
|
||||
void updateLegend();
|
||||
bool hasCategoryResult() const;
|
||||
|
||||
protected:
|
||||
void initAfterRead() override;
|
||||
void onLoadDataAndUpdate(bool updateParentPlot);
|
||||
|
||||
void createCurves(const RigEclipseCrossPlotResult& result);
|
||||
|
||||
std::map<int, cvf::UByteArray> calculateCellVisibility(RimEclipseCase* eclipseCase) const;
|
||||
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
@@ -111,6 +120,8 @@ protected:
|
||||
void setDefaults();
|
||||
void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
|
||||
|
||||
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimCase*> m_case;
|
||||
caf::PdmField<int> m_timeStep;
|
||||
@@ -119,11 +130,9 @@ private:
|
||||
caf::PdmChildField<RimEclipseResultDefinition*> m_xAxisProperty;
|
||||
caf::PdmChildField<RimEclipseResultDefinition*> m_yAxisProperty;
|
||||
caf::PdmChildField<RimEclipseResultDefinition*> m_categoryProperty;
|
||||
caf::PdmField<int> m_categoryBinCount;
|
||||
|
||||
caf::PdmChildField<RimGridCrossPlotCurveSetNameConfig*> m_nameConfig;
|
||||
|
||||
caf::PdmChildArrayField<RimGridCrossPlotCurve*> m_crossPlotCurves;
|
||||
|
||||
std::map<int, QString> m_categoryNames;
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user