From daaa9b193ee7397a927a699d5b63a25dc22e746e Mon Sep 17 00:00:00 2001
From: Pierre-Antoine Rouby <pierre-antoine.rouby@inrae.fr>
Date: Tue, 17 Oct 2023 11:18:35 +0200
Subject: [PATCH] Resutls: CustomPlot: Prepare ploting mecanisme.

---
 src/View/Results/CustomPlot/Plot.py      | 112 +++++++++++++++++++++++
 src/View/Results/CustomPlot/Translate.py |  16 +++-
 src/View/Results/Window.py               |  75 ++++++++++++++-
 3 files changed, 195 insertions(+), 8 deletions(-)
 create mode 100644 src/View/Results/CustomPlot/Plot.py

diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py
new file mode 100644
index 00000000..ea1e2001
--- /dev/null
+++ b/src/View/Results/CustomPlot/Plot.py
@@ -0,0 +1,112 @@
+# Plot.py -- Pamhyr
+# Copyright (C) 2023  INRAE
+#
+# This program 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.
+#
+# This program 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 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# -*- coding: utf-8 -*-
+
+import logging
+
+from functools import reduce
+
+from tools import timer
+from View.Tools.PamhyrPlot import PamhyrPlot
+
+logger = logging.getLogger()
+
+unit = {
+    "elevation": "meter",
+    "water_elevation": "meter",
+    "discharge": "m3s",
+}
+
+
+class CustomPlot(PamhyrPlot):
+    def __init__(self, x, y, reach, profile, timestamp,
+                 data=None, canvas=None, trad=None,
+                 toolbar=None, parent=None):
+        super(CustomPlot, self).__init__(
+            canvas=canvas,
+            trad=trad,
+            data=data,
+            toolbar=toolbar,
+            parent=parent
+        )
+
+        self._x = x
+        self._y = y
+        self._reach = reach
+        self._profile = profile
+        self._timestamp = timestamp
+
+        self._y_axis = list(
+            set(
+                map(
+                    lambda y: self._trad[y],
+                    self._y
+                )
+            )
+        )
+
+    @timer
+    def draw(self):
+        self.canvas.axes.cla()
+        self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5)
+
+        if self.data is None:
+            return
+
+        self.canvas.axes.set_xlabel(
+            self._trad[self._x],
+            color='green', fontsize=12
+        )
+        self.canvas.axes.set_ylabel(
+            self._trad[self._y_axis[0]],
+            color='green', fontsize=12
+        )
+
+        for axes in self._y_axis[1:]:
+            logger.info(axes)
+            ax_new = ax.twinx()
+            #ax_new.spines['right'].set_position(('axes', 1 + spacing * (n - 1)))
+            ax_new.set_ylabel(
+                self._trad[axes],
+                color='green', fontsize=12
+            )
+
+        if self._x is "kp":
+            if "elevation" in self._y:
+                logging.info("TODO: kp/elevation")
+            if "water_elevation" in self._y:
+                logging.info("TODO: kp/water_elevation")
+            if "discharge" in self._y:
+                logging.info("TODO: kp/discharge")
+        elif self._x is "time":
+            if "elevation" in self._y:
+                logging.info("TODO: time/elevation")
+            if "water_elevation" in self._y:
+                logging.info("TODO: time/water_elevation")
+            if "discharge" in self._y:
+                logging.info("TODO: time/discharge")
+
+        self.canvas.figure.tight_layout()
+        self.canvas.figure.canvas.draw_idle()
+        if self.toolbar is not None:
+            self.toolbar.update()
+
+    @timer
+    def update(self, reach, profile, timestamp):
+        if not self._init:
+            self.draw()
+            return
diff --git a/src/View/Results/CustomPlot/Translate.py b/src/View/Results/CustomPlot/Translate.py
index 11c3187e..aee28e0d 100644
--- a/src/View/Results/CustomPlot/Translate.py
+++ b/src/View/Results/CustomPlot/Translate.py
@@ -27,33 +27,39 @@ class CustomPlotTranslate(ResultsTranslate):
     def __init__(self):
         super(CustomPlotTranslate, self).__init__()
 
+        # Value type
+
         self._dict['time'] = _translate(
             "CustomPlot", "Time (sec)"
         )
-
         self._dict['kp'] = _translate(
             "CustomPlot", "Kp (m)"
         )
-
         self._dict['elevation'] = _translate(
             "CustomPlot", "Elevation (m)"
         )
-
         self._dict['water_elevation'] = _translate(
             "CustomPlot", "Water elevation (m)"
         )
