#1690 Summary: Import clipboard data from Excel as new curves

This commit is contained in:
Bjørnar Grip Fjær
2017-08-11 11:20:40 +02:00
parent d5d5cedbf5
commit a47c5b5d84
10 changed files with 783 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RicNewSummaryPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFilterFeature.h
${CEE_CURRENT_LIST_DIR}RicPasteAsciiDataToSummaryPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicViewZoomAllFeature.h
${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.h
${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.h
@@ -23,6 +24,7 @@ set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RicNewSummaryPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFilterFeature.cpp
${CEE_CURRENT_LIST_DIR}RicPasteAsciiDataToSummaryPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicViewZoomAllFeature.cpp
${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.cpp
${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.cpp

View File

@@ -93,7 +93,7 @@ void RicNewSummaryPlotFeature::setupActionLook(QAction* actionToSetup)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewSummaryPlotFeature::createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase)
RimSummaryPlot* RicNewSummaryPlotFeature::createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase)
{
RimSummaryPlot* plot = new RimSummaryPlot();
summaryPlotColl->summaryPlots().push_back(plot);
@@ -118,4 +118,6 @@ void RicNewSummaryPlotFeature::createNewSummaryPlot(RimSummaryPlotCollection* su
mainPlotWindow->selectAsCurrentItem(newCurveFilter);
mainPlotWindow->setExpanded(newCurveFilter, true);
}
return plot;
}

View File

@@ -22,6 +22,7 @@
class RimSummaryCase;
class RimSummaryPlotCollection;
class RimSummaryPlot;
//==================================================================================================
///
@@ -31,7 +32,7 @@ class RicNewSummaryPlotFeature : public caf::CmdFeature
CAF_CMD_HEADER_INIT;
public:
static void createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase);
static RimSummaryPlot* createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase);
protected:
// Overrides

View File

