///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RiuResultQwtPlot.h" #include "RiaApplication.h" #include "RiaCurveDataTools.h" #include "RiaPreferences.h" #include "RiaQDateTimeTools.h" #include "RimCase.h" #include "RimContextCommandBuilder.h" #include "RiuQwtPlotCurve.h" #include "RiuQwtPlotTools.h" #include "RiuTextDialog.h" #include "cafCmdFeatureMenuBuilder.h" #include "cvfColor3.h" #include "qwt_date_scale_draw.h" #include "qwt_date_scale_engine.h" #include "qwt_legend.h" #include "qwt_plot_curve.h" #include "qwt_plot_grid.h" #include "qwt_plot_layout.h" #include "qwt_scale_engine.h" #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RiuResultQwtPlot::RiuResultQwtPlot( QWidget* parent ) : RiuDockedQwtPlot( parent ) { setAutoFillBackground( true ); setDefaults(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RiuResultQwtPlot::~RiuResultQwtPlot() { deleteAllCurves(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::addCurve( const RimCase* rimCase, const QString& curveName, const cvf::Color3f& curveColor, const std::vector& dateTimes, const std::vector& timeHistoryValues ) { if ( dateTimes.empty() || timeHistoryValues.empty() ) { return; } RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve( nullptr, "Curve 1" ); plotCurve->setSamplesFromDatesAndYValues( dateTimes, timeHistoryValues, false ); plotCurve->setTitle( curveName ); plotCurve->setPen( QPen( QColor( curveColor.rByte(), curveColor.gByte(), curveColor.bByte() ) ) ); plotCurve->attach( this ); m_plotCurves.push_back( plotCurve ); this->setAxisScale( QwtAxis::XTop, QwtDate::toDouble( dateTimes.front() ), QwtDate::toDouble( dateTimes.back() ) ); this->applyFontSizes( false ); this->replot(); int caseId = rimCase->caseId(); m_caseNames[caseId] = rimCase->caseUserDescription(); m_curveNames[caseId].push_back( curveName ); m_curveData[caseId].push_back( timeHistoryValues ); m_timeSteps[caseId] = dateTimes; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::addCurve( const RimCase* rimCase, const QString& curveName, const cvf::Color3f& curveColor, const std::vector& frameTimes, const std::vector& timeHistoryValues ) { std::vector dateTimes; for ( double frameTime : frameTimes ) { dateTimes.push_back( QwtDate::toDateTime( frameTime ) ); } addCurve( rimCase, curveName, curveColor, dateTimes, timeHistoryValues ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::deleteAllCurves() { for ( size_t i = 0; i < m_plotCurves.size(); i++ ) { m_plotCurves[i]->detach(); delete m_plotCurves[i]; } m_plotCurves.clear(); m_caseNames.clear(); m_curveNames.clear(); m_curveData.clear(); m_timeSteps.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QSize RiuResultQwtPlot::sizeHint() const { return QSize( 100, 100 ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QSize RiuResultQwtPlot::minimumSizeHint() const { return QSize( 0, 0 ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::contextMenuEvent( QContextMenuEvent* event ) { QMenu menu; caf::CmdFeatureMenuBuilder menuBuilder; menuBuilder << "RicNewGridTimeHistoryCurveFeature"; const int curveCount = this->itemList( QwtPlotItem::Rtti_PlotCurve ).count(); QAction* act = menu.addAction( "Show Plot Data", this, SLOT( slotCurrentPlotDataInTextDialog() ) ); act->setEnabled( curveCount > 0 ); menuBuilder.appendToMenu( &menu ); if ( !menu.actions().empty() ) { menu.exec( event->globalPos() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::setDefaults() { RiuQwtPlotTools::setCommonPlotBehaviour( this ); setAxesCount( QwtAxis::XBottom, 1 ); setAxesCount( QwtAxis::YLeft, 1 ); QString dateFormat = RiaPreferences::current()->dateFormat(); QString timeFormat = RiaPreferences::current()->timeFormat(); RiuQwtPlotTools::enableDateBasedBottomXAxis( this, dateFormat, timeFormat ); setAxisMaxMinor( QwtAxis::XBottom, 2 ); setAxisMaxMinor( QwtAxis::YLeft, 3 ); applyFontSizes( false ); // The legend will be deleted in the destructor of the plot or when // another legend is inserted. QwtLegend* legend = new QwtLegend( this ); this->insertLegend( legend, BottomLegend ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RiuResultQwtPlot::asciiDataForUiSelectedCurves() const { QString out; for ( std::pair caseIdAndName : m_caseNames ) { int caseId = caseIdAndName.first; out += "Case: " + caseIdAndName.second; out += "\n"; for ( size_t i = 0; i < m_timeSteps.at( caseId ).size(); i++ ) // time steps & data points { if ( i == 0 ) { out += "Date and time"; for ( QString curveName : m_curveNames.at( caseId ) ) { out += "\t" + curveName; } } out += "\n"; QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale( m_timeSteps.at( caseId )[i], "yyyy-MM-dd hh:mm:ss " ); out += dateString; for ( size_t j = 0; j < m_curveData.at( caseId ).size(); j++ ) // curves { out += "\t" + QString::number( m_curveData.at( caseId )[j][i], 'g', 6 ); } } out += "\n\n"; } return out; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuResultQwtPlot::slotCurrentPlotDataInTextDialog() { QString outTxt = asciiDataForUiSelectedCurves(); RiuTextDialog* textDialog = new RiuTextDialog( this ); textDialog->setMinimumSize( 400, 600 ); textDialog->setWindowTitle( "Result Plot Data" ); textDialog->setText( outTxt ); textDialog->show(); }