From fe5a7d9afba2aee177e9f84d31803dd268fce48e Mon Sep 17 00:00:00 2001
From: rinkk <karsten.rink@ufz.de>
Date: Thu, 2 Aug 2018 11:19:27 +0200
Subject: [PATCH] fixed issue with limiting the date range on time series data

---
 .../DataView/DiagramView/DiagramList.cpp      | 59 +++++++++------
 .../DataView/DiagramView/DiagramList.h        | 11 ++-
 .../DataView/DiagramView/DiagramPrefs.ui      | 15 +++-
 .../DiagramView/DiagramPrefsDialog.cpp        | 72 ++++++++++---------
 .../DataView/DiagramView/DiagramScene.cpp     | 26 +++----
 .../DataView/DiagramView/DiagramScene.h       |  4 +-
 .../DataView/DiagramView/QArrow.cpp           |  9 +--
 .../DataView/DiagramView/QArrow.h             | 16 ++---
 8 files changed, 124 insertions(+), 88 deletions(-)

diff --git a/Applications/DataExplorer/DataView/DiagramView/DiagramList.cpp b/Applications/DataExplorer/DataView/DiagramView/DiagramList.cpp
index 8b2ef69a036..0f0b210e50a 100644
--- a/Applications/DataExplorer/DataView/DiagramView/DiagramList.cpp
+++ b/Applications/DataExplorer/DataView/DiagramView/DiagramList.cpp
@@ -171,9 +171,6 @@ int DiagramList::readList(const QString &path, std::vector<DiagramList*> &lists)
         }
 
         bool first_loop(true);
-        int numberOfSecs(0);
-        double value(0);
-        QString stringDate("");
         QDateTime startDate, currentDate;
         unsigned line_count (1);
 
@@ -184,7 +181,7 @@ int DiagramList::readList(const QString &path, std::vector<DiagramList*> &lists)
             fields = line.split('\t');
             if (fields.size() >= (nLists + 1))
             {
-                stringDate = fields.takeFirst();
+                QString const stringDate = fields.takeFirst();
                 currentDate = getDateTime(stringDate);
                 if (first_loop)
                 {
@@ -194,15 +191,12 @@ int DiagramList::readList(const QString &path, std::vector<DiagramList*> &lists)
                     first_loop = false;
                 }
 
-                numberOfSecs = startDate.secsTo(currentDate);
-
+                float const numberOfSecs = static_cast<float>(startDate.secsTo(currentDate));
                 for (int i = 0; i < nLists; i++)
                 {
-                    value =
-                        strtod(BaseLib::replaceString(
-                                   ",", ".", fields.takeFirst().toStdString())
-                                   .c_str(),
-                               nullptr);
+                    float const value = static_cast<float>(strtod(
+                        BaseLib::replaceString(",", ".", fields.takeFirst().toStdString()).c_str(),
+                        nullptr));
                     lists[i]->addNextPoint(numberOfSecs,value);
                 }
             }
@@ -268,10 +262,10 @@ int DiagramList::readList(const SensorData* data, std::vector<DiagramList*> &lis
             l->setXUnit("day");
             QDateTime startDate(getDateTime(QString::fromStdString(BaseLib::int2date(time_steps[0]))));
             lists[i]->setStartDate(startDate);
-            int numberOfSecs(0);
             for (std::size_t j = 0; j < nValues; j++)
             {
-                numberOfSecs = startDate.secsTo(getDateTime(QString::fromStdString(BaseLib::int2date(time_steps[j]))));
+                QString const data_str = QString::fromStdString(BaseLib::int2date(time_steps[j]));
+                float numberOfSecs = static_cast<float>(startDate.secsTo(getDateTime(data_str)));
                 lists[i]->addNextPoint(numberOfSecs, (*time_series)[j]);
             }
         }
