#4185 Implement data export for Grid Cross Plot

This commit is contained in:
Gaute Lindkvist 2019-03-11 11:39:23 +01:00
parent 6008b8a45d
commit e72f57072c
15 changed files with 432 additions and 134 deletions

View File

@ -20,6 +20,9 @@
#include "RiaApplication.h"
#include "RimGridCrossPlot.h"
#include "RimGridCrossPlotCurve.h"
#include "RimGridCrossPlotCurveSet.h"
#include "RimProject.h"
#include "RimSummaryCrossPlot.h"
#include "RimSummaryPlot.h"
@ -28,6 +31,8 @@
#include "RiuPlotMainWindow.h"
#include "RiuTextDialog.h"
#include "cafPdmPointer.h"
#include "cafProgressInfo.h"
#include "cafSelectionManagerTools.h"
#include <QAction>
@ -35,6 +40,128 @@
CAF_CMD_SOURCE_INIT(RicShowPlotDataFeature, "RicShowPlotDataFeature");
//--------------------------------------------------------------------------------------------------
/// Private text provider class for summary plots
//--------------------------------------------------------------------------------------------------
class RiuTabbedSummaryPlotTextProvider : public RiuTabbedTextProvider
{
public:
RiuTabbedSummaryPlotTextProvider(RimSummaryPlot* summaryPlot)
: m_summaryPlot(summaryPlot)
{
}
virtual bool isValid() const override
{
return m_summaryPlot.notNull();
}
QString description() const override
{
CVF_ASSERT(m_summaryPlot.notNull() && "Need to check that provider is valid");
return m_summaryPlot->description();
}
QString tabTitle(int tabIndex) const override
{
auto allTabs = tabs();
CVF_ASSERT(tabIndex < (int)allTabs.size());
DateTimePeriod timePeriod = allTabs[tabIndex];
if (timePeriod == DateTimePeriod::NONE)
{
return "No Resampling";
}
else
{
return QString("Plot Data, %1").arg(RiaQDateTimeTools::dateTimePeriodName(timePeriod));
}
}
QString tabText(int tabIndex) const override
{
CVF_ASSERT(m_summaryPlot.notNull() && "Need to check that provider is valid");
DateTimePeriod timePeriod = indexToPeriod(tabIndex);
if (m_summaryPlot->containsResamplableCurves())
{
return m_summaryPlot->asciiDataForPlotExport(timePeriod);
}
else
{
return m_summaryPlot->asciiDataForPlotExport();
}
}
int tabCount() const override
{
return (int)tabs().size();
}
private:
static DateTimePeriod indexToPeriod(int tabIndex)
{
auto allTabs = tabs();
CVF_ASSERT(tabIndex < (int)allTabs.size());
DateTimePeriod timePeriod = allTabs[tabIndex];
return timePeriod;
}
static std::vector<DateTimePeriod> tabs()
{
std::vector<DateTimePeriod> dateTimePeriods = RiaQDateTimeTools::dateTimePeriods();
dateTimePeriods.erase(std::remove(dateTimePeriods.begin(), dateTimePeriods.end(), DateTimePeriod::DECADE),
dateTimePeriods.end());
return dateTimePeriods;
}
private:
caf::PdmPointer<RimSummaryPlot> m_summaryPlot;
};
//--------------------------------------------------------------------------------------------------
/// Private text provider class for grid cross plots
//--------------------------------------------------------------------------------------------------
class RiuTabbedGridCrossPlotTextProvider : public RiuTabbedTextProvider
{
public:
RiuTabbedGridCrossPlotTextProvider(RimGridCrossPlot* crossPlot)
: m_crossPlot(crossPlot)
{
}
virtual bool isValid() const override
{
return m_crossPlot.notNull();
}
virtual QString description() const override
{
CVF_ASSERT(m_crossPlot.notNull() && "Need to check that provider is valid");
return m_crossPlot->createAutoName();
}
virtual QString tabTitle(int tabIndex) const override
{
CVF_ASSERT(m_crossPlot.notNull() && "Need to check that provider is valid");
return m_crossPlot->asciiTitleForPlotExport(tabIndex);
}
virtual QString tabText(int tabIndex) const override
{
CVF_ASSERT(m_crossPlot.notNull() && "Need to check that provider is valid");
return m_crossPlot->asciiDataForPlotExport(tabIndex);
}
virtual int tabCount() const override
{
CVF_ASSERT(m_crossPlot.notNull() && "Need to check that provider is valid");
return (int)m_crossPlot->curveSets().size();
}
private:
caf::PdmPointer<RimGridCrossPlot> m_crossPlot;
};
//--------------------------------------------------------------------------------------------------
///
@ -62,6 +189,9 @@ bool RicShowPlotDataFeature::isCommandEnabled()
auto wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
if (wellLogPlots.size() > 0) return true;
auto gridCrossPlots = caf::selectedObjectsByType<RimGridCrossPlot*>();
if (gridCrossPlots.size() > 0) return true;
return false;
}
@ -72,10 +202,10 @@ void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
{
this->disableModelChangeContribution();
std::vector<RimSummaryPlot*> selectedSummaryPlots = caf::selectedObjectsByType<RimSummaryPlot*>();
std::vector<RimWellLogPlot*> wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
if (selectedSummaryPlots.size() == 0 && wellLogPlots.size() == 0)
std::vector<RimSummaryPlot*> selectedSummaryPlots = caf::selectedObjectsByType<RimSummaryPlot*>();
std::vector<RimWellLogPlot*> wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
std::vector<RimGridCrossPlot*> crossPlots = caf::selectedObjectsByType<RimGridCrossPlot*>();
if (selectedSummaryPlots.size() == 0 && wellLogPlots.size() == 0 && crossPlots.size() == 0)
{
CVF_ASSERT(false);
@ -87,26 +217,22 @@ void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
for (RimSummaryPlot* summaryPlot : selectedSummaryPlots)
{
QString title = summaryPlot->description();
if (summaryPlot->containsResamplableCurves())
{
RicShowPlotDataFeature::showTabbedTextWindow(title, [summaryPlot](DateTimePeriod period) { return summaryPlot->asciiDataForPlotExport(period); });
}
else
{
QString text = summaryPlot->asciiDataForPlotExport();
RicShowPlotDataFeature::showTextWindow(title, text);
}
auto textProvider = new RiuTabbedSummaryPlotTextProvider(summaryPlot);
RicShowPlotDataFeature::showTabbedTextWindow(textProvider);
}
for (RimWellLogPlot* wellLogPlot : wellLogPlots)
{
QString title = wellLogPlot->description();
QString text = wellLogPlot->asciiDataForPlotExport();
RicShowPlotDataFeature::showTextWindow(title, text);
}
for (RimGridCrossPlot* crossPlot : crossPlots)
{
auto textProvider = new RiuTabbedGridCrossPlotTextProvider(crossPlot);
RicShowPlotDataFeature::showTabbedTextWindow(textProvider);
}
}
//--------------------------------------------------------------------------------------------------
@ -118,24 +244,19 @@ void RicShowPlotDataFeature::setupActionLook(QAction* actionToSetup)
actionToSetup->setIcon(QIcon(":/PlotWindow24x24.png"));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowPlotDataFeature::showTabbedTextWindow(const QString& title, std::function<QString(DateTimePeriod)> textProvider)
void RicShowPlotDataFeature::showTabbedTextWindow(RiuTabbedTextProvider* textProvider)
{
RiuPlotMainWindow* plotwindow = RiaApplication::instance()->mainPlotWindow();
CVF_ASSERT(plotwindow);
RiuShowTabbedPlotDataDialog* textWidget = new RiuShowTabbedPlotDataDialog();
RiuTabbedTextDialog* textWidget = new RiuTabbedTextDialog(textProvider);
textWidget->setMinimumSize(800, 600);
textWidget->setWindowTitle(title);
textWidget->setDescription(title);
textWidget->setTextProvider(textProvider);
textWidget->show();
plotwindow->addToTemporaryWidgets(textWidget);
textWidget->show();
textWidget->redrawText();
}
//--------------------------------------------------------------------------------------------------

View File

@ -24,6 +24,8 @@
#include <functional>
class RiuTabbedTextProvider;
//==================================================================================================
///
//==================================================================================================
@ -38,7 +40,7 @@ protected:
void setupActionLook( QAction* actionToSetup ) override;
public:
static void showTabbedTextWindow(const QString& title, std::function<QString(DateTimePeriod)> textProvider);
static void showTabbedTextWindow(RiuTabbedTextProvider* textProvider);
static void showTextWindow(const QString& title, const QString& text);
};