-
         self._dict['discharge'] = _translate(
             "CustomPlot", "Discharge (m³/s)"
         )
 
+        # Unit corresponding long name (plot axes display)
+
+        self._dict['meter'] = _translate(
+            "CustomPlot", "Elevation (m)"
+        )
+        self._dict['m3s'] = _translate(
+            "CustomPlot", "Discharge (m³/s)"
+        )
+
         # SubDict
 
         self._sub_dict["values_x"] = {
             "kp": self._dict["kp"],
             "time": self._dict["time"],
         }
-
         self._sub_dict["values_y"] = {
             "elevation": self._dict["elevation"],
             "water_elevation": self._dict["water_elevation"],
diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py
index 353a036c..eb8c5b1d 100644
--- a/src/View/Results/Window.py
+++ b/src/View/Results/Window.py
@@ -38,7 +38,7 @@ from PyQt5.QtWidgets import (
     QFileDialog, QTableView, QAbstractItemView,
     QUndoStack, QShortcut, QAction, QItemDelegate,
     QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
-    QSlider, QLabel,
+    QSlider, QLabel, QWidget, QGridLayout,
 )
 
 from View.Tools.Plot.PamhyrCanvas import MplCanvas
@@ -51,6 +51,7 @@ from View.Results.PlotH import PlotH
 from View.Results.PlotSedReach import PlotSedReach
 from View.Results.PlotSedProfile import PlotSedProfile
 
+from View.Results.CustomPlot.Plot import CustomPlot
 from View.Results.CustomPlot.CustomPlotValuesSelectionDialog import (
     CustomPlotValuesSelectionDialog,
 )
@@ -91,6 +92,8 @@ class ResultsWindow(PamhyrWindow):
             parent=parent
         )
 
+        self._additional_plot = {}
+
         self.setup_table()
         self.setup_plot()
         self.setup_slider()
@@ -377,6 +380,27 @@ class ResultsWindow(PamhyrWindow):
 
         self.update_statusbar()
 
+    def _get_current_reach(self):
+        table = self.find(QTableView, f"tableView_reach")
+        indexes = table.selectedIndexes()
+        if len(indexes) == 0:
+            return 0
+
+        return indexes[0].row()
+
+    def _get_current_profile(self):
+        table = self.find(QTableView, f"tableView_profile")
+        indexes = table.selectedIndexes()
+        if len(indexes) == 0:
+            return 0
+
+        return indexes[0].row()
+
+    def _get_current_timestamp(self):
+        return self._timestamps[
+            self._slider_time.value()
+        ]
+
     def _set_current_reach(self):
         table = self.find(QTableView, f"tableView_reach")
         indexes = table.selectedIndexes()
@@ -408,8 +432,53 @@ class ResultsWindow(PamhyrWindow):
     def _add_custom_plot(self):
         dlg = CustomPlotValuesSelectionDialog(parent=self)
         if dlg.exec():
-            value = dlg.value
-            logger.info(value)
+            x, y = dlg.value
+            self.create_new_tab_custom_plot(x, y)
+
+    def create_new_tab_custom_plot(self, x:str, y:list):
+        name = f"{x}: {','.join(y)}"
+        wname = f"tab_custom_{x}_{y}"
+
+        tab_widget = self.find(QTabWidget, f"tabWidget")
+
+        # This plot already exists
+        if name in self._additional_plot:
+            tab_widget.setCurrentWidget(
+                tab_widget.findChild(QWidget, wname)
+            )
+            return
+
+        widget = QWidget()
+        grid = QGridLayout()
+
+        widget.setObjectName(wname)
+
+        canvas = MplCanvas(width=5, height=4, dpi=100)
+        canvas.setObjectName(f"canvas_{x}_{y}")
+        toolbar = PamhyrPlotToolbar(
+            canvas, self
+        )
+
+        plot = CustomPlot(
+            x, y,
+            self._get_current_reach(),
+            self._get_current_profile(),
+            self._get_current_timestamp(),
+            data=self._results,
+            canvas=canvas,
+            toolbar=toolbar,
+            trad=self._trad,
+            parent=self,
+        )
+        plot.draw()
+
+        # Add plot to additional plot
+        self._additional_plot[name] = plot
+
+        grid.addWidget(toolbar, 0, 0)
+        grid.addWidget(canvas, 1, 0)
+        widget.setLayout(grid)
+        tab_widget.addTab(widget, name)
 
     def _copy(self):
         logger.info("TODO: copy")
-- 
GitLab