@@ -279,7 +273,8 @@ int DiagramList::readList(const SensorData* data, std::vector<DiagramList*> &lis
         {
             l->setXUnit("time step");
             for (std::size_t j = 0; j < nValues; j++)
-                lists[i]->addNextPoint(time_steps[j], (*time_series)[j]);
+                lists[i]->addNextPoint(static_cast<float>(time_steps[j]),
+                                       (*time_series)[j]);
         }
 
         lists[i]->update();
@@ -288,19 +283,38 @@ int DiagramList::readList(const SensorData* data, std::vector<DiagramList*> &lis
     return nLists;
 }
 
-void DiagramList::setList(std::vector< std::pair<QDateTime, float> > coords)
+void DiagramList::truncateToRange(QDateTime const& start, QDateTime const& end)
 {
-    int numberOfDays;
+    float start_secs = static_cast<float>(_startDate.secsTo(start));
+    if (start_secs < 0)
+        start_secs = 0;
+    float end_secs = static_cast<float>(_startDate.secsTo(end));
+    if (end_secs < start_secs)
+        end_secs = _coords.back().first;
+
+    if (start_secs == 0 && end_secs == _coords.back().first)
+        return;
+
+    _coords.erase(std::remove_if(_coords.begin(), _coords.end(),
+        [&](std::pair<float, float> const& c){return (c.first<start_secs || c.first>end_secs);}),
+        _coords.end());
+    _startDate = start;
+    for (auto& c : _coords)
+        c.first -= start_secs;
+    update();
+}
 
+void DiagramList::setList(std::vector< std::pair<QDateTime, float> > coords)
+{
     this->_startDate = coords[0].first;
     _coords.emplace_back(0.0f, coords[0].second);
 
     std::size_t nCoords = coords.size();
     for (std::size_t i = 1; i < nCoords; i++)
     {
-        numberOfDays = this->_startDate.daysTo(coords[i].first);
-        _coords.emplace_back(static_cast<float>(numberOfDays),
-                             coords[i].second);
+        _coords.emplace_back(
+            static_cast<float>(_startDate.daysTo(coords[i].first)),
+            coords[i].second);
     }
 
     update();
@@ -334,8 +348,11 @@ void DiagramList::update()
 
 QDateTime DiagramList::getDateTime(QString stringDate)
 {
-    if (stringDate.length() <= 10)
+    if (stringDate.length() == 10)
         return QDateTime::fromString(stringDate, "dd.MM.yyyy");
 
-    return QDateTime::fromString(stringDate, "dd.MM.yyyy.HH.mm.ss");
+    if (stringDate.length() == 19)
+        return QDateTime::fromString(stringDate, "dd.MM.yyyy.HH.mm.ss");
+
+    return QDateTime();
 }
diff --git a/Applications/DataExplorer/DataView/DiagramView/DiagramList.h b/Applications/DataExplorer/DataView/DiagramView/DiagramList.h
index f90ff3642da..734edd39d73 100644
--- a/Applications/DataExplorer/DataView/DiagramView/DiagramList.h
+++ b/Applications/DataExplorer/DataView/DiagramView/DiagramList.h
@@ -107,6 +107,10 @@ public:
 
     /// Adds a point at (x,y) to the list
     void addNextPoint(float x, float y) { _coords.emplace_back(x, y); }
+
+    /// cut list entries not within the given range
+    void truncateToRange(QDateTime const& start, QDateTime const& end);
+
     /// Sets the start date (i.e. the min-value of the x-axis).
     void setStartDate(QDateTime date) { _startDate = date; }
 
@@ -142,6 +146,9 @@ public:
     /// Returns the width of the bounding box of all data points within the list.
     double width() const { return _maxX - _minX; }
 
+    /// Converts string into QDateTime-format
+    static QDateTime getDateTime(QString s);
+
 private:
     /// Returns the minimum x-value of all the data points.
     float calcMinXValue();
@@ -154,9 +161,7 @@ private:
 
     /// Returns the maximum y-value of all the data points.
     float calcMaxYValue();
-
-    static QDateTime getDateTime(QString s);
-
+    
     /**
      * Reads an ASCII file containing the coordinates in the following format:
      *        date (tab) value
diff --git a/Applications/DataExplorer/DataView/DiagramView/DiagramPrefs.ui b/Applications/DataExplorer/DataView/DiagramView/DiagramPrefs.ui
index 19ca90608a4..2d83be760f9 100644
--- a/Applications/DataExplorer/DataView/DiagramView/DiagramPrefs.ui
+++ b/Applications/DataExplorer/DataView/DiagramView/DiagramPrefs.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>267</width>
-    <height>236</height>
+    <width>317</width>
+    <height>244</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -45,7 +45,16 @@
    </item>
    <item>
     <layout class="QGridLayout" name="DateBoundsLayout">
-     <property name="margin">
+     <property name="leftMargin">
+      <number>10</number>
+     </property>
+     <property name="topMargin">
+      <number>10</number>
+     </property>
+     <property name="rightMargin">
+      <number>10</number>
+     </property>
+     <property name="bottomMargin">
       <number>10</number>
      </property>
      <property name="spacing">
diff --git a/Applications/DataExplorer/DataView/DiagramView/DiagramPrefsDialog.cpp b/Applications/DataExplorer/DataView/DiagramView/DiagramPrefsDialog.cpp
index 137fc350bc3..f55381614a3 100644
--- a/Applications/DataExplorer/DataView/DiagramView/DiagramPrefsDialog.cpp
+++ b/Applications/DataExplorer/DataView/DiagramView/DiagramPrefsDialog.cpp
@@ -67,47 +67,52 @@ DiagramPrefsDialog::~DiagramPrefsDialog()
 
 void DiagramPrefsDialog::accept()
 {
-    if ((fromDateLine->text().length() > 0) && (toDateLine->text().length() > 0) &&
-        (!_list.empty()))
+    QDateTime start_date(DiagramList::getDateTime(fromDateLine->text()));
+    QDateTime end_date(DiagramList::getDateTime(toDateLine->text()));
+
+    if (start_date == QDateTime() || end_date == QDateTime() ||
+        start_date > end_date || _list.empty())
     {
-        // data has been loaded
-        if (_list[0]->size() > 0)
-        {
-            bool window_is_empty(false);
-            if (_window == nullptr)
-            {
-                _window = new DetailWindow();
-                _window->setAttribute(Qt::WA_DeleteOnClose);
-                window_is_empty = true;
-            }
+        OGSError::box("No data found...");
+        return;
+    }
 
-            for (std::size_t i = 0; i < _list.size(); i++)
-                if (this->_visability[i]->isChecked())
-                {
-                    _window->addList(_list[i]);
-                    window_is_empty = false;
-                }
+    // data has been loaded
+    if (_list[0]->size() > 0)
+    {
+        bool window_is_empty(false);
+        if (_window == nullptr)
+        {
+            _window = new DetailWindow();
+            _window->setAttribute(Qt::WA_DeleteOnClose);
+            window_is_empty = true;
+        }
 
-            if (!window_is_empty)
-            {
-                _window->show();
-                this->done(QDialog::Accepted);
-            }
-            else
+        for (std::size_t i = 0; i < _list.size(); i++)
+            if (_visability[i]->isChecked())
             {
-                delete _window;
-                _window = nullptr;
-                OGSError::box("No dataset selected.");
+                _list[i]->truncateToRange(start_date, end_date);
+                _window->addList(_list[i]);
+                window_is_empty = false;
             }
+
+        if (!window_is_empty)
+        {
+            _window->show();
+            this->done(QDialog::Accepted);
         }
         else
         {
-            OGSError::box("Invalid station data.");
-            this->done(QDialog::Rejected);
+            delete _window;
+            _window = nullptr;
+            OGSError::box("No dataset selected.");
         }
     }
     else
-        OGSError::box("No data found...");
+    {
+        OGSError::box("Invalid station data.");
+        this->done(QDialog::Rejected);
+    }
 }
 
 void DiagramPrefsDialog::reject()
@@ -139,10 +144,9 @@ int DiagramPrefsDialog::loadFile(const QString &filename)
             // item->setYUnit("metres");
             item->setColor(QColor(Qt::red));
         }
-        fromDateLine->setText(_list[0]->getStartDate().toString("dd.MM.yyyy")); //QString::number(_list[0]->minXValue()));
-        QDateTime endDate =
-                _list[0]->getStartDate().addSecs(static_cast<int>(_list[0]->maxXValue()));
-        toDateLine->setText(endDate.toString("dd.MM.yyyy")); //QString::number(_list[0]->maxXValue()));
+        fromDateLine->setText(_list[0]->getStartDate().toString("dd.MM.yyyy"));
+        QDateTime endDate = _list[0]->getStartDate().addSecs(static_cast<int>(_list[0]->maxXValue()));
+        toDateLine->setText(endDate.toString("dd.MM.yyyy"));
         this->createVisibilityCheckboxes();
         return 1;
     }
diff --git a/Applications/DataExplorer/DataView/DiagramView/DiagramScene.cpp b/Applications/DataExplorer/DataView/DiagramView/DiagramScene.cpp
index 544621fb6d3..2fc9e0569af 100644
--- a/Applications/DataExplorer/DataView/DiagramView/DiagramScene.cpp
+++ b/Applications/DataExplorer/DataView/DiagramView/DiagramScene.cpp
@@ -68,7 +68,7 @@ DiagramScene::~DiagramScene()
 }
 
 /// Adds an arrow object to the diagram which might be used as a coordinate axis, etc.
-QArrow* DiagramScene::addArrow(float length, float angle, QPen &pen)
+QArrow* DiagramScene::addArrow(qreal length, qreal angle, QPen &pen)
 {
     auto* arrow = new QArrow(length, angle, 8, 5, pen);
     addItem(arrow);
@@ -130,7 +130,7 @@ QNonScalableGraphicsTextItem* DiagramScene::addNonScalableText(const QString &te
 }
 
 /// Resizes a given axis to "nice" dimensions and calculates an adequate number of ticks to be placed on it
-void DiagramScene::adjustAxis(float &min, float &max, int &numberOfTicks)
+void DiagramScene::adjustAxis(qreal& min, qreal& max, int& numberOfTicks)
 {
     const int MinTicks = 4;
     double grossStep = (max - min) / MinTicks;
@@ -142,8 +142,8 @@ void DiagramScene::adjustAxis(float &min, float &max, int &numberOfTicks)
     numberOfTicks = int(ceil(max / step) - std::floor(min / step));
     if (numberOfTicks < MinTicks)
         numberOfTicks = MinTicks;
-    min = std::floor(min / step) * step;
-    max = ceil(max / step) * step;
+    min = (std::floor(min / step) * step);
+    max = (ceil(max / step) * step);
 }
 
 ///Calculates scaling factors to set coordinate system and graphs to default window size
@@ -151,8 +151,8 @@ void DiagramScene::adjustScaling()
 {
     if ( (_unscaledBounds.width() > 0) && (_unscaledBounds.height() > 0))
     {
-        _scaleX = DEFAULTX / (_unscaledBounds.width());
-        _scaleY = DEFAULTY / (_unscaledBounds.height());
+        _scaleX = DEFAULTX / static_cast<float>(_unscaledBounds.width());
+        _scaleY = DEFAULTY / static_cast<float>(_unscaledBounds.height());
     }
 }
 
@@ -184,10 +184,10 @@ void DiagramScene::constructGrid()
 {
     // be very careful with scaling parameters here!
     int numXTicks, numYTicks;
-    float xMin = _unscaledBounds.left();
-    float yMin = _unscaledBounds.top();
-    float xMax = _unscaledBounds.right();
-    float yMax = _unscaledBounds.bottom();
+    qreal xMin = _unscaledBounds.left();
+    qreal yMin = _unscaledBounds.top();
+    qreal xMax = _unscaledBounds.right();
+    qreal yMax = _unscaledBounds.bottom();
 
     adjustAxis(xMin, xMax, numXTicks);
     adjustAxis(yMin, yMax, numYTicks);
@@ -229,9 +229,9 @@ void DiagramScene::constructGrid()
 
     for (int j = 0; j <= numYTicks; ++j)
     {
-        float y     = _bounds.bottom() / _scaleY -
+        qreal y     = _bounds.bottom() / _scaleY -
                       (j * (_bounds.height() / _scaleY) / numYTicks);
-        float label = _bounds.top()   / _scaleY +
+        qreal label = _bounds.top()   / _scaleY +
                       (j * (_bounds.height() / _scaleY) / numYTicks);
         _yTicksText.push_back(addNonScalableText(QString::number(label)));
         _yTicksText.last()->setPos(_bounds.left() - MARGIN / 2, y * _scaleY);
@@ -284,7 +284,7 @@ int DiagramScene::getYAxisOffset()
 /// calculates axes-lengths, offsets, etc.
 void DiagramScene::initialize()
 {
-    QPen pen(Qt::black, 2, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
+    QPen pen(Qt::black, 1, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
     pen.setCosmetic(true);
 
     setXAxis(addArrow(_bounds.width(),  0, pen));
diff --git a/Applications/DataExplorer/DataView/DiagramView/DiagramScene.h b/Applications/DataExplorer/DataView/DiagramView/DiagramScene.h
index 889b0a2d5f9..3eef400d7ca 100644
--- a/Applications/DataExplorer/DataView/DiagramView/DiagramScene.h
+++ b/Applications/DataExplorer/DataView/DiagramView/DiagramScene.h
@@ -32,7 +32,7 @@ public:
     DiagramScene(DiagramList* list, QObject* parent = nullptr);
     ~DiagramScene() override;
 
-    QArrow* addArrow(float length, float angle, QPen &pen);
+    QArrow* addArrow(qreal length, qreal angle, QPen &pen);
     void addGraph(DiagramList* list);
     QGraphicsGrid* addGrid(const QRectF &rect, int xTicks, int yTicks, const QPen &pen);
 
@@ -42,7 +42,7 @@ private:
     void addCaption(const QString &name, QPen &pen);
     QNonScalableGraphicsTextItem* addNonScalableText(const QString &text,
                                                      const QFont &font = QFont());
-    void adjustAxis(float &min, float &max, int &numberOfTicks);
+    void adjustAxis(qreal& min, qreal& max, int& numberOfTicks);
     void adjustScaling();
     void clearGrid();
     void constructGrid();
diff --git a/Applications/DataExplorer/DataView/DiagramView/QArrow.cpp b/Applications/DataExplorer/DataView/DiagramView/QArrow.cpp
index a2fe1ef0321..6ddb4f81652 100644
--- a/Applications/DataExplorer/DataView/DiagramView/QArrow.cpp
+++ b/Applications/DataExplorer/DataView/DiagramView/QArrow.cpp
@@ -25,7 +25,7 @@
  * \param pen The pen for drawing the arrow
  * \param parent The parent QGraphicsItem.
  */
-QArrow::QArrow(float l, float a, float hl, float hw, QPen &pen,
+QArrow::QArrow(qreal l, qreal a, qreal hl, qreal hw, QPen& pen,
                QGraphicsItem* parent) : QGraphicsItem(parent)
 {
     _arrowLength = l;
@@ -42,7 +42,8 @@ QArrow::QArrow(float l, float a, float hl, float hw, QPen &pen,
  * \param pen The pen for drawing the arrow
  * \param parent The parent QGraphicsItem.
  */
-QArrow::QArrow(float l, float a, QPen &pen, QGraphicsItem* parent) : QGraphicsItem(parent)
+QArrow::QArrow(qreal l, qreal a, QPen& pen, QGraphicsItem* parent)
+    : QGraphicsItem(parent)
 {
     _arrowLength = l;
     _arrowAngle  = a;
@@ -116,13 +117,13 @@ void QArrow::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QW
 }
 
 /// Changes orientation of the arrow.
-void QArrow::setAngle(double a)
+void QArrow::setAngle(float a)
 {
     _arrowAngle = a;
 }
 
 /// Changes the length of the arrow.
-void QArrow::setLength(double l)
+void QArrow::setLength(qreal l)
 {
     _arrowLength = l;
 }
diff --git a/Applications/DataExplorer/DataView/DiagramView/QArrow.h b/Applications/DataExplorer/DataView/DiagramView/QArrow.h
index f87f4c44734..85e11e17f4b 100644
--- a/Applications/DataExplorer/DataView/DiagramView/QArrow.h
+++ b/Applications/DataExplorer/DataView/DiagramView/QArrow.h
@@ -25,9 +25,9 @@ const double PI = 3.14159265;
 class QArrow : public QGraphicsItem
 {
 public:
-    QArrow(float l, float a, float hl, float hw, QPen& pen,
+    QArrow(qreal l, qreal a, qreal hl, qreal hw, QPen& pen,
            QGraphicsItem* parent = nullptr);
-    QArrow(float l, float a, QPen& pen, QGraphicsItem* parent = nullptr);
+    QArrow(qreal l, qreal a, QPen& pen, QGraphicsItem* parent = nullptr);
     ~QArrow() override;
 
     double getLength();
@@ -35,16 +35,16 @@ public:
     void paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
                QWidget* widget) override;
     QRectF boundingRect() const override;
-    void setAngle(double a);
-    void setLength(double l);
+    void setAngle(float a);
+    void setLength(qreal l);
 
 private:
     double calcCos(double angle);
     double calcSin(double angle);
 
-    float _arrowLength;
-    float _arrowAngle;
-    float _headLength;
-    float _headWidth;
+    qreal _arrowLength;
+    qreal _arrowAngle;
+    qreal _headLength;
+    qreal _headWidth;
     QPen _arrowPen;
 };
-- 
GitLab