View File

@ -106,7 +106,7 @@ void RicExportSelectedWellPathsFeature::writeWellPathGeometryToStream(QTextStrea
double endMd = wellPathGeom->measureDepths().back();
RifEclipseDataTableFormatter formatter(stream);
formatter.setCommentPrefix("#");
formatter.setCommentPrefix("# ");
formatter.setTableRowPrependText(" ");
if (writeProjectInfo)

View File

@ -32,7 +32,7 @@ RifEclipseDataTableFormatter::RifEclipseDataTableFormatter(QTextStream& out)
, m_colSpacing(5)
, m_tableRowPrependText(" ")
, m_tableRowAppendText(" /")
, m_commentPrefix("--")
, m_commentPrefix("-- ")
, m_maxDataRowWidth(MAX_ECLIPSE_DATA_ROW_WIDTH)
{
}
@ -154,7 +154,7 @@ void RifEclipseDataTableFormatter::outputBuffer()
{
if (!m_columns.empty() && !isAllHeadersEmpty(m_columns))
{
m_out << m_commentPrefix << " ";
m_out << m_commentPrefix;
for (size_t i = 0u; i < m_columns.size(); ++i)
{
m_out << formatColumn(m_columns[i].title, i);
@ -206,7 +206,7 @@ void RifEclipseDataTableFormatter::outputBuffer()
//--------------------------------------------------------------------------------------------------
void RifEclipseDataTableFormatter::outputComment(RifEclipseOutputTableLine& comment)
{
m_out << m_commentPrefix << " " << comment.data[0] << "\n";
m_out << m_commentPrefix << comment.data[0] << "\n";
}
//--------------------------------------------------------------------------------------------------

View File

@ -17,6 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RimGridCrossPlot.h"
#include "RifEclipseDataTableFormatter.h"
#include "RiuGridCrossQwtPlot.h"
#include "RiuPlotMainWindowTools.h"
#include "RiuQwtPlotTools.h"
@ -28,6 +29,7 @@
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h"
#include "cvfAssert.h"
#include "qwt_legend.h"
@ -520,6 +522,45 @@ void RimGridCrossPlot::swapAllAxisProperties()
loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCrossPlot::asciiTitleForPlotExport(int curveSetIndex) const
{
if ((size_t)curveSetIndex < m_crossPlotCurveSets.size())
{
return m_crossPlotCurveSets[curveSetIndex]->createAutoName();
}
return "Data invalid";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCrossPlot::asciiDataForPlotExport(int curveSetIndex) const
{
if ((size_t)curveSetIndex < m_crossPlotCurveSets.size())
{
QString asciiData;
QTextStream stringStream(&asciiData);
RifEclipseDataTableFormatter formatter(stringStream);
formatter.setCommentPrefix("");
formatter.setTableRowPrependText("");
formatter.setTableRowLineAppendText("");
formatter.setColumnSpacing(3);
m_crossPlotCurveSets[curveSetIndex]->exportFormattedData(formatter);
formatter.tableCompleted();
return asciiData;
}
else
{
return "Data invalid and may have been deleted.";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -70,8 +70,10 @@ public:
void performAutoNameUpdate() override;
void updateCurveNamesAndPlotTitle();
void swapAllAxisProperties();
QString asciiTitleForPlotExport(int curveSetIndex) const;
QString asciiDataForPlotExport(int curveSetIndex) const;
RiuGridCrossQwtPlot* qwtPlot() const;
public:
// Rim2dPlotInterface overrides
void updateAxisScaling() override;
@ -112,6 +114,7 @@ private:
caf::PdmChildArrayField<RimGridCrossPlotCurveSet*> m_crossPlotCurveSets;
QPointer<RiuGridCrossQwtPlot> m_qwtPlot;
};

View File

@ -42,6 +42,7 @@ public:
~RimGridCrossPlotCurve() override = default;
void setGroupingInformation(int curveSetIndex, int groupIndex);
void setSamples(const std::vector<double>& xValues, const std::vector<double>& yValues);
void updateCurveAppearance() override;
int groupIndex() const;

View File

@ -21,6 +21,8 @@
#include "RiaColorTables.h"
#include "RiaLogging.h"
#include "RifEclipseDataTableFormatter.h"
#include "RigActiveCellInfo.h"
#include "RigActiveCellsResultAccessor.h"
#include "RigCaseCellResultCalculator.h"
@ -44,11 +46,14 @@
#include "RimRegularLegendConfig.h"
#include "RimTools.h"
#include "cafCategoryMapper.h"
#include "cafColorTable.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiSliderEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h"
#include "cvfScalarMapper.h"
#include "cvfqtUtils.h"
#include <QString>
@ -210,7 +215,11 @@ QString RimGridCrossPlotCurveSet::createAutoName() const
//--------------------------------------------------------------------------------------------------
QString RimGridCrossPlotCurveSet::groupTitle() const
{
return QString("Grouping by %1").arg(groupParameter());
if (m_grouping != NO_GROUPING)
{
return QString("Grouped by %1").arg(groupParameter());
}
return "";
}
//--------------------------------------------------------------------------------------------------
@ -410,6 +419,7 @@ void RimGridCrossPlotCurveSet::onLoadDataAndUpdate(bool updateParentPlot)
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& result)
{
m_groupedResults.clear();
if (!groupingEnabled())
{
const caf::ColorTable& colors = RiaColorTables::contrastCategoryPaletteColors();
@ -422,11 +432,10 @@ void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& res
curve->updateCurveAppearance();
curve->updateUiIconFromPlotSymbol();
m_crossPlotCurves.push_back(curve);
m_groupedResults[0] = result;
}
else
{
std::map<int, std::pair<std::vector<double>, std::vector<double>>> groupedResults;
std::vector<double> tickValues;
if (groupingByCategoryResult())
@ -438,8 +447,13 @@ void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& res
? static_cast<int>(result.groupValuesContinuous[i])
: result.groupValuesDiscrete[i];
groupedResults[categoryNum].first.push_back(result.xValues[i]);
groupedResults[categoryNum].second.push_back(result.yValues[i]);
m_groupedResults[categoryNum].xValues.push_back(result.xValues[i]);
m_groupedResults[categoryNum].yValues.push_back(result.yValues[i]);
if (!result.groupValuesContinuous.empty())
m_groupedResults[categoryNum].groupValuesContinuous.push_back(result.groupValuesContinuous[i]);
if (!result.groupValuesDiscrete.empty())
m_groupedResults[categoryNum].groupValuesDiscrete.push_back(result.groupValuesDiscrete[i]);
}
}
else
@ -450,13 +464,17 @@ void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& res
{
auto upperBoundIt = std::lower_bound(tickValues.begin(), tickValues.end(), result.groupValuesContinuous[i]);
int upperBoundIndex = static_cast<int>(upperBoundIt - tickValues.begin());
int lowerBoundIndex = std::min((int) tickValues.size() - 2, std::max(0, upperBoundIndex - 1));
groupedResults[lowerBoundIndex].first.push_back(result.xValues[i]);
groupedResults[lowerBoundIndex].second.push_back(result.yValues[i]);
int categoryNum = std::min((int) tickValues.size() - 2, std::max(0, upperBoundIndex - 1));
m_groupedResults[categoryNum].xValues.push_back(result.xValues[i]);
m_groupedResults[categoryNum].yValues.push_back(result.yValues[i]);
if (!result.groupValuesContinuous.empty())
m_groupedResults[categoryNum].groupValuesContinuous.push_back(result.groupValuesContinuous[i]);
if (!result.groupValuesDiscrete.empty())
m_groupedResults[categoryNum].groupValuesDiscrete.push_back(result.groupValuesDiscrete[i]);
}
}
for (auto it = groupedResults.rbegin(); it != groupedResults.rend(); ++it)
for (auto it = m_groupedResults.rbegin(); it != m_groupedResults.rend(); ++it)
{
RimGridCrossPlotCurve* curve = new RimGridCrossPlotCurve();
curve->setGroupingInformation(indexInPlot(), it->first);
@ -468,9 +486,9 @@ void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& res
{
curve->setColor(cvf::Color3f(legendConfig()->scalarMapper()->mapToColor(tickValues[it->first])));
}
curve->setSamples(it->second.first, it->second.second);
curve->setSamples(it->second.xValues, it->second.yValues);
curve->showLegend(m_crossPlotCurves.empty());
curve->setLegendEntryTitle(createAutoName());
curve->setLegendEntryText(createAutoName());
curve->updateCurveAppearance();
curve->updateUiIconFromPlotSymbol();
m_crossPlotCurves.push_back(curve);
@ -478,6 +496,26 @@ void RimGridCrossPlotCurveSet::createCurves(const RigEclipseCrossPlotResult& res
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCrossPlotCurveSet::createGroupName(size_t groupIndex) const
{
if (groupingByCategoryResult())
{
return legendConfig()->categoryNameFromCategoryValue(groupIndex);
}
else
{
std::vector<double> tickValues;
legendConfig()->scalarMapper()->majorTickValues(&tickValues);
double lowerLimit = tickValues[groupIndex];
double upperLimit =
groupIndex + 1u < tickValues.size() ? tickValues[groupIndex + 1u] : std::numeric_limits<double>::infinity();
return QString("%1 [%2, %3]").arg(groupParameter()).arg(lowerLimit).arg(upperLimit);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -786,6 +824,56 @@ void RimGridCrossPlotCurveSet::swapAxisProperties(bool updatePlot)
loadDataAndUpdate(updatePlot);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlotCurveSet::exportFormattedData(RifEclipseDataTableFormatter& formatter) const
{
if (m_groupedResults.empty())
return;
if (m_grouping != NO_GROUPING)
{
std::vector<RifEclipseOutputTableColumn> header = {RifEclipseOutputTableColumn("X"),
RifEclipseOutputTableColumn("Y"),
RifEclipseOutputTableColumn("Group Index"),
RifEclipseOutputTableColumn("Group Description")};
formatter.header(header);
}
else
{
std::vector<RifEclipseOutputTableColumn> header = {RifEclipseOutputTableColumn("X"), RifEclipseOutputTableColumn("Y")};
formatter.header(header);
}
caf::ProgressInfo progress(m_groupedResults.size(), "Gathering Data Points");
for (auto it = m_groupedResults.begin(); it != m_groupedResults.end(); ++it)
{
int groupIndex = it->first;
RigEclipseCrossPlotResult res = it->second;
for (size_t i = 0; i < it->second.xValues.size(); ++i)
{
if (m_grouping() == NO_GROUPING)
{
formatter.add(res.xValues[i]);
formatter.add(res.yValues[i]);
}
else
{
QString groupName = createGroupName(groupIndex);
formatter.add(res.xValues[i]);
formatter.add(res.yValues[i]);
formatter.add(groupIndex);
formatter.add(groupName);
}
formatter.rowCompleted();
}
progress.incrementProgress();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -809,29 +897,17 @@ void RimGridCrossPlotCurveSet::updateCurveNames(size_t curveSetIndex, size_t cur
if (curveSetName.isEmpty())
{
if (curveSetCount > 1u)
curveSetName = QString("Curve #%1").arg(curveSetIndex + 1);
curveSetName = QString("Curve Set #%1").arg(curveSetIndex + 1);
else
curveSetName = "Curve";
curveSetName = "Curve Set";
}
auto curve = m_crossPlotCurves[i];
if (groupingEnabled())
{
if (groupingByCategoryResult())
{
curve->setCustomName(legendConfig()->categoryNameFromCategoryValue(curve->groupIndex()));
}
else
{
std::vector<double> tickValues;
legendConfig()->scalarMapper()->majorTickValues(&tickValues);
size_t catIndex = (size_t) curve->groupIndex();
double lowerLimit = tickValues[catIndex];
double upperLimit = catIndex + 1u < tickValues.size()
? tickValues[catIndex + 1u] : std::numeric_limits<double>::infinity();
curve->setCustomName(QString("%1 [%2, %3]").arg(groupParameter()).arg(lowerLimit).arg(upperLimit));
}
curve->setLegendEntryTitle(curveSetName);
QString curveGroupName = createGroupName(curve->groupIndex());
curve->setCustomName(curveGroupName);
curve->setLegendEntryText(curveSetName);
}
else
{

View File

@ -18,6 +18,7 @@
#pragma once
#include "RigGridCrossPlotCurveGrouping.h"
#include "RigEclipseCrossPlotDataExtractor.h"
#include "RimCheckableNamedObject.h"
#include "RimNameConfig.h"
@ -34,7 +35,7 @@
#include <QList>
#include <map>
struct RigEclipseCrossPlotResult;
class RifEclipseDataTableFormatter;
class RimCase;
class RimGridCrossPlotCurve;
class RimGridView;
@ -114,12 +115,14 @@ public:
bool groupingByCategoryResult() const;
bool groupingEnabled() const;
void swapAxisProperties(bool updatePlot);
void exportFormattedData(RifEclipseDataTableFormatter& formatter) const;
protected:
void initAfterRead() override;
void onLoadDataAndUpdate(bool updateParentPlot);
void createCurves(const RigEclipseCrossPlotResult& result);
QString createGroupName(size_t curveIndex) const;
std::map<int, cvf::UByteArray> calculateCellVisibility(RimEclipseCase* eclipseCase) const;
@ -137,6 +140,7 @@ protected:
bool hasMultipleTimeSteps() const;
private:
caf::PdmPtrField<RimCase*> m_case;
caf::PdmField<int> m_timeStep;
caf::PdmPtrField<RimGridView*> m_cellFilterView;
@ -148,4 +152,6 @@ private:
caf::PdmChildField<RimGridCrossPlotCurveSetNameConfig*> m_nameConfig;
caf::PdmChildArrayField<RimGridCrossPlotCurve*> m_crossPlotCurves;
std::map<int, RigEclipseCrossPlotResult> m_groupedResults;
};

View File

@ -96,8 +96,8 @@ RimPlotCurve::RimPlotCurve()
CAF_PDM_InitFieldNoDefault(&m_customCurveName, "CurveDescription", "Custom Name", "", "", "");
m_customCurveName.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_legendEntryTitle, "LegendDescription", "Legend Name", "", "", "");
m_legendEntryTitle.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_legendEntryText, "LegendDescription", "Legend Name", "", "", "");
m_legendEntryText.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_isUsingAutoName, "AutoName", true, "Auto Name", "", "", "");
@ -219,9 +219,21 @@ void RimPlotCurve::setCustomName(const QString& customName)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotCurve::setLegendEntryTitle(const QString& legendEntryTitle)
QString RimPlotCurve::legendEntryText() const
{
m_legendEntryTitle = legendEntryTitle;
if (!m_legendEntryText().isEmpty())
{
return m_legendEntryText;
}
return m_customCurveName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotCurve::setLegendEntryText(const QString& legendEntryText)
{
m_legendEntryText = legendEntryText;
}
//--------------------------------------------------------------------------------------------------
@ -378,9 +390,9 @@ void RimPlotCurve::updateCurveName()
m_curveName = m_customCurveName;
}
if (!m_legendEntryTitle().isEmpty())
if (!m_legendEntryText().isEmpty())
{
m_qwtPlotCurve->setTitle(m_legendEntryTitle);
m_qwtPlotCurve->setTitle(m_legendEntryText);
}
else
{

View File

@ -78,7 +78,8 @@ public:
QString curveName() const { return m_curveName; }
virtual QString curveExportDescription(const RifEclipseSummaryAddress& address = RifEclipseSummaryAddress()) const { return m_curveName; }
void setCustomName(const QString& customName);
void setLegendEntryTitle(const QString& legendEntryTitle);
QString legendEntryText() const;
void setLegendEntryText(const QString& legendEntryText);
void updateCurveVisibility(bool updateParentPlot);
void updateLegendEntryVisibilityAndPlotLegend();
@ -127,7 +128,7 @@ protected:
caf::PdmField<bool> m_showLegend;
QString m_symbolLabel;
caf::PdmField<int> m_symbolSize;
caf::PdmField<QString> m_legendEntryTitle;
caf::PdmField<QString> m_legendEntryText;
caf::PdmField<bool> m_isUsingAutoName;
caf::PdmField<cvf::Color3f> m_curveColor;

View File

@ -24,8 +24,11 @@
#include "RimGridCrossPlotCurveSet.h"
#include "RimRegularLegendConfig.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafSelectionManager.h"
#include "cafTitledOverlayFrame.h"
#include <QMenu>
#include <QResizeEvent>
//--------------------------------------------------------------------------------------------------
@ -207,3 +210,24 @@ bool RiuGridCrossQwtPlot::resizeOverlayItemToFitPlot(caf::TitledOverlayFrame* ov
overlayItem->setRenderSize(legendSize);
return sizeAltered;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::contextMenuEvent(QContextMenuEvent* event)
{
QMenu menu;
caf::CmdFeatureMenuBuilder menuBuilder;
caf::SelectionManager::instance()->setSelectedItem(ownerViewWindow());
menuBuilder << "RicShowPlotDataFeature";
menuBuilder.appendToMenu(&menu);
if (menu.actions().size() > 0)
{
menu.exec(event->globalPos());
}
}

View File

@ -52,6 +52,7 @@ protected:
void updateLegendLayout();
void resizeEvent(QResizeEvent *e) override;
bool resizeOverlayItemToFitPlot(caf::TitledOverlayFrame* overlayItem);
void contextMenuEvent(QContextMenuEvent*) override;
private:
std::map<caf::PdmPointer<RimGridCrossPlotCurveSet>, QPointer<RiuCvfOverlayItemWidget>> m_legendWidgets;
};

View File

@ -101,12 +101,12 @@ void RiuQPlainTextEdit::slotSelectAll()
void RiuQPlainTextEdit::slotExportToFile()
{
// Get dialog
RiuShowTabbedPlotDataDialog* dialog = nullptr;
RiuTabbedTextDialog* dialog = nullptr;
auto curr = parent();
while (dialog == nullptr)
{
if (!curr) break;
dialog = dynamic_cast<RiuShowTabbedPlotDataDialog*>(curr);
dialog = dynamic_cast<RiuTabbedTextDialog*>(curr);
if (dialog) break;
curr = curr->parent();
}
@ -190,21 +190,19 @@ void RiuTextDialog::contextMenuEvent(QContextMenuEvent* event)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuShowTabbedPlotDataDialog::RiuShowTabbedPlotDataDialog(QWidget* parent /*= nullptr*/)
: QDialog(parent, RiuTools::defaultDialogFlags())
RiuTabbedTextDialog::RiuTabbedTextDialog(RiuTabbedTextProvider* textProvider, QWidget* parent /*= nullptr*/)
: m_textProvider(textProvider), QDialog(parent, RiuTools::defaultDialogFlags())
{
m_tabWidget = new QTabWidget(this);
connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotTabChanged(int)));
for(auto timePeriod : RiaQDateTimeTools::dateTimePeriods())
CVF_ASSERT(m_textProvider->isValid());
this->setWindowTitle(m_textProvider->description());
for (int tabIndex = 0; tabIndex < m_textProvider->tabCount(); ++tabIndex)
{
if(timePeriod == DateTimePeriod::DECADE) continue;
QString tabTitle =
timePeriod == DateTimePeriod::NONE ? "No Resampling" :
QString("Plot Data, %1").arg(RiaQDateTimeTools::dateTimePeriodName(timePeriod));
QString tabTitle = m_textProvider->tabTitle(tabIndex);
RiuQPlainTextEdit* textEdit = new RiuQPlainTextEdit();
textEdit->setReadOnly(true);
textEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
@ -218,43 +216,56 @@ RiuShowTabbedPlotDataDialog::RiuShowTabbedPlotDataDialog(QWidget* parent /*= nul
m_tabWidget->addTab(textEdit, tabTitle);
}
m_tabTexts.resize(m_textProvider->tabCount());
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(m_tabWidget);
setLayout(layout);
updateTabText();
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RiuShowTabbedPlotDataDialog::setDescription(const QString& description)
QString RiuTabbedTextDialog::description() const
{
m_description = description;
if (m_textProvider && m_textProvider->isValid())
{
return m_textProvider->description();
}
else
{
return "Data Invalid";
}
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
QString RiuShowTabbedPlotDataDialog::description() const
void RiuTabbedTextDialog::redrawText()
{
if (m_description.isEmpty()) return "Plot Data";
return m_description;
auto textEdit = currentTextEdit();
auto currIndex = m_tabWidget->currentIndex();
textEdit->setPlainText("Populating Text View...");
textEdit->repaint();
if (currIndex < (int)m_tabTexts.size())
{
if (m_tabTexts[currIndex].isEmpty())
{
updateTabText();
}
textEdit->setPlainText(m_tabTexts[currIndex]);
textEdit->repaint();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuShowTabbedPlotDataDialog::setTextProvider(std::function<QString(DateTimePeriod)> textProvider)
{
m_textProvider = textProvider;
updateText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQPlainTextEdit * RiuShowTabbedPlotDataDialog::currentTextEdit() const
RiuQPlainTextEdit * RiuTabbedTextDialog::currentTextEdit() const
{
return dynamic_cast<RiuQPlainTextEdit*>(m_tabWidget->currentWidget());
}
@ -262,44 +273,32 @@ RiuQPlainTextEdit * RiuShowTabbedPlotDataDialog::currentTextEdit() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
DateTimePeriod RiuShowTabbedPlotDataDialog::indexToPeriod(int index)
{
auto currTabTitle = m_tabWidget->tabText(index);
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_DAY_NAME)) return DateTimePeriod::DAY;
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_WEEK_NAME)) return DateTimePeriod::WEEK;
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_MONTH_NAME)) return DateTimePeriod::MONTH;
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_QUARTER_NAME)) return DateTimePeriod::QUARTER;
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_HALFYEAR_NAME)) return DateTimePeriod::HALFYEAR;
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_YEAR_NAME)) return DateTimePeriod::YEAR;
if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_DECADE_NAME)) return DateTimePeriod::DECADE;
return DateTimePeriod::NONE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuShowTabbedPlotDataDialog::updateText()
{
auto textEdit = currentTextEdit();
void RiuTabbedTextDialog::updateTabText()
{
auto currIndex = m_tabWidget->currentIndex();
if (textEdit && textEdit->toPlainText().isEmpty() && m_textProvider)
if (m_textProvider && m_textProvider->isValid() &&
m_tabWidget->tabText(currIndex) == m_textProvider->tabTitle(currIndex))
{
textEdit->setPlainText(m_textProvider(indexToPeriod(currIndex)));
m_tabTexts[currIndex] = m_textProvider->tabText(currIndex);
}
else
{
m_tabTexts[currIndex] = "Data Source No Longer Valid";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuShowTabbedPlotDataDialog::slotTabChanged(int index)
void RiuTabbedTextDialog::slotTabChanged(int index)
{
updateText();
redrawText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuShowTabbedPlotDataDialog::contextMenuEvent(QContextMenuEvent* event)
void RiuTabbedTextDialog::contextMenuEvent(QContextMenuEvent* event)
{
QMenu menu;
RiuQPlainTextEdit* textEdit = dynamic_cast<RiuQPlainTextEdit*>(m_tabWidget->currentWidget());

View File

@ -22,6 +22,7 @@
#include <QDialog>
#include <QPlainTextEdit>
#include <QPointer>
#include <functional>
@ -67,28 +68,38 @@ protected:
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiuShowTabbedPlotDataDialog : public QDialog
class RiuTabbedTextProvider : public QObject
{
Q_OBJECT
public:
explicit RiuShowTabbedPlotDataDialog(QWidget* parent = nullptr);
virtual bool isValid() const = 0;
virtual QString description() const = 0;
virtual QString tabTitle(int tabIndex) const = 0;
virtual QString tabText(int tabIndex) const = 0;
virtual int tabCount() const = 0;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiuTabbedTextDialog : public QDialog
{
Q_OBJECT
public:
explicit RiuTabbedTextDialog(RiuTabbedTextProvider* textProvider, QWidget* parent = nullptr);
void setDescription(const QString& description);
QString description() const;
void setTextProvider(std::function<QString (DateTimePeriod)> textProvider);
void redrawText();
private:
RiuQPlainTextEdit * currentTextEdit() const;
DateTimePeriod indexToPeriod(int index);
void updateText();
RiuQPlainTextEdit* currentTextEdit() const;
void updateTabText();
QTabWidget* m_tabWidget;
QString m_description;
std::function<QString(DateTimePeriod)> m_textProvider;
QTabWidget* m_tabWidget;
QPointer<RiuTabbedTextProvider> m_textProvider;
std::vector<QString> m_tabTexts;
private slots:
void slotTabChanged(int index);