mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
* 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
372 lines
12 KiB
C++
372 lines
12 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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);
|
|
}
|