@@ -0,0 +1,282 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RicPasteAsciiDataToSummaryPlotFeature.h"
#include "OperationsUsingObjReferences/RicPasteFeatureImpl.h"
#include "RicNewSummaryPlotFeature.h"
#include "RiaLogging.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimAsciiDataCurve.h"
#include "RimSummaryCurveAppearanceCalculator.h"
#include "cafPdmDefaultObjectFactory.h"
#include "cafPdmDocument.h"
#include "cafPdmObjectGroup.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include "cvfColor3.h"
#include <QApplication>
#include <QAction>
#include <QClipboard>
#include <QMimeData>
CAF_CMD_SOURCE_INIT(RicPasteAsciiDataToSummaryPlotFeature, "RicPasteExcelToSummaryPlotFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicPasteAsciiDataToSummaryPlotFeature::isCommandEnabled()
{
caf::PdmObjectHandle* destinationObject = dynamic_cast<caf::PdmObjectHandle*>(caf::SelectionManager::instance()->selectedItem());
RimSummaryPlot* summaryPlot = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlot);
if (!summaryPlot)
{
RimSummaryPlotCollection* summaryPlotCollection = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlotCollection);
if (!summaryPlotCollection)
{
return false;
}
}
return hasPastedText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicPasteAsciiDataToSummaryPlotFeature::onActionTriggered(bool isChecked)
{
caf::PdmObjectHandle* destinationObject = dynamic_cast<caf::PdmObjectHandle*>(caf::SelectionManager::instance()->selectedItem());
RimSummaryPlot* summaryPlot = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlot);
if (!summaryPlot)
{
RimSummaryPlotCollection* summaryPlotCollection = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlotCollection);
if (!summaryPlotCollection)
{
return;
}
summaryPlot = RicNewSummaryPlotFeature::createNewSummaryPlot(summaryPlotCollection, nullptr);
if (!summaryPlot)
{
return;
}
}
QString text = getPastedData();
std::vector<RimAsciiDataCurve*> curves = parseCurves(text);
for (RimAsciiDataCurve* curve : curves)
{
summaryPlot->addAsciiDataCruve(curve);
}
summaryPlot->updateConnectedEditors();
summaryPlot->loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicPasteAsciiDataToSummaryPlotFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setText("Paste Excel Data to Summary Curve");
RicPasteFeatureImpl::setIconAndShortcuts(actionToSetup);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicPasteAsciiDataToSummaryPlotFeature::getPastedData()
{
if (hasPastedText())
{
QClipboard* clipboard = QApplication::clipboard();
return clipboard->text();
}
return QString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicPasteAsciiDataToSummaryPlotFeature::hasPastedText()
{
QClipboard* clipboard = QApplication::clipboard();
const QMimeData* mimeData = clipboard->mimeData();
return mimeData->hasText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimAsciiDataCurve*> RicPasteAsciiDataToSummaryPlotFeature::parseCurves(QString& data)
{
std::vector<RimAsciiDataCurve*> curves;
std::vector<QString> headers;
QTextStream tableData(&data);
{
QString header;
do {
header = tableData.readLine();
} while (header.isEmpty() && !tableData.atEnd());
// No header row found
if (header.isEmpty()) return curves;
QStringList columnHeaders = header.split('\t');
for (size_t i = 1; i < columnHeaders.size(); ++i)
{
headers.push_back(columnHeaders[static_cast<int>(i)]);
}
// No columns found
if (headers.empty()) return curves;
}
size_t numColumns = headers.size();
std::vector<QDateTime> timeSteps;
std::vector< std::vector<double> > values;
values.resize(numColumns);
size_t row = 0;
while (!tableData.atEnd())
{
++row;
QString line = tableData.readLine();
// Skip empty lines
if (line.isEmpty()) continue;
QStringList columns = line.split('\t');
if (columns.size() != numColumns + 1)
{
RiaLogging::warning(QString("Invalid number of columns in row %1").arg(row));
continue;
}
QDateTime date = parseDateString(columns[0]);
if (!date.isValid())
{
RiaLogging::warning(QString("First column of row %1 could not be parsed as a date: %2").arg(row).arg(columns[0]));
continue;
}
timeSteps.push_back(date);
for (size_t col = 1; col < columns.size(); ++col)
{
bool ok;
values[col - 1].push_back(columns[static_cast<int>(col)].toDouble(&ok));
if (!ok)
{
RiaLogging::warning(QString("Could not parse value at row %1 column %2 as double: %3. Defaulting to 0.0").arg(row).arg(col).arg(columns[static_cast<int>(col)]));
}
}
}
std::map< CurveType, std::vector<RimAsciiDataCurve*> > curveToTypeMap;
for (size_t i = 0; i < values.size(); ++i)
{
RimAsciiDataCurve* curve = new RimAsciiDataCurve();
curve->setTimeSteps(timeSteps);
curve->setValues(values[i]);
curve->setTitle(headers[i]);
curveToTypeMap[guessCurveType(headers[i])].push_back(curve);
curves.push_back(curve);
}
for (auto& it : curveToTypeMap)
{
for (int i = 0; i < it.second.size(); ++i)
{
cvf::Color3f color;
switch (it.first)
{
case CURVE_GAS:
color = RimSummaryCurveAppearanceCalculator::cycledRedColor(i);
break;
case CURVE_OIL:
color = RimSummaryCurveAppearanceCalculator::cycledGreenColor(i);
break;
case CURVE_WAT:
color = RimSummaryCurveAppearanceCalculator::cycledBlueColor(i);
break;
default:
color = RimSummaryCurveAppearanceCalculator::cycledNoneRGBBrColor(i);
break;
}
it.second[i]->setColor(color);
}
}
return curves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RicPasteAsciiDataToSummaryPlotFeature::parseDateString(const QString& date)
{
QDateTime parsedDate;
parsedDate = QDateTime::fromString(date, "dd.MM.yyyy hh:mm");
if (parsedDate.isValid()) return parsedDate;
parsedDate = QDateTime::fromString(date, "dd.MM.yyyy");
return parsedDate;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicPasteAsciiDataToSummaryPlotFeature::CurveType RicPasteAsciiDataToSummaryPlotFeature::guessCurveType(const QString& curveName)
{
if (curveName.contains("SW") || curveName.contains("water", Qt::CaseInsensitive))
{
return CURVE_WAT;
}
else if (curveName.contains("oil", Qt::CaseInsensitive))
{
return CURVE_OIL;
}
else if (curveName.contains("gas", Qt::CaseInsensitive))
{
return CURVE_GAS;
}
return CURVE_UNKNOWN;
}

View File

@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "cafPdmPointer.h"
#include <vector>
#include <QDateTime>
class RimSummaryCurve;
class RimSummaryCurveFilter;
class RimAsciiDataCurve;
//==================================================================================================
///
//==================================================================================================
class RicPasteAsciiDataToSummaryPlotFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
enum CurveType
{
CURVE_GAS,
CURVE_OIL,
CURVE_WAT,
CURVE_UNKNOWN,
};
protected:
// Overrides
virtual bool isCommandEnabled() override;
virtual void onActionTriggered( bool isChecked ) override;
virtual void setupActionLook(QAction* actionToSetup) override;
private:
static QString getPastedData();
static bool hasPastedText();
static std::vector<RimAsciiDataCurve*> parseCurves(QString& data);
static QDateTime parseDateString(const QString& date);
static CurveType guessCurveType(const QString& curveName);
};

View File

@@ -5,6 +5,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "2.8.2")
endif()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RimAsciiDataCurve.h
${CEE_CURRENT_LIST_DIR}RimFileSummaryCase.h
${CEE_CURRENT_LIST_DIR}RimGridSummaryCase.h
${CEE_CURRENT_LIST_DIR}RimSummaryCase.h
@@ -22,6 +23,7 @@ ${CEE_CURRENT_LIST_DIR}RimSummaryYAxisProperties.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RimAsciiDataCurve.cpp
${CEE_CURRENT_LIST_DIR}RimFileSummaryCase.cpp
${CEE_CURRENT_LIST_DIR}RimGridSummaryCase.cpp
${CEE_CURRENT_LIST_DIR}RimSummaryCase.cpp

View File

@@ -0,0 +1,237 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RimAsciiDataCurve.h"
#include "RiaApplication.h"
#include "RifReaderEclipseSummary.h"
#include "RigSummaryCaseData.h"
#include "RimDefines.h"
#include "RimEclipseResultCase.h"
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryFilter.h"
#include "RimSummaryPlot.h"
#include "RimSummaryTimeAxisProperties.h"
#include "RiuLineSegmentQwtPlotCurve.h"
#include "RiuSummaryQwtPlot.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "qwt_date.h"
CAF_PDM_SOURCE_INIT(RimAsciiDataCurve, "AsciiDataCurve");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimAsciiDataCurve::RimAsciiDataCurve()
{
CAF_PDM_InitObject("ASCII Data Curve", ":/SummaryCurve16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_plotAxis, "PlotAxis", "Axis", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_timeSteps, "TimeSteps", "Time Steps", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_values, "Values", "Values", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_title, "Title", "Title", "", "", "");
m_symbolSkipPixelDistance = 10.0f;
m_curveThickness = 2;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimAsciiDataCurve::~RimAsciiDataCurve()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimAsciiDataCurve::yValues() const
{
return m_values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RimAsciiDataCurve::timeSteps() const
{
static std::vector<time_t> timeSteps;
timeSteps.clear();
for (const QDateTime& dateTime : m_timeSteps())
{
timeSteps.push_back(dateTime.toTime_t());
}
return timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setYAxis(RimDefines::PlotAxis plotAxis)
{
m_plotAxis = plotAxis;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimDefines::PlotAxis RimAsciiDataCurve::yAxis() const
{
return m_plotAxis();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimAsciiDataCurve::createCurveAutoName()
{
return m_title();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::updateZoomInParentPlot()
{
RimSummaryPlot* plot = nullptr;
firstAncestorOrThisOfType(plot);
plot->updateZoomInQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::onLoadDataAndUpdate()
{
this->RimPlotCurve::updateCurvePresentation();
if (isCurveVisible())
{
std::vector<time_t> dateTimes = this->timeSteps();
std::vector<double> values = this->yValues();
RimSummaryPlot* plot = nullptr;
firstAncestorOrThisOfType(plot);
bool isLogCurve = plot->isLogarithmicScaleEnabled(this->yAxis());
if (dateTimes.size() > 0 && dateTimes.size() == values.size())
{
if (plot->timeAxisProperties()->timeMode() == RimSummaryTimeAxisProperties::DATE)
{
m_qwtPlotCurve->setSamplesFromTimeTAndValues(dateTimes, values, isLogCurve);
}
else
{
double timeScale = plot->timeAxisProperties()->fromTimeTToDisplayUnitScale();
std::vector<double> times;
if ( dateTimes.size() )
{
time_t startDate = dateTimes[0];
for ( time_t& date: dateTimes )
{
times.push_back(timeScale*(date - startDate));
}
}
m_qwtPlotCurve->setSamplesFromTimeAndValues(times, values, isLogCurve);
}
}
else
{
m_qwtPlotCurve->setSamplesFromTimeTAndValues(std::vector<time_t>(), std::vector<double>(), isLogCurve);
}
updateZoomInParentPlot();
if (m_parentQwtPlot) m_parentQwtPlot->replot();
}
updateQwtPlotAxis();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::updateQwtPlotAxis()
{
if (m_qwtPlotCurve)
{
if (this->yAxis() == RimDefines::PLOT_AXIS_LEFT)
{
m_qwtPlotCurve->setYAxis(QwtPlot::yLeft);
}
else
{
m_qwtPlotCurve->setYAxis(QwtPlot::yRight);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setTimeSteps(const std::vector<QDateTime>& timeSteps)
{
m_timeSteps = timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setValues(const std::vector<double>& values)
{
m_values = values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setTitle(const QString& title)
{
m_title = title;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimAsciiDataCurve::curveData(std::vector<QDateTime>* timeSteps, std::vector<double>* values) const
{
CVF_ASSERT(timeSteps && values);
*timeSteps = m_timeSteps();
*values = m_values();
return true;
}

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "cafPdmPtrField.h"
#include "cafPdmChildField.h"
#include "RifEclipseSummaryAddress.h"
#include "RimDefines.h"
#include "RimPlotCurve.h"
#include "cafAppEnum.h"
#include <QDateTime>
class RifReaderEclipseSummary;
class RimSummaryCase;
class RimSummaryFilter;
class RiuLineSegmentQwtPlotCurve;
class RimAsciiDataCurveAutoName;
//==================================================================================================
///
///
//==================================================================================================
class RimAsciiDataCurve : public RimPlotCurve
{
CAF_PDM_HEADER_INIT;
public:
RimAsciiDataCurve();
virtual ~RimAsciiDataCurve();
std::vector<double> yValues() const;
const std::vector<time_t>& timeSteps() const;
void setYAxis(RimDefines::PlotAxis plotAxis);
RimDefines::PlotAxis yAxis() const;
void updateQwtPlotAxis();
void setTimeSteps(const std::vector<QDateTime>& timeSteps);
void setValues(const std::vector<double>& values);
void setTitle(const QString& title);
protected:
// RimPlotCurve overrides
virtual QString createCurveAutoName() override;
virtual void updateZoomInParentPlot() override;
virtual void onLoadDataAndUpdate() override;
private:
bool curveData(std::vector<QDateTime>* timeSteps, std::vector<double>* values) const;
private:
// Fields
caf::PdmField< caf::AppEnum< RimDefines::PlotAxis > > m_plotAxis;
caf::PdmField< std::vector<QDateTime> > m_timeSteps;
caf::PdmField< std::vector<double> > m_values;
caf::PdmField< QString > m_title;
};

View File

@@ -28,6 +28,7 @@
#include "RimSummaryPlotCollection.h"
#include "RimSummaryTimeAxisProperties.h"
#include "RimSummaryYAxisProperties.h"
#include "RimAsciiDataCurve.h"
#include "RiuMainPlotWindow.h"
#include "RiuSummaryQwtPlot.h"
@@ -72,6 +73,9 @@ RimSummaryPlot::RimSummaryPlot()
CAF_PDM_InitFieldNoDefault(&m_gridTimeHistoryCurves, "GridTimeHistoryCurves", "", "", "", "");
m_gridTimeHistoryCurves.uiCapability()->setUiTreeHidden(true);
CAF_PDM_InitFieldNoDefault(&m_asciiDataCurves, "AsciiDataCurves", "", "", "", "");
m_asciiDataCurves.uiCapability()->setUiTreeHidden(true);
CAF_PDM_InitFieldNoDefault(&m_leftYAxisProperties, "LeftYAxisProperties", "Left Y Axis", "", "", "");
m_leftYAxisProperties.uiCapability()->setUiTreeHidden(true);
@@ -359,6 +363,68 @@ QString RimSummaryPlot::asciiDataForPlotExport() const
}
}
{
std::vector<std::vector<time_t> > timeSteps;
std::vector<std::vector<std::vector<double> > > allCurveData;
std::vector<std::vector<QString > > allCurveNames;
//Vectors containing cases - curves - data points/curve name
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
if (!curve->isCurveVisible()) continue;
size_t casePosInList = cvf::UNDEFINED_SIZE_T;
if (casePosInList == cvf::UNDEFINED_SIZE_T)
{
std::vector<time_t> curveTimeSteps = curve->timeSteps();
timeSteps.push_back(curveTimeSteps);
std::vector<std::vector<double> > curveDataForCase;
std::vector<double> curveYData = curve->yValues();
curveDataForCase.push_back(curveYData);
allCurveData.push_back(curveDataForCase);
std::vector<QString> curveNamesForCase;
curveNamesForCase.push_back(curve->curveName());
allCurveNames.push_back(curveNamesForCase);
}
else
{
std::vector<double> curveYData = curve->yValues();
allCurveData[casePosInList].push_back(curveYData);
QString curveName = curve->curveName();
allCurveNames[casePosInList].push_back(curveName);
}
}
for (size_t i = 0; i < timeSteps.size(); i++) //cases
{
out += "\n\n";
for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points
{
if (j == 0)
{
out += "Date and time";
for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves
{
out += "\t" + (allCurveNames[i][k]);
}
}
out += "\n";
out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss ");
for (size_t k = 0; k < allCurveData[i].size(); k++) // curves
{
out += "\t" + QString::number(allCurveData[i][k][j], 'g', 6);
}
}
}
}
return out;
}
@@ -691,6 +757,21 @@ void RimSummaryPlot::addGridTimeHistoryCurve(RimGridTimeHistoryCurve* curve)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::addAsciiDataCruve(RimAsciiDataCurve* curve)
{
CVF_ASSERT(curve);
m_asciiDataCurves.push_back(curve);
if (m_qwtPlot)
{
curve->setParentQwtPlot(m_qwtPlot);
this->updateAxes();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -742,6 +823,7 @@ void RimSummaryPlot::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering
uiTreeOrdering.add(&m_curveFilters);
uiTreeOrdering.add(&m_summaryCurves);
uiTreeOrdering.add(&m_gridTimeHistoryCurves);
uiTreeOrdering.add(&m_asciiDataCurves);
uiTreeOrdering.skipRemainingChildren(true);
}
@@ -768,6 +850,11 @@ void RimSummaryPlot::loadDataAndUpdate()
curve->loadDataAndUpdate();
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->loadDataAndUpdate();
}
this->updateAxes();
updateZoomInQwt();
@@ -867,6 +954,11 @@ QWidget* RimSummaryPlot::createViewWidget(QWidget* mainWindowParent)
{
curve->setParentQwtPlot(m_qwtPlot);
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->setParentQwtPlot(m_qwtPlot);
}
}
return m_qwtPlot;
@@ -937,6 +1029,11 @@ void RimSummaryPlot::detachAllCurves()
{
curve->detachQwtCurve();
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->detachQwtCurve();
}
}
//--------------------------------------------------------------------------------------------------
@@ -960,6 +1057,14 @@ caf::PdmObject* RimSummaryPlot::findRimCurveFromQwtCurve(const QwtPlotCurve* qwt
}
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
if (curve->qwtPlotCurve() == qwtCurve)
{
return curve;
}
}
for (RimSummaryCurveFilter* curveFilter: m_curveFilters)
{
RimSummaryCurve* foundCurve = curveFilter->findRimCurveFromQwtCurve(qwtCurve);
@@ -974,7 +1079,7 @@ caf::PdmObject* RimSummaryPlot::findRimCurveFromQwtCurve(const QwtPlotCurve* qwt
//--------------------------------------------------------------------------------------------------
size_t RimSummaryPlot::curveCount() const
{
return m_summaryCurves.size() + m_gridTimeHistoryCurves.size();
return m_summaryCurves.size() + m_gridTimeHistoryCurves.size() + m_asciiDataCurves.size();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -36,6 +36,7 @@ class RimSummaryCurveFilter;
class RimSummaryYAxisProperties;
class RimSummaryTimeAxisProperties;
class RimGridTimeHistoryCurve;
class RimAsciiDataCurve;
class PdmUiTreeOrdering;
class QwtPlotCurve;
@@ -61,6 +62,8 @@ public:
void addGridTimeHistoryCurve(RimGridTimeHistoryCurve* curve);
void addAsciiDataCruve(RimAsciiDataCurve* curve);
caf::PdmObject* findRimCurveFromQwtCurve(const QwtPlotCurve* curve) const;
size_t curveCount() const;
@@ -125,6 +128,7 @@ private:
caf::PdmChildArrayField<RimGridTimeHistoryCurve*> m_gridTimeHistoryCurves;
caf::PdmChildArrayField<RimSummaryCurve*> m_summaryCurves;
caf::PdmChildArrayField<RimSummaryCurveFilter*> m_curveFilters;
caf::PdmChildArrayField<RimAsciiDataCurve*> m_asciiDataCurves;
caf::PdmField<bool> m_isAutoZoom;
caf::PdmChildField<RimSummaryYAxisProperties*> m_leftYAxisProperties;