From bc3deec91973f00378a4c458effb902ad53b60e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 15 Sep 2022 09:44:01 +0200
Subject: [PATCH 01/11] package.json: use ng2-charts instead of
 angular2-chartjs

refs #554
---
 package-lock.json | 124 +++++++++++++++++++---------------------------
 package.json      |   4 +-
 2 files changed, 53 insertions(+), 75 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 3accb6991..1df2daaff 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,9 +25,8 @@
         "@ngx-matomo/tracker": "^3.0.0",
         "@types/pako": "^1.0.4",
         "@types/sprintf-js": "^1.1.2",
-        "angular2-chartjs": "^0.5.1",
         "angular2-hotkeys": "^13.1.0",
-        "chartjs-plugin-zoom": "^0.7.7",
+        "chartjs-plugin-zoom": "^1.2.1",
         "cordova-android": "^11.0.0",
         "cordova-plugin-advanced-http": "^3.3.1",
         "cordova-plugin-app-version": "^0.1.14",
@@ -44,6 +43,7 @@
         "material-design-icons": "^3.0.1",
         "mathjax": "^3.2.2",
         "mermaid": "^9.1.3",
+        "ng2-charts": "^4.0.0",
         "ngx-markdown": "^14.0.1",
         "ngx-material-file-input": "^4.0.0",
         "ngx-webstorage-service": "^5.0.0",
@@ -4444,18 +4444,6 @@
         "semver": "bin/semver"
       }
     },
-    "node_modules/angular2-chartjs": {
-      "version": "0.5.1",
-      "license": "MIT",
-      "dependencies": {
-        "chart.js": "^2.3.0"
-      },
-      "peerDependencies": {
-        "@angular/common": ">=4.0.0 || ^2.0.0",
-        "@angular/compiler": ">=4.0.0 || ^2.0.0",
-        "@angular/core": ">=4.0.0 || ^2.0.0"
-      }
-    },
     "node_modules/angular2-hotkeys": {
       "version": "13.1.0",
       "license": "MIT",
@@ -5873,36 +5861,20 @@
       "license": "MIT"
     },
     "node_modules/chart.js": {
-      "version": "2.9.4",
-      "license": "MIT",
-      "dependencies": {
-        "chartjs-color": "^2.1.0",
-        "moment": "^2.10.2"
-      }
-    },
-    "node_modules/chartjs-color": {
-      "version": "2.4.1",
-      "license": "MIT",
-      "dependencies": {
-        "chartjs-color-string": "^0.6.0",
-        "color-convert": "^1.9.3"
-      }
-    },
-    "node_modules/chartjs-color-string": {
-      "version": "0.6.0",
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "^1.0.0"
-      }
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
+      "integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w==",
+      "peer": true
     },
     "node_modules/chartjs-plugin-zoom": {
-      "version": "0.7.7",
-      "license": "MIT",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.2.1.tgz",
+      "integrity": "sha512-2zbWvw2pljrtMLMXkKw1uxYzAne5PtjJiOZftcut4Lo3Ee8qUt95RpMKDWrZ+pBZxZKQKOD/etdU4pN2jxZUmg==",
       "dependencies": {
         "hammerjs": "^2.0.8"
       },
       "peerDependencies": {
-        "chart.js": "^2.6.0"
+        "chart.js": "^3.2.0"
       }
     },
     "node_modules/cheerio": {
@@ -13362,6 +13334,11 @@
       "version": "4.17.21",
       "license": "MIT"
     },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
       "license": "MIT"
@@ -13893,13 +13870,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/moment": {
-      "version": "2.29.4",
-      "license": "MIT",
-      "engines": {
-        "node": "*"
-      }
-    },
     "node_modules/moment-mini": {
       "version": "2.24.0",
       "license": "MIT"
@@ -14021,6 +13991,21 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/ng2-charts": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-4.0.0.tgz",
+      "integrity": "sha512-1COLMs1UH8XIurk9C3pBQW3zH4RM3ggPtaC5vGjEmRGZ2cK/j8DqpzN4xMqyk0KB4D2vw/ZejgXmxxZ4Ie58Rw==",
+      "dependencies": {
+        "lodash-es": "^4.17.15",
+        "tslib": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@angular/common": ">=14.0.0",
+        "@angular/core": ">=14.0.0",
+        "chart.js": "^3.4.0",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
     "node_modules/ngx-markdown": {
       "version": "14.0.1",
       "license": "MIT",
@@ -22809,12 +22794,6 @@
         }
       }
     },
-    "angular2-chartjs": {
-      "version": "0.5.1",
-      "requires": {
-        "chart.js": "^2.3.0"
-      }
-    },
     "angular2-hotkeys": {
       "version": "13.1.0",
       "requires": {
@@ -23741,27 +23720,15 @@
       "version": "0.7.0"
     },
     "chart.js": {
-      "version": "2.9.4",
-      "requires": {
-        "chartjs-color": "^2.1.0",
-        "moment": "^2.10.2"
-      }
-    },
-    "chartjs-color": {
-      "version": "2.4.1",
-      "requires": {
-        "chartjs-color-string": "^0.6.0",
-        "color-convert": "^1.9.3"
-      }
-    },
-    "chartjs-color-string": {
-      "version": "0.6.0",
-      "requires": {
-        "color-name": "^1.0.0"
-      }
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
+      "integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w==",
+      "peer": true
     },
     "chartjs-plugin-zoom": {
-      "version": "0.7.7",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.2.1.tgz",
+      "integrity": "sha512-2zbWvw2pljrtMLMXkKw1uxYzAne5PtjJiOZftcut4Lo3Ee8qUt95RpMKDWrZ+pBZxZKQKOD/etdU4pN2jxZUmg==",
       "requires": {
         "hammerjs": "^2.0.8"
       }
@@ -28676,6 +28643,11 @@
     "lodash": {
       "version": "4.17.21"
     },
+    "lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
     "lodash.debounce": {
       "version": "4.0.8"
     },
@@ -28991,9 +28963,6 @@
     "mkdirp": {
       "version": "1.0.4"
     },
-    "moment": {
-      "version": "2.29.4"
-    },
     "moment-mini": {
       "version": "2.24.0"
     },
@@ -29079,6 +29048,15 @@
       "version": "1.1.0",
       "dev": true
     },
+    "ng2-charts": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-4.0.0.tgz",
+      "integrity": "sha512-1COLMs1UH8XIurk9C3pBQW3zH4RM3ggPtaC5vGjEmRGZ2cK/j8DqpzN4xMqyk0KB4D2vw/ZejgXmxxZ4Ie58Rw==",
+      "requires": {
+        "lodash-es": "^4.17.15",
+        "tslib": "^2.3.0"
+      }
+    },
     "ngx-markdown": {
       "version": "14.0.1",
       "requires": {
diff --git a/package.json b/package.json
index f9a1a962c..24abe266b 100644
--- a/package.json
+++ b/package.json
@@ -51,9 +51,9 @@
     "@ngx-matomo/tracker": "^3.0.0",
     "@types/pako": "^1.0.4",
     "@types/sprintf-js": "^1.1.2",
-    "angular2-chartjs": "^0.5.1",
+    "ng2-charts": "^4.0.0",
     "angular2-hotkeys": "^13.1.0",
-    "chartjs-plugin-zoom": "^0.7.7",
+    "chartjs-plugin-zoom": "^1.2.1",
     "cordova-android": "^11.0.0",
     "cordova-plugin-advanced-http": "^3.3.1",
     "cordova-plugin-app-version": "^0.1.14",
-- 
GitLab


From 56b9ff4c6211f97a51996f4746d66058b38195e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 15 Sep 2022 10:27:36 +0200
Subject: [PATCH 02/11] refactor: adapt components,graph options,templates to
 ng2-charts

refs #554
---
 src/app/app.module.ts                         |  4 +-
 .../dialog-edit-param-values.component.html   |  4 +-
 .../dialog-edit-param-values.component.ts     | 20 ++---
 .../jet-trajectory-chart.component.html       |  4 +-
 .../jet-trajectory-chart.component.ts         | 48 ++++++------
 .../pab-profile-chart.component.html          |  4 +-
 .../pab-profile-chart.component.ts            | 44 ++++++-----
 .../remous-results.component.html             |  8 +-
 .../remous-results.component.ts               | 58 +++++++-------
 .../results-chart.component.html              |  4 +-
 .../results-chart/results-chart.component.ts  | 76 ++++++++++---------
 11 files changed, 143 insertions(+), 131 deletions(-)

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 468ee73c9..7c57cdce8 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -41,7 +41,7 @@ import {
 
 import { HttpClientModule } from "@angular/common/http";
 import { FormsModule, ReactiveFormsModule } from "@angular/forms"; // <-- NgModel lives here
-import { ChartModule } from "angular2-chartjs";
+import { NgChartsModule } from "ng2-charts";
 import { RouterModule, Routes } from "@angular/router";
 import { HotkeyModule } from "angular2-hotkeys";
 import { NgxMatomoTrackerModule } from "@ngx-matomo/tracker";
@@ -138,7 +138,7 @@ const appRoutes: Routes = [
         ReactiveFormsModule,
         BrowserAnimationsModule,
         BrowserModule,
-        ChartModule,
+        NgChartsModule,
         DragDropModule,
         FlexLayoutModule,
         HotkeyModule.forRoot(),
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
index 9bc8e3bb1..76aefb4b6 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
@@ -116,8 +116,8 @@
 </div>
 
 <div mat-dialog-content *ngIf="viewChart">
-    <chart id="values-chart" type="scatter" [data]="chartData" [options]="chartOptions">
-    </chart>
+    <canvas baseChart id="values-chart" type="scatter" [data]="chartData" [options]="chartOptions">
+    </canvas>
 </div>
 
 <div mat-dialog-actions [attr.align]="'end'">
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
index 7f28b26dd..b1e971ec1 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
@@ -107,18 +107,15 @@ export class DialogEditParamValuesComponent implements OnInit {
             animation: {
                 duration: 0
             },
-            legend: {
-                display: false
-            },
             scales: {
-                xAxes: [{
+                x: [{
                     type: "linear",
                     position: "bottom",
                     ticks: {
                         precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                     }
                 }],
-                yAxes: [{
+                y: [{
                     type: "linear",
                     position: "left",
                     ticks: {
@@ -131,10 +128,15 @@ export class DialogEditParamValuesComponent implements OnInit {
                     tension: 0
                 }
             },
-            tooltips: {
-                callbacks: {
-                    label: function(tooltipItem) {
-                        return  fv(Number(tooltipItem.yLabel));
+            plugins: {
+                legend: {
+                    display: false
+                },
+                tooltip: {
+                    callbacks: {
+                        label: function (tooltipItem) {
+                            return fv(Number(tooltipItem.formattedValue));
+                        }
                     }
                 }
             }
diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
index cedbcf293..78d2ed8f5 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
@@ -17,7 +17,7 @@
         </div>
 
         <div *ngIf="! displayChart" class="fake-chart"></div><!-- trick to avoid blinking effect due to forceRebuild -->
-        <chart *ngIf="displayChart" type="scatter" [data]="graph_data" [options]="graph_options">
-        </chart>
+        <canvas baseChart *ngIf="displayChart" type="scatter" [data]="graph_data" [options]="graph_options">
+        </canvas>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
index 2d726e9f9..c5df1edb3 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
-import { ChartComponent } from "angular2-chartjs";
+import { NgChartsModule } from "ng2-charts";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
@@ -19,7 +19,7 @@ import { Jet, Result } from "jalhyd";
 })
 export class JetTrajectoryChartComponent extends ResultsComponentDirective implements OnChanges {
 
-    @ViewChild(ChartComponent)
+    @ViewChild(NgChartsModule)
     private chartComponent;
 
     private _results: Result;
@@ -42,14 +42,16 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
         animation: {
             duration: 0
         },
-        legend: {
-            display: true,
-            position: "bottom",
-            reverse: false
-        },
-        title: {
-            display: true,
-            text: this.intlService.localizeText("INFO_JET_TITRE_TRAJECTOIRE")
+        plugins: {
+            legend: {
+                display: true,
+                position: "bottom",
+                reverse: false
+            },
+            title: {
+                display: true,
+                text: this.intlService.localizeText("INFO_JET_TITRE_TRAJECTOIRE")
+            }
         },
         elements: {
             line: {
@@ -65,26 +67,26 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
         super();
         // do not move following block out of constructor or scale labels won't be rendered
         this.graph_options["scales"] = {
-            xAxes: [{
+            x: [{
                 type: "linear",
                 position: "bottom",
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.intlService.localizeText("INFO_LIB_ABSCISSE")
+                    text: this.intlService.localizeText("INFO_LIB_ABSCISSE")
                 }
             }],
-            yAxes: [{
+            y: [{
                 type: "linear",
                 position: "left",
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.intlService.localizeText("INFO_LIB_ALTITUDE")
+                    text: this.intlService.localizeText("INFO_LIB_ALTITUDE")
                 }
             }]
         };
@@ -110,12 +112,12 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
                 }
             }
         };
-        // format numbers in tooltips
-        this.graph_options.tooltips = {
+        // format numbers in tooltip
+        this.graph_options.tooltip = {
             displayColors: false,
             callbacks: {
-                label: (tooltipItem, data) => {
-                    return "(" + fv(Number(tooltipItem.xLabel)) + ", " + fv(Number(tooltipItem.yLabel)) + ")";
+                label: (tooltipItem) => {
+                    return "(" + fv(Number(tooltipItem.label)) + ", " + fv(Number(tooltipItem.formattedValue)) + ")";
                 }
             }
         };
@@ -132,7 +134,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
 
     @Input()
     public set results(r: Result) {
-        this.forceRebuild(); // used for forcing redefinition of xAxes[0].ticks.min/max in generateScatterChart()
+        this.forceRebuild(); // used for forcing redefinition of x[0].min/max in generateScatterChart()
         this._results = r;
     }
 
@@ -193,8 +195,8 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
         }
 
         // adjust chart width
-        this.graph_options.scales.xAxes[0].ticks.min = 0;
-        this.graph_options.scales.xAxes[0].ticks.max = greatestAbscissa;
+        this.graph_options.scales.x[0].min = 0;
+        this.graph_options.scales.x[0].max = greatestAbscissa;
 
         // build Y data series
         for (const ys of ySeries) {
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.html b/src/app/components/pab-profile-chart/pab-profile-chart.component.html
index f7c4d9079..fbc980f17 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.html
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.html
@@ -16,7 +16,7 @@
             </button>
         </div>
 
-        <chart type="scatter" [data]="graph_data" [options]="graph_options">
-        </chart>
+        <canvas baseChart type="scatter" [data]="graph_data" [options]="graph_options">
+        </canvas>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index 449c050ff..ca8aeebcd 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
-import { ChartComponent } from "angular2-chartjs";
+import { NgChartsModule } from "ng2-charts";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
@@ -23,7 +23,7 @@ import { CalculatorResults } from 'app/results/calculator-results';
 })
 export class PabProfileChartComponent extends ResultsComponentDirective implements OnChanges {
 
-    @ViewChild(ChartComponent)
+    @ViewChild(NgChartsModule)
     private chartComponent;
 
     private _results: PabResults;
@@ -40,21 +40,23 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
      * config du graphique
      */
     public graph_data: { datasets: any[] };
-    public graph_options = {
+    public graph_options: any = {
         responsive: true,
         maintainAspectRatio: true,
         aspectRatio: 1.5,
         animation: {
             duration: 0
         },
-        legend: {
-            display: true,
-            position: "bottom",
-            reverse: false
-        },
-        title: {
-            display: true,
-            text: this.intlService.localizeText("INFO_PAB_TITRE_PROFIL")
+        plugins: {
+            legend: {
+                display: true,
+                position: "bottom",
+                reverse: false
+            },
+            title: {
+                display: true,
+                text: this.intlService.localizeText("INFO_PAB_TITRE_PROFIL")
+            }
         },
         elements: {
             line: {
@@ -70,26 +72,26 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
         super();
         // do not move following block out of constructor or scale labels won't be rendered
         this.graph_options["scales"] = {
-            xAxes: [{
+            x: [{
                 type: "linear",
                 position: "bottom",
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.intlService.localizeText("INFO_LIB_DISTANCE_AMONT")
+                    text: this.intlService.localizeText("INFO_LIB_DISTANCE_AMONT")
                 }
             }],
-            yAxes: [{
+            y: [{
                 type: "linear",
                 position: "left",
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.intlService.localizeText("INFO_LIB_COTE")
+                    text: this.intlService.localizeText("INFO_LIB_COTE")
                 }
             }]
         };
@@ -115,12 +117,12 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
                 }
             }
         };
-        // format numbers in tooltips
-        this.graph_options["tooltips"] = {
+        // format numbers in tooltip
+        this.graph_options["tooltip"] = {
             displayColors: false,
             callbacks: {
-                label: (tooltipItem, data) => {
-                    return "(" + fv(Number(tooltipItem.xLabel)) + ", " + fv(Number(tooltipItem.yLabel)) + ")";
+                label: (tooltipItem) => {
+                    return "(" + fv(Number(tooltipItem.label)) + ", " + fv(Number(tooltipItem.formattedValue)) + ")";
                 }
             }
         };
diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html
index 7f9efd5fd..bdeaafee6 100644
--- a/src/app/components/remous-results/remous-results.component.html
+++ b/src/app/components/remous-results/remous-results.component.html
@@ -14,9 +14,9 @@
             </button>
         </div>
 
-        <chart id="main-chart" ngClass.lt-sm="height300" ngClass.sm="height400" ngClass.md="height400"
+        <canvas baseChart id="main-chart" ngClass.lt-sm="height300" ngClass.sm="height400" ngClass.md="height400"
             ngClass.gt-md="height600" [type]="graph1_type" [data]="graph1_data" [options]="graph1_options">
-        </chart>
+        </canvas>
     </div>
 </div>
 
@@ -36,7 +36,7 @@
             </button>
         </div>
 
-        <chart [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></chart>
+        <canvas baseChart [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></canvas>
     </div>
 </div>
 
@@ -47,4 +47,4 @@
 <div *ngIf="hasData">
     <!-- résultats numériques -->
     <var-results [results]=varResults></var-results>
-</div>
+</div>
\ No newline at end of file
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index b753778b4..ad48d2957 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -397,12 +397,8 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
             animation: {
                 duration: 0
             },
-            legend: {
-                display: true,
-                position: "bottom"
-            },
             scales: {
-                xAxes: [{
+                x: [{
                     gridLines: {
                         display: true,
                         color: "rgba(255,99,132,0.2)",
@@ -410,27 +406,33 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                     },
                     ticks: {
                         precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION,
-                        callback: function(value, index, values) {
+                        callback: function (value, index, values) {
                             return fv(Number(value));
                         }
                     },
-                    scaleLabel: {
+                    title: {
                         display: true,
-                        labelString: this.uitextAbscisse
+                        text: this.uitextAbscisse
                     }
                 }],
-                yAxes: [{
+                y: [{
                     // stacked: true,
                     gridLines: {
-                      display: true,
-                      color: "rgba(255,99,132,0.2)"
+                        display: true,
+                        color: "rgba(255,99,132,0.2)"
                     }
                 }]
             },
-            tooltips: {
-                callbacks: {
-                    label: function(tooltipItem, data) {
-                        return fv(Number(tooltipItem.yLabel));
+            plugins: {
+                legend: {
+                    display: true,
+                    position: "bottom"
+                },
+                tooltip: {
+                    callbacks: {
+                        label: function (tooltipItem) {
+                            return fv(Number(tooltipItem.formattedValue));
+                        }
                     }
                 }
             }
@@ -445,28 +447,30 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                 animation: {
                     duration: 0
                 },
-                legend: {
-                    display: true,
-                    position: "bottom"
-                },
                 scales: {
-                    xAxes: [{
-                        scaleLabel: {
+                    x: [{
+                        title: {
                             display: true,
-                            labelString: this.uitextAbscisse
+                            text: this.uitextAbscisse
                         },
                         ticks: {
                             precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION,
-                            callback: function(value, index, values) {
+                            callback: function (value, index, values) {
                                 return fv(Number(value));
                             }
                         },
                     }]
                 },
-                tooltips: {
-                    callbacks: {
-                        label: function(tooltipItem, data) {
-                            return fv(Number(tooltipItem.yLabel));
+                plugins: {
+                    legend: {
+                        display: true,
+                        position: "bottom"
+                    },
+                    tooltip: {
+                        callbacks: {
+                            label: function (tooltipItem) {
+                                return fv(Number(tooltipItem.formattedValue));
+                            }
                         }
                     }
                 }
diff --git a/src/app/components/results-chart/results-chart.component.html b/src/app/components/results-chart/results-chart.component.html
index be55ade02..3e228f456 100644
--- a/src/app/components/results-chart/results-chart.component.html
+++ b/src/app/components/results-chart/results-chart.component.html
@@ -17,8 +17,8 @@
         </div>
 
         <div *ngIf="! displayChart" class="fake-chart"></div><!-- trick to avoid blinking effect due to forceRebuild -->
-        <chart *ngIf="displayChart" [type]="graph_type" [data]="graph_data" [options]="graph_options">
-        </chart>
+        <canvas baseChart *ngIf="displayChart" [type]="graph_type" [data]="graph_data" [options]="graph_options">
+        </canvas>
     </div>
 </div>
 
diff --git a/src/app/components/results-chart/results-chart.component.ts b/src/app/components/results-chart/results-chart.component.ts
index a547f1097..743986e40 100644
--- a/src/app/components/results-chart/results-chart.component.ts
+++ b/src/app/components/results-chart/results-chart.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, AfterContentInit, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
-import { ChartComponent } from "angular2-chartjs";
+import { NgChartsModule } from "ng2-charts";
 
 import { Observer, ParamFamily, Result } from "jalhyd";
 
@@ -23,7 +23,7 @@ import { AppComponent } from "../../app.component";
 })
 export class ResultsChartComponent extends ResultsComponentDirective implements AfterContentInit, Observer, OnChanges {
 
-    @ViewChild(ChartComponent)
+    @ViewChild(NgChartsModule)
     private chartComponent;
 
     private _results: PlottableData;
@@ -47,12 +47,14 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         animation: {
             duration: 0
         },
-        legend: {
-            display: false
-        },
-        title: {
-            display: true,
-            text: ""
+        plugins: {
+            legend: {
+                display: false
+            },
+            title: {
+                display: true,
+                text: ""
+            }
         },
         elements: {
             line: {
@@ -250,42 +252,42 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         }
 
         this.graph_options["scales"] = {
-            xAxes: [{
+            x: [{
                 gridLines: {
                     offsetGridLines: true
                 },
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION,
-                    callback: function(value, index, values) {
+                    callback: function (value, index, values) {
                         return fv(Number(value));
                     }
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.axisLabelWithoutSymbol(this.chartX)
+                    text: this.axisLabelWithoutSymbol(this.chartX)
                 }
             }],
-            yAxes: [{
-                scaleLabel: {
+            y: [{
+                title: {
                     display: true,
-                    labelString: this.axisLabelWithoutSymbol(this.chartY)
+                    text: this.axisLabelWithoutSymbol(this.chartY)
                 }
             }]
         };
 
         const that = this;
-        this.graph_options["tooltips"] = {
+        this.graph_options["tooltip"] = {
             displayColors: false,
             callbacks: {
-                title: (tooltipItems, data) => {
-                    return this.chartY + " = " + fv(Number(tooltipItems[0].yLabel));
+                title: (tooltipItems) => {
+                    return this.chartY + " = " + fv(Number(tooltipItems[0].formattedValue));
                 },
-                label: (tooltipItem, data) => {
+                label: (tooltipItem) => {
                     const lines: string[] = [];
                     const nbLines = that._results.getVariatingParametersSymbols().length;
                     for (const v of that._results.getVariatingParametersSymbols()) {
                         const series = that._results.getValuesSeries(v);
-                        const line = v + " = " + fv(series[tooltipItem.index]);
+                        const line = v + " = " + fv(series[tooltipItem.dataIndex]);
                         if (v === this.chartX) {
                             if (nbLines > 1) {
                                 lines.unshift("");
@@ -347,54 +349,54 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         }
 
         this.graph_options["scales"] = {
-            xAxes: [{
+            x: [{
                 type: "linear",
                 position: "bottom",
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.axisLabelWithoutSymbol(this.chartX)
+                    text: this.axisLabelWithoutSymbol(this.chartX)
                 }
             }],
-            yAxes: [{
+            y: [{
                 type: "linear",
                 position: "left",
                 ticks: {
                     precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                 },
-                scaleLabel: {
+                title: {
                     display: true,
-                    labelString: this.axisLabelWithoutSymbol(this.chartY)
+                    text: this.axisLabelWithoutSymbol(this.chartY)
                 }
             }]
         };
 
         if (isMultiple) {
             // add legend for multiple series
-            this.graph_options.legend = {
+            this.graph_options.plugins.legend = {
                 display: true,
                 position: "bottom",
                 reverse: false
             };
-            // remove tooltips
-            delete this.graph_options.tooltips;
+            // remove tooltip
+            delete this.graph_options.tooltip;
         } else {
-            // enhanced tooltips for single series
+            // enhanced tooltip for single series
             const that = this;
-            this.graph_options.tooltips = {
+            this.graph_options.tooltip = {
                 displayColors: false,
                 callbacks: {
-                    title: (tooltipItems, data) => {
-                        return this.chartY + " = " + fv(Number(tooltipItems[0].yLabel));
+                    title: (tooltipItems) => {
+                        return this.chartY + " = " + fv(Number(tooltipItems[0].formattedValue));
                     },
-                    label: (tooltipItem, data) => {
+                    label: (tooltipItem) => {
                         let lines: string[] = [];
                         // 1. X if different from Y
                         if (this.chartX !== this.chartY) {
                             const xseries = that._results.getValuesSeries(this.chartX);
-                            const xline = this.chartX + " = " + fv(xseries[tooltipItem.index]);
+                            const xline = this.chartX + " = " + fv(xseries[tooltipItem.dataIndex]);
                             lines.push(xline);
                         }
                         // 2. variated parameters other than X or Y
@@ -402,7 +404,7 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
                         for (const v of that._results.getVariatingParametersSymbols()) {
                             if (v !== this.chartX && v !== this.chartY) {
                                 const series = that._results.getValuesSeries(v);
-                                const line = v + " = " + fv(series[tooltipItem.index]);
+                                const line = v + " = " + fv(series[tooltipItem.dataIndex]);
                                 varLines.push(line);
                             }
                         }
@@ -416,7 +418,7 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
                 }
             };
             // remove legend
-            this.graph_options.legend = {
+            this.graph_options.plugins.legend = {
                 display: false
             };
         }
-- 
GitLab


From dd6112a5b018596fd520631a19f68adbd2c42341 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 15 Sep 2022 10:47:40 +0200
Subject: [PATCH 03/11] fix: backwater curves: ever growing result graph

refs #554
---
 src/app/components/remous-results/remous-results.component.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index ad48d2957..ed8143ab3 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -393,7 +393,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
 
         this.graph1_options = {
             responsive: true,
-            maintainAspectRatio: false,
+            maintainAspectRatio: true,
             animation: {
                 duration: 0
             },
-- 
GitLab


From bdf91b4d76e31469ebddf904fdf1ba8a3fa86eba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 15 Sep 2022 11:48:49 +0200
Subject: [PATCH 04/11] fix: console error message "invalid scale configuration
 for scale"

refs #554
---
 .../dialog-edit-param-values.component.ts        |  8 ++++----
 .../jet-trajectory-chart.component.ts            | 14 +++++++-------
 .../pab-profile-chart.component.ts               |  8 ++++----
 .../remous-results/remous-results.component.ts   | 12 ++++++------
 .../results-chart/results-chart.component.ts     | 16 ++++++++--------
 5 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
index b1e971ec1..a5cc9fcec 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
@@ -108,20 +108,20 @@ export class DialogEditParamValuesComponent implements OnInit {
                 duration: 0
             },
             scales: {
-                x: [{
+                x: {
                     type: "linear",
                     position: "bottom",
                     ticks: {
                         precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                     }
-                }],
-                y: [{
+                },
+                y: {
                     type: "linear",
                     position: "left",
                     ticks: {
                         precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION
                     }
-                }]
+                }
             },
             elements: {
                 line: {
diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
index c5df1edb3..c11af834a 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
@@ -67,7 +67,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
         super();
         // do not move following block out of constructor or scale labels won't be rendered
         this.graph_options["scales"] = {
-            x: [{
+            x: {
                 type: "linear",
                 position: "bottom",
                 ticks: {
@@ -77,8 +77,8 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
                     display: true,
                     text: this.intlService.localizeText("INFO_LIB_ABSCISSE")
                 }
-            }],
-            y: [{
+            },
+            y: {
                 type: "linear",
                 position: "left",
                 ticks: {
@@ -88,7 +88,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
                     display: true,
                     text: this.intlService.localizeText("INFO_LIB_ALTITUDE")
                 }
-            }]
+            }
         };
         // enable zoom and pan (using "chartjs-plugin-zoom" package)
         const that = this;
@@ -134,7 +134,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
 
     @Input()
     public set results(r: Result) {
-        this.forceRebuild(); // used for forcing redefinition of x[0].min/max in generateScatterChart()
+        this.forceRebuild(); // used for forcing redefinition of x.min/max in generateScatterChart()
         this._results = r;
     }
 
@@ -195,8 +195,8 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
         }
 
         // adjust chart width
-        this.graph_options.scales.x[0].min = 0;
-        this.graph_options.scales.x[0].max = greatestAbscissa;
+        this.graph_options.scales.x.min = 0;
+        this.graph_options.scales.x.max = greatestAbscissa;
 
         // build Y data series
         for (const ys of ySeries) {
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index ca8aeebcd..b79afc76b 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -72,7 +72,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
         super();
         // do not move following block out of constructor or scale labels won't be rendered
         this.graph_options["scales"] = {
-            x: [{
+            x: {
                 type: "linear",
                 position: "bottom",
                 ticks: {
@@ -82,8 +82,8 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
                     display: true,
                     text: this.intlService.localizeText("INFO_LIB_DISTANCE_AMONT")
                 }
-            }],
-            y: [{
+            },
+            y: {
                 type: "linear",
                 position: "left",
                 ticks: {
@@ -93,7 +93,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
                     display: true,
                     text: this.intlService.localizeText("INFO_LIB_COTE")
                 }
-            }]
+            }
         };
         // enable zoom and pan (using "chartjs-plugin-zoom" package)
         const that = this;
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index ed8143ab3..77f8bd8d6 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -398,7 +398,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                 duration: 0
             },
             scales: {
-                x: [{
+                x: {
                     gridLines: {
                         display: true,
                         color: "rgba(255,99,132,0.2)",
@@ -414,14 +414,14 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                         display: true,
                         text: this.uitextAbscisse
                     }
-                }],
-                y: [{
+                },
+                y: {
                     // stacked: true,
                     gridLines: {
                         display: true,
                         color: "rgba(255,99,132,0.2)"
                     }
-                }]
+                }
             },
             plugins: {
                 legend: {
@@ -448,7 +448,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                     duration: 0
                 },
                 scales: {
-                    x: [{
+                    x: {
                         title: {
                             display: true,
                             text: this.uitextAbscisse
@@ -459,7 +459,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                                 return fv(Number(value));
                             }
                         },
-                    }]
+                    }
                 },
                 plugins: {
                     legend: {
diff --git a/src/app/components/results-chart/results-chart.component.ts b/src/app/components/results-chart/results-chart.component.ts
index 743986e40..9821f98e9 100644
--- a/src/app/components/results-chart/results-chart.component.ts
+++ b/src/app/components/results-chart/results-chart.component.ts
@@ -252,7 +252,7 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         }
 
         this.graph_options["scales"] = {
-            x: [{
+            x: {
                 gridLines: {
                     offsetGridLines: true
                 },
@@ -266,13 +266,13 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
                     display: true,
                     text: this.axisLabelWithoutSymbol(this.chartX)
                 }
-            }],
-            y: [{
+            },
+            y: {
                 title: {
                     display: true,
                     text: this.axisLabelWithoutSymbol(this.chartY)
                 }
-            }]
+            }
         };
 
         const that = this;
@@ -349,7 +349,7 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         }
 
         this.graph_options["scales"] = {
-            x: [{
+            x: {
                 type: "linear",
                 position: "bottom",
                 ticks: {
@@ -359,8 +359,8 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
                     display: true,
                     text: this.axisLabelWithoutSymbol(this.chartX)
                 }
-            }],
-            y: [{
+            },
+            y: {
                 type: "linear",
                 position: "left",
                 ticks: {
@@ -370,7 +370,7 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
                     display: true,
                     text: this.axisLabelWithoutSymbol(this.chartY)
                 }
-            }]
+            }
         };
 
         if (isMultiple) {
-- 
GitLab


From 4fa8a52d01c90a47408aab3d28e809031ca3a25f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Fri, 23 Sep 2022 14:22:12 +0200
Subject: [PATCH 05/11] fix: backwater curves: restore filled area under water
 line

refs #554
---
 .../remous-results/remous-results.component.ts         | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index 77f8bd8d6..0e810fe2a 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -435,6 +435,11 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                         }
                     }
                 }
+            },
+            elements: {
+                line: {
+                    fill: true
+                }
             }
         };
 
@@ -473,6 +478,11 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                             }
                         }
                     }
+                },
+                elements: {
+                    line: {
+                        fill: true
+                    }
                 }
             };
         }
-- 
GitLab


From 7d5743578fcfc687079b66efcb1a50cfe5af12cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Fri, 23 Sep 2022 15:18:24 +0200
Subject: [PATCH 06/11] fix: backwater curves chart: restore filled legend
 rectangle items

refs #554
---
 src/app/components/remous-results/line-and-chart-data.ts  | 6 ++++--
 .../components/remous-results/remous-results.component.ts | 8 ++++----
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/app/components/remous-results/line-and-chart-data.ts b/src/app/components/remous-results/line-and-chart-data.ts
index c0c7b1d17..433e147f6 100644
--- a/src/app/components/remous-results/line-and-chart-data.ts
+++ b/src/app/components/remous-results/line-and-chart-data.ts
@@ -193,13 +193,15 @@ export class ChartData {
     /**
      * Dessigne une ligne droite entre y0 (abscisse 0) et ymax (abscisse max),
      * sans passer par les méthodes mapPoint() et mapY() utilisées dans drawLine
+     * @param fillArea true pour remplir la zone sous la ligne
+     * @param fillColor couleur de remplissage de la zone sous la ligne
      */
-    public drawSimpleLine(y0: number, ymax: number, prof: number, color: string, lbl: string, fillColor?: string) {
+    public drawSimpleLine(y0: number, ymax: number, prof: number, color: string, lbl: string, fillArea: boolean = false, fillColor?: string) {
         const l = this.newLine(prof);
         l.setPoint(0, y0);
         l.setPoint(this._longBief, ymax);
         l.data = {
-            label: lbl, fill: fillColor !== undefined, tension: 0, spanGaps: true,
+            label: lbl, fill: fillArea, tension: 0, spanGaps: true,
             borderColor: color, backgroundColor: fillColor, pointRadius: 0, showLine: "true"
         };
     }
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index 0e810fe2a..e982e1999 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -272,18 +272,18 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         }
 
         // ligne de fond
-        gr1.drawSimpleLine(ZF1, ZF2, 3, "#753F00", this.uitextFond, "#753F00");
+        gr1.drawSimpleLine(ZF1, ZF2, 3, "#753F00", this.uitextFond, true, "#753F00");
 
         // ligne de berge
         if (hauteurBerge) {
-            gr1.drawSimpleLine(ZF1 + hauteurBerge, ZF2 + hauteurBerge, 4, "#C58F50", this.uitextBerge);
+            gr1.drawSimpleLine(ZF1 + hauteurBerge, ZF2 + hauteurBerge, 4, "#C58F50", this.uitextBerge, false, "#C58F50");
         }
 
         // hauteur normale
         if (this._remousResults.hautNormale?.ok) {
             const Yn = this._remousResults.hautNormale.vCalc;
             gr1.drawSimpleLine(Yn + ZF1, Yn + ZF2,
-                5, "#A4C537", this.uitextTirantNormal
+                5, "#A4C537", this.uitextTirantNormal, false, "#A4C537"
             );
         }
 
@@ -291,7 +291,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         if (this._remousResults.hautCritique?.ok) {
             const Yc = this._remousResults.hautCritique.vCalc;
             gr1.drawSimpleLine(Yc + ZF1, Yc + ZF2,
-                6, "#FF0000", this.uitextTirantCritique
+                6, "#FF0000", this.uitextTirantCritique, false, "#FF0000"
             );
         }
 
-- 
GitLab


From babbde3fd5281867c68de8b362edab968b82851d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Mon, 26 Sep 2022 10:31:16 +0200
Subject: [PATCH 07/11] fix: backwater curves chart: restore extra graph colors

refs #554
---
 .../remous-results.component.ts               | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index e982e1999..4d63c2219 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -348,11 +348,12 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
             }
         }
 
+        const extraLineColor = "#0093BD";
         if (this._remousResults.hasExtra) {
             if (this._remousResults.extraChart) {
                 lineExtra.data = {
                     label: this.extraParamLabel,
-                    tension: 0, spanGaps: true, borderColor: "#0093BD", pointRadius: 4
+                    tension: 0, spanGaps: true, borderColor: extraLineColor
                 };
             } else {
                 lineExtra.data = {
@@ -365,6 +366,9 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         // raccordement ligne fluviale -> torrentielle pour dessiner le ressaut
         this.connectRessaut(lineFlu, lineTor);
 
+        // couleur de la zone sous la ligne
+        const lineAreaColor = "rgba(209,208,212,0.5)";
+
         // ajout des données au graphique
         if (lineTor !== undefined) {
             lineTor.data = {
@@ -373,7 +377,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                 borderColor: "#77A3CD",
                 pointBackgroundColor: "#77A3CD",
                 pointRadius: 4,
-                backgroundColor: "#D1D0D4",
+                backgroundColor: lineAreaColor,
                 showLine: "true"
             };
         }
@@ -384,7 +388,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                 borderColor: "#0093BD",
                 pointBackgroundColor: "#0093BD",
                 pointRadius: 4,
-                backgroundColor: "#D1D0D4",
+                backgroundColor: lineAreaColor,
                 showLine: "true"
             };
         }
@@ -481,7 +485,14 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                 },
                 elements: {
                     line: {
-                        fill: true
+                        fill: true,
+                        backgroundColor: lineAreaColor
+                    },
+                    point: {
+                        pointBorderColor: extraLineColor,
+                        pointBackgroundColor: lineAreaColor,
+                        radius: 4,
+                        borderWidth: 1
                     }
                 }
             };
-- 
GitLab


From 1157093984f50f118e3dc6439a5bb93641420160 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Mon, 26 Sep 2022 14:42:49 +0200
Subject: [PATCH 08/11] fix: graphs: restore zoom with mouse

refs #554
---
 .../jet-trajectory-chart.component.ts         |  8 +++--
 .../pab-profile-chart.component.ts            |  7 +++--
 .../remous-results.component.ts               | 31 +++++++++++++++++++
 .../results-chart/results-chart.component.ts  |  7 +++--
 4 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
index c11af834a..1b3d245c0 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
@@ -10,6 +10,10 @@ import { AppComponent } from "../../app.component";
 
 import { Jet, Result } from "jalhyd";
 
+
+import zoomPlugin from 'chartjs-plugin-zoom';
+import { Chart } from "chart.js";
+
 @Component({
     selector: "jet-trajectory-chart",
     templateUrl: "./jet-trajectory-chart.component.html",
@@ -65,6 +69,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
         private cd: ChangeDetectorRef
     ) {
         super();
+        Chart.register(zoomPlugin);
         // do not move following block out of constructor or scale labels won't be rendered
         this.graph_options["scales"] = {
             x: {
@@ -96,11 +101,10 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective imple
             zoom: {
                 pan: {
                     enabled: false, // conflicts with drag zoom
-                    mode: "xy",
                 },
                 zoom: {
-                    enabled: true,
                     drag: { // conflicts with pan; set to false to enable mouse wheel zoom,
+                        enabled: true,
                         borderColor: "rgba(225,225,225,0.3)",
                         borderWidth: 1,
                         backgroundColor: "rgba(0,0,0,0.25)"
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index b79afc76b..93e057400 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -14,6 +14,9 @@ import { CloisonAval, Cloisons, LoiDebit } from "jalhyd";
 import { sprintf } from "sprintf-js";
 import { CalculatorResults } from 'app/results/calculator-results';
 
+import zoomPlugin from 'chartjs-plugin-zoom';
+import { Chart } from "chart.js";
+
 @Component({
     selector: "pab-profile-chart",
     templateUrl: "./pab-profile-chart.component.html",
@@ -70,6 +73,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
         private cd: ChangeDetectorRef
     ) {
         super();
+        Chart.register(zoomPlugin);
         // do not move following block out of constructor or scale labels won't be rendered
         this.graph_options["scales"] = {
             x: {
@@ -101,11 +105,10 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
             zoom: {
                 pan: {
                     enabled: false, // conflicts with drag zoom
-                    mode: "xy",
                 },
                 zoom: {
-                    enabled: true,
                     drag: { // conflicts with pan; set to false to enable mouse wheel zoom,
+                        enabled: true,
                         borderColor: "rgba(225,225,225,0.3)",
                         borderWidth: 1,
                         backgroundColor: "rgba(0,0,0,0.25)"
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index 4d63c2219..cd6baa78f 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -11,6 +11,8 @@ import { AppComponent } from "../../app.component";
 import { LineData, ChartData } from "./line-and-chart-data";
 import { fv } from "../../util";
 import { VarResults } from "../../results/var-results";
+import zoomPlugin from 'chartjs-plugin-zoom';
+import { Chart } from "chart.js";
 
 @Component({
     selector: "remous-results",
@@ -47,6 +49,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         private formService: FormulaireService
     ) {
         super();
+        Chart.register(zoomPlugin);
     }
 
     public get remousResults() {
@@ -438,6 +441,20 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                             return fv(Number(tooltipItem.formattedValue));
                         }
                     }
+                },
+                zoom: {
+                    pan: {
+                        enabled: false,
+                    },
+                    zoom: {
+                        drag: {
+                            enabled: true,
+                            borderColor: "rgba(225,225,225,0.3)",
+                            borderWidth: 1,
+                            backgroundColor: "rgba(0,0,0,0.25)"
+                        },
+                        mode: 'xy',
+                    }
                 }
             },
             elements: {
@@ -481,6 +498,20 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                                 return fv(Number(tooltipItem.formattedValue));
                             }
                         }
+                    },
+                    zoom: {
+                        pan: {
+                            enabled: false,
+                        },
+                        zoom: {
+                            drag: {
+                                enabled: true,
+                                borderColor: "rgba(225,225,225,0.3)",
+                                borderWidth: 1,
+                                backgroundColor: "rgba(0,0,0,0.25)"
+                            },
+                            mode: 'xy',
+                        }
                     }
                 },
                 elements: {
diff --git a/src/app/components/results-chart/results-chart.component.ts b/src/app/components/results-chart/results-chart.component.ts
index 9821f98e9..ce85c72b2 100644
--- a/src/app/components/results-chart/results-chart.component.ts
+++ b/src/app/components/results-chart/results-chart.component.ts
@@ -14,6 +14,9 @@ import { VarResults } from "../../results/var-results";
 import { fv } from "../../util";
 import { AppComponent } from "../../app.component";
 
+import zoomPlugin from 'chartjs-plugin-zoom';
+import { Chart } from "chart.js";
+
 @Component({
     selector: "results-chart",
     templateUrl: "./results-chart.component.html",
@@ -68,17 +71,17 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         private cd: ChangeDetectorRef
     ) {
         super();
+        Chart.register(zoomPlugin);
         // enable zoom and pan (using "chartjs-plugin-zoom" package)
         const that = this;
         this.graph_options["plugins"] = {
             zoom: {
                 pan: {
                     enabled: false, // conflicts with drag zoom
-                    mode: "xy",
                 },
                 zoom: {
-                    enabled: true,
                     drag: { // conflicts with pan; set to false to enable mouse wheel zoom,
+                        enabled: true,
                         borderColor: "rgba(225,225,225,0.3)",
                         borderWidth: 1,
                         backgroundColor: "rgba(0,0,0,0.25)"
-- 
GitLab


From 3c49a34ca04ffbd76287a916d990ae49a40c5a4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Mon, 26 Sep 2022 15:30:03 +0200
Subject: [PATCH 09/11] fix: graphs: reset zoom not working

refs #554
---
 .../jet-trajectory-chart.component.html                     | 2 +-
 .../jet-trajectory-chart/jet-trajectory-chart.component.ts  | 6 +++---
 .../pab-profile-chart/pab-profile-chart.component.html      | 2 +-
 .../pab-profile-chart/pab-profile-chart.component.ts        | 6 +++---
 .../components/results-chart/results-chart.component.html   | 2 +-
 src/app/components/results-chart/results-chart.component.ts | 6 +++---
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
index 78d2ed8f5..045e8b49d 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
@@ -17,7 +17,7 @@
         </div>
 
         <div *ngIf="! displayChart" class="fake-chart"></div><!-- trick to avoid blinking effect due to forceRebuild -->
-        <canvas baseChart *ngIf="displayChart" type="scatter" [data]="graph_data" [options]="graph_options">
+        <canvas baseChart #chartcanvas="base-chart" *ngIf="displayChart" type="scatter" [data]="graph_data" [options]="graph_options">
         </canvas>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
index 1b3d245c0..5bd87e2bb 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
-import { NgChartsModule } from "ng2-charts";
+import { BaseChartDirective } from "ng2-charts";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
@@ -23,8 +23,8 @@ import { Chart } from "chart.js";
 })
 export class JetTrajectoryChartComponent extends ResultsComponentDirective implements OnChanges {
 
-    @ViewChild(NgChartsModule)
-    private chartComponent;
+    @ViewChild('chartcanvas')
+    private chartComponent: BaseChartDirective;
 
     private _results: Result;
 
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.html b/src/app/components/pab-profile-chart/pab-profile-chart.component.html
index fbc980f17..873035f24 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.html
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.html
@@ -16,7 +16,7 @@
             </button>
         </div>
 
-        <canvas baseChart type="scatter" [data]="graph_data" [options]="graph_options">
+        <canvas baseChart #chartcanvas="base-chart" type="scatter" [data]="graph_data" [options]="graph_options">
         </canvas>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index 93e057400..35c943ea6 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
-import { NgChartsModule } from "ng2-charts";
+import { BaseChartDirective } from "ng2-charts";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
@@ -26,8 +26,8 @@ import { Chart } from "chart.js";
 })
 export class PabProfileChartComponent extends ResultsComponentDirective implements OnChanges {
 
-    @ViewChild(NgChartsModule)
-    private chartComponent;
+    @ViewChild('chartcanvas')
+    private chartComponent: BaseChartDirective;
 
     private _results: PabResults;
 
diff --git a/src/app/components/results-chart/results-chart.component.html b/src/app/components/results-chart/results-chart.component.html
index 3e228f456..8f135402d 100644
--- a/src/app/components/results-chart/results-chart.component.html
+++ b/src/app/components/results-chart/results-chart.component.html
@@ -17,7 +17,7 @@
         </div>
 
         <div *ngIf="! displayChart" class="fake-chart"></div><!-- trick to avoid blinking effect due to forceRebuild -->
-        <canvas baseChart *ngIf="displayChart" [type]="graph_type" [data]="graph_data" [options]="graph_options">
+        <canvas baseChart #chartcanvas="base-chart" *ngIf="displayChart" [type]="graph_type" [data]="graph_data" [options]="graph_options">
         </canvas>
     </div>
 </div>
diff --git a/src/app/components/results-chart/results-chart.component.ts b/src/app/components/results-chart/results-chart.component.ts
index ce85c72b2..bb0c86a01 100644
--- a/src/app/components/results-chart/results-chart.component.ts
+++ b/src/app/components/results-chart/results-chart.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, AfterContentInit, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
-import { NgChartsModule } from "ng2-charts";
+import { BaseChartDirective, NgChartsModule } from "ng2-charts";
 
 import { Observer, ParamFamily, Result } from "jalhyd";
 
@@ -26,8 +26,8 @@ import { Chart } from "chart.js";
 })
 export class ResultsChartComponent extends ResultsComponentDirective implements AfterContentInit, Observer, OnChanges {
 
-    @ViewChild(NgChartsModule)
-    private chartComponent;
+    @ViewChild('chartcanvas')
+    private chartComponent: BaseChartDirective;
 
     private _results: PlottableData;
 
-- 
GitLab


From 1307fac45897c331f8e2fe0292b5fbbf2e5e39ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 28 Sep 2022 09:55:01 +0200
Subject: [PATCH 10/11] fix: avoid unwanted view updates by Angular due to form
 results recreated by getter

refs #554
---
 .../definition/form-courbe-remous.ts          | 34 +++++++++--------
 .../formulaire/definition/form-definition.ts  | 22 ++++++++++-
 .../formulaire/definition/form-fixedvar.ts    | 37 +++++++++++--------
 .../definition/form-macrorugo-compound.ts     | 23 +++++++-----
 src/app/formulaire/definition/form-pab.ts     | 34 ++++++++++-------
 .../formulaire/definition/form-prebarrage.ts  | 36 ++++++++++--------
 .../definition/form-section-parametree.ts     | 21 ++++++-----
 .../definition/form-verificateur.ts           | 10 +++--
 8 files changed, 134 insertions(+), 83 deletions(-)

diff --git a/src/app/formulaire/definition/form-courbe-remous.ts b/src/app/formulaire/definition/form-courbe-remous.ts
index 304fef0ba..3762c846c 100644
--- a/src/app/formulaire/definition/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-courbe-remous.ts
@@ -16,6 +16,7 @@ export class FormulaireCourbeRemous extends FormulaireSection {
     constructor() {
         super();
         this._remousResults = new RemousResults(this);
+        this.updateCalcResults();
         this._props["varCalc"] = ""; // important
     }
 
@@ -27,43 +28,44 @@ export class FormulaireCourbeRemous extends FormulaireSection {
         const cr: CourbeRemous = this.currentNub as CourbeRemous;
         const prmCR: CourbeRemousParams = cr.prms as CourbeRemousParams;
 
-        this.remousResults.parameters = prmCR;
+        this._remousResults.parameters = prmCR;
 
         // variable supplémentaire à calculer
-        this.remousResults.extraParamSymbol = this.currentNub.properties.getPropValue("varCalc");
+        this._remousResults.extraParamSymbol = this.currentNub.properties.getPropValue("varCalc");
 
         // calcul
-        this.remousResults.result = cr.CalcSerie();
+        this._remousResults.result = cr.CalcSerie();
 
         const sect: acSection = cr.Sn;
         this.resultYn = sect.CalcSection("Yn"); // hauteur normale
         this.resultYc = sect.CalcSection("Yc"); // hauteur critique
 
         // données du graphique
-        this.remousResults.hauteurNormale = this.resultYn.resultElement;
-        this.remousResults.hauteurCritique = this.resultYc.resultElement;
-        if (this.remousResults.extraParamSymbol) {
-            this.remousResults.extraChart = ! ["Hs", "Hsc", "Ycor", "Ycon"].includes(this.remousResults.extraParamSymbol);
+        this._remousResults.hauteurNormale = this.resultYn.resultElement;
+        this._remousResults.hauteurCritique = this.resultYc.resultElement;
+        if (this._remousResults.extraParamSymbol) {
+            this._remousResults.extraChart = !["Hs", "Hsc", "Ycor", "Ycon"].includes(this._remousResults.extraParamSymbol);
         } else {
-            this.remousResults.extraChart = false;
+            this._remousResults.extraChart = false;
         }
+        this.updateCalcResults();
     }
 
-    public get remousResults() {
-        return this._remousResults;
+    protected updateCalcResults() {
+        this._calcResults = [];
+        if (this._remousResults) {
+            // ensure help links are propagated
+            this._remousResults.helpLinks = this.helpLinks;
+            this._calcResults.push(this._remousResults);
+        }
     }
 
     public resetFormResults() {
         this._remousResults.reset();
+        this.updateCalcResults();
     }
 
     public get hasResults(): boolean {
         return this._remousResults.hasResults;
     }
-
-    public get results(): CalculatorResults[] {
-        // ensure help links are propagated
-        this._remousResults.helpLinks = this.helpLinks;
-        return [ this._remousResults ];
-    }
 }
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 3fd3ee3a2..bacf4f4d1 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -56,6 +56,15 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     /** copy of options.resultsHelp read by FormDefinition.parseOptions() */
     public helpLinks: { [key: string]: string };
 
+    /*
+    * Propriété destinée à éviter des MAJ intempestives par Angular : avant, le getter public get results()
+    * recréait à chaque appel un tableau CalculatorResults[], ce qui était détecté par Angular
+    * comme un changement même si les résultats stockés dans le tableau n'étaient pas modifiés.
+    *  A présent, _calcResults n'est recréé que si les resultats sont modifiés
+    *  (cf. updateCalcResults()).
+    */
+    protected _calcResults: CalculatorResults[];
+
     constructor(parent?: FormulaireNode) {
         super(parent);
     }
@@ -435,12 +444,23 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
 
     public abstract get hasResults(): boolean;
 
-    public abstract get results(): CalculatorResults[];
+    public get results(): CalculatorResults[] {
+        return this._calcResults;
+    }
+
+    /**
+     * Recrée l'objet retourné par public get results() et
+     * évite des mises à jour par Angular dues à un une détection
+     * de changement causée par le fait que get results() recréait
+     * systématiquement un CalculatorResults[]
+     */
+    protected abstract updateCalcResults();
 
     /**
      * Copies current Nub result into result components for display on page.
      * Should be called every time the Nub result changes.
      * Must be idempotent.
+     * Must call updateCalcResults() at the end.
      */
     protected abstract reaffectResultComponents();
 
diff --git a/src/app/formulaire/definition/form-fixedvar.ts b/src/app/formulaire/definition/form-fixedvar.ts
index 7b596ffbf..575f7cb10 100644
--- a/src/app/formulaire/definition/form-fixedvar.ts
+++ b/src/app/formulaire/definition/form-fixedvar.ts
@@ -25,16 +25,13 @@ export class FormulaireFixedVar extends FormulaireDefinition {
         super(parent);
         this._fixedResults = new FixedResults();
         this._varResults = new VarResults(this);
+        this.updateCalcResults();
     }
 
     public get fixedResults() {
         return this._fixedResults;
     }
 
-    public get varResults() {
-        return this._varResults;
-    }
-
     public get selectids(): string[] {
         return this._selectIds;
     }
@@ -42,9 +39,10 @@ export class FormulaireFixedVar extends FormulaireDefinition {
     public resetFormResults() {
         this._fixedResults.reset();
         this._varResults.reset();
+        this.updateCalcResults();
     }
 
-    public addFixedParameters() {
+    protected addFixedParameters() {
         for (const p of this.getFixedParameters()) {
             this._fixedResults.addFixedParameter(p);
         }
@@ -52,20 +50,26 @@ export class FormulaireFixedVar extends FormulaireDefinition {
 
     public set chartType(t: ChartType) {
         this._varResults.chartType = t;
+        this.updateCalcResults();
     }
 
     public get hasResults(): boolean {
         return this._fixedResults.hasResults || this._varResults.hasResults;
     }
 
-    public get results(): CalculatorResults[] {
-        const res: CalculatorResults[] = [];
+    /**
+     * Recrée l'objet retourné par public get results() et
+     * évite des mises à jour par Angular dues à un une détection
+     * de changement causée par le fait que get results() recréait
+     * systématiquement un CalculatorResults[]
+     */
+    protected updateCalcResults() {
+        this._calcResults = [];
         // ensure help links are propagated
         this._fixedResults.helpLinks = this.helpLinks;
         this._varResults.helpLinks = this.helpLinks;
-        res.push(this._fixedResults);
-        res.push(this._varResults);
-        return res;
+        this._calcResults.push(this._fixedResults);
+        this._calcResults.push(this._varResults);
     }
 
     public afterParseFieldset(fs: FieldSet) {
@@ -120,20 +124,21 @@ export class FormulaireFixedVar extends FormulaireDefinition {
 
         if (varParams.length === 0) {
             // pas de paramètre à varier
-            this.fixedResults.result = nub.result;
+            this._fixedResults.result = nub.result;
             if (computedParam !== undefined) {
-                this.fixedResults.calculatedParameter = computedParam;
+                this._fixedResults.calculatedParameter = computedParam;
             }
         } else {
             // il y a un paramètre à varier
-            this.varResults.variatedParameters = varParams;
+            this._varResults.variatedParameters = varParams;
             if (computedParam !== undefined) {
-                this.varResults.calculatedParameter = computedParam;
+                this._varResults.calculatedParameter = computedParam;
             }
 
-            this.varResults.result = nub.result;
-            this.varResults.update();
+            this._varResults.result = nub.result;
+            this._varResults.update();
         }
+        this.updateCalcResults();
     }
 
     /**
diff --git a/src/app/formulaire/definition/form-macrorugo-compound.ts b/src/app/formulaire/definition/form-macrorugo-compound.ts
index a8cbc7ac6..b28b59b7d 100644
--- a/src/app/formulaire/definition/form-macrorugo-compound.ts
+++ b/src/app/formulaire/definition/form-macrorugo-compound.ts
@@ -18,6 +18,7 @@ export class FormulaireMacrorugoCompound extends FormulaireRepeatableFieldset {
     constructor() {
         super();
         this._mrcResults = new MacrorugoCompoundResults();
+        this.updateCalcResults();
         // default properties
         this._props["inclinedApron"] = MRCInclination.NOT_INCLINED;
     }
@@ -119,18 +120,18 @@ export class FormulaireMacrorugoCompound extends FormulaireRepeatableFieldset {
         const varParams: VariatedDetails[] = this.getVariatedParameters();
 
         // résultat de calcul de la passe à macrorugo complexe
-        const mrcr = this.mrcResults;
-        mrcr.calculatedParameter = computedParam;
-        mrcr.result = mrc.result;
+        this._mrcResults.calculatedParameter = computedParam;
+        this._mrcResults.result = mrc.result;
         if (varParams) {
-            mrcr.variatedParameters = varParams;
+            this._mrcResults.variatedParameters = varParams;
         }
         // résultat de chaque enfant
         const cr: Result[] = [];
         for (const c of mrc.children) {
             cr.push(c.result);
         }
-        mrcr.childrenResults = cr;
+        this._mrcResults.childrenResults = cr;
+        this.updateCalcResults();
     }
 
     public get mrcResults() {
@@ -139,12 +140,16 @@ export class FormulaireMacrorugoCompound extends FormulaireRepeatableFieldset {
 
     public resetFormResults() {
         this._mrcResults.reset();
+        this.updateCalcResults();
     }
 
-    public get results(): CalculatorResults[] {
-        // ensure help links are propagated
-        this._mrcResults.helpLinks = this.helpLinks;
-        return [ this._mrcResults ];
+    protected updateCalcResults() {
+        this._calcResults = [];
+        if (this._mrcResults) {
+            // ensure help links are propagated
+            this._mrcResults.helpLinks = this.helpLinks;
+            this._calcResults.push(this._mrcResults);
+        }
     }
 
     public get hasResults(): boolean {
diff --git a/src/app/formulaire/definition/form-pab.ts b/src/app/formulaire/definition/form-pab.ts
index af9b7f56d..b82eea454 100644
--- a/src/app/formulaire/definition/form-pab.ts
+++ b/src/app/formulaire/definition/form-pab.ts
@@ -17,6 +17,7 @@ export class FormulairePab extends FormulaireDefinition {
     constructor() {
         super();
         this._pabResults = new PabResults();
+        this.updateCalcResults();
     }
 
     public get pabNub(): Pab {
@@ -38,21 +39,20 @@ export class FormulairePab extends FormulaireDefinition {
         const varParams: VariatedDetails[] = this.getVariatedParameters();
 
         // résultat de calcul de la passe à bassins
-        const pabr = this.pabResults;
-        pabr.calculatedParameter = computedParam;
-        pabr.result = pab.result;
+        this._pabResults.calculatedParameter = computedParam;
+        this._pabResults.result = pab.result;
 
         // résultat de chaque cloison
         const cr: Result[] = [];
         for (const c of pab.children) {
             cr.push(c.result);
         }
-        pabr.cloisonsResults = cr;
+        this._pabResults.cloisonsResults = cr;
         // résultat de la cloison aval
-        pabr.cloisonAvalResults = pab.downWall.result;
+        this._pabResults.cloisonAvalResults = pab.downWall.result;
 
         // cote aval de la passe
-        pabr.Z2 = [];
+        this._pabResults.Z2 = [];
         if (varParams.length > 0) {
             // find longest list
             const lvp = longestVarParam(varParams);
@@ -62,20 +62,22 @@ export class FormulairePab extends FormulaireDefinition {
                 const iter = pab.prms.Z2.getExtendedValuesIterator(longest);
                 while (iter.hasNext) {
                     const nv = iter.next();
-                    pabr.Z2.push(nv.value);
+                    this._pabResults.Z2.push(nv.value);
                 }
             } else {
                 for (let i = 0; i < longest; i++) {
-                    pabr.Z2.push(pab.prms.Z2.v);
+                    this._pabResults.Z2.push(pab.prms.Z2.v);
                 }
             }
         } else {
-            pabr.Z2 = [ pab.prms.Z2.singleValue ];
+            this._pabResults.Z2 = [pab.prms.Z2.singleValue];
         }
 
         if (varParams) {
-            pabr.variatedParameters = varParams;
+            this._pabResults.variatedParameters = varParams;
         }
+
+        this.updateCalcResults();
     }
 
     public get pabResults() {
@@ -84,12 +86,16 @@ export class FormulairePab extends FormulaireDefinition {
 
     public resetFormResults() {
         this._pabResults.reset();
+        this.updateCalcResults();
     }
 
-    public get results(): CalculatorResults[] {
-        // ensure help links are propagated
-        this._pabResults.helpLinks = this.helpLinks;
-        return [ this._pabResults ];
+    protected updateCalcResults() {
+        this._calcResults = [];
+        if (this._pabResults) {
+            // ensure help links are propagated
+            this._pabResults.helpLinks = this.helpLinks;
+            this._calcResults.push(this._pabResults);
+        }
     }
 
     public get hasResults(): boolean {
diff --git a/src/app/formulaire/definition/form-prebarrage.ts b/src/app/formulaire/definition/form-prebarrage.ts
index 993a72e8b..8f317caba 100644
--- a/src/app/formulaire/definition/form-prebarrage.ts
+++ b/src/app/formulaire/definition/form-prebarrage.ts
@@ -42,6 +42,7 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
     constructor() {
         super();
         this._pbResults = new PrebarrageResults();
+        this.updateCalcResults();
         this._pbResults.addObserver(this);
     }
 
@@ -53,10 +54,13 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
         return this._pbResults;
     }
 
-    public get results(): CalculatorResults[] {
-        // ensure help links are propagated
-        this._pbResults.helpLinks = this.helpLinks;
-        return [this._pbResults];
+    protected updateCalcResults() {
+        this._calcResults = [];
+        if (this._pbResults) {
+            // ensure help links are propagated
+            this._pbResults.helpLinks = this.helpLinks;
+            this._calcResults.push(this._pbResults);
+        }
     }
 
     public get hasResults(): boolean {
@@ -219,8 +223,7 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
         this.runNubCalc(this.currentNub);
         this.refreshFieldsets(); // important: before reaffectResultComponents() or it will break results components localization
         // reset variable index to avoid trying to access an index > 0 when nothing varies
-        const pbr = this.pbResults;
-        pbr.variableIndex = 0;
+        this._pbResults.variableIndex = 0;
 
         this.reaffectResultComponents();
         this.refreshSchema();
@@ -231,39 +234,41 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
         const computedParam: NgParameter = this.getComputedParameter();
 
         // cacher les résultats
-        this.pbResults.reset();
+        this._pbResults.reset();
         this.addFixedParameters();
 
         // pour le sélecteur d'itérations
         const varParams: VariatedDetails[] = this.getVariatedParameters();
         if (varParams) {
-            this.pbResults.variatedParameters = varParams;
+            this._pbResults.variatedParameters = varParams;
             const lvp = longestVarParam(this._pbResults.variatedParameters);
             this._pbResults.size = lvp.size;
             this._pbResults.cloisonResults.size = lvp.size;
         }
 
-        this.pbResults.result = pb.result;
+        this._pbResults.result = pb.result;
         // résultats selon l'objet sélectionné sur le schéma
         if (this._selectedItem !== undefined && this._selectedItem instanceof PbCloison) {
             // afficher les résultats de cloison
-            this.pbResults.cloisonResults.result = this._selectedItem.result;
+            this._pbResults.cloisonResults.result = this._selectedItem.result;
             if (computedParam !== undefined) {
-                this.pbResults.cloisonResults.calculatedParameter = computedParam;
+                this._pbResults.cloisonResults.calculatedParameter = computedParam;
             }
             // transmission des suffixes de cloisons calculés par l'algo de tri de PbSchemaComponent,
             // pour le sélecteur de conditions limites
             const pbs = this.kids[0] as PbSchema;
-            this.pbResults.wallsSuffixes = pbs.wallsSuffixes;
+            this._pbResults.wallsSuffixes = pbs.wallsSuffixes;
         } else {
             // afficher les résultats des bassins
             // résultat général du Nub (amont, aval, débit)
-            this.pbResults.calculatedParameter = computedParam;
+            this._pbResults.calculatedParameter = computedParam;
             // résultat de chaque bassin
             for (const b of pb.bassins) {
-                this.pbResults.bassinsResults.push(b.result);
+                this._pbResults.bassinsResults.push(b.result);
             }
         }
+
+        this.updateCalcResults();
     }
 
     /**
@@ -282,7 +287,7 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
         }
     }
 
-    public addFixedParameters() {
+    protected addFixedParameters() {
         if (this._selectedItem !== undefined && this._selectedItem instanceof PbCloison) {
             for (const s of this._selectedItem.structures) {
                 for (const p of s.parameterIterator) {
@@ -300,6 +305,7 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
 
     public resetFormResults() {
         this._pbResults.reset();
+        this.updateCalcResults();
     }
 
     public resetResults() {
diff --git a/src/app/formulaire/definition/form-section-parametree.ts b/src/app/formulaire/definition/form-section-parametree.ts
index 743880b5d..7f91f2fca 100644
--- a/src/app/formulaire/definition/form-section-parametree.ts
+++ b/src/app/formulaire/definition/form-section-parametree.ts
@@ -15,6 +15,7 @@ export class FormulaireSectionParametree extends FormulaireSection {
     public constructor() {
         super();
         this._sectionResults = new SectionResults();
+        this.updateCalcResults();
     }
 
     protected compute() {
@@ -43,15 +44,16 @@ export class FormulaireSectionParametree extends FormulaireSection {
             this._sectionResults.result = sectNub.result;
             // résultats complémentaires des paramètres fixés
             this.addFixedParameters();
-            this.fixedResults.result = sectNub.result;
+            this._fixedResults.result = sectNub.result;
         }
-
+        this.updateCalcResults();
     }
 
     public resetFormResults() {
         this._fixedResults.reset();
         this._varResults.reset();
         this._sectionResults.reset();
+        this.updateCalcResults();
     }
 
     public get hasResults(): boolean {
@@ -60,15 +62,16 @@ export class FormulaireSectionParametree extends FormulaireSection {
             || (this._sectionResults?.hasResults);
     }
 
-    public get results(): CalculatorResults[] {
-        const res: CalculatorResults[] = [];
+    protected updateCalcResults() {
+        this._calcResults = [];
         // ensure help links are propagated
         this._fixedResults.helpLinks = this.helpLinks;
         this._varResults.helpLinks = this.helpLinks;
-        this._sectionResults.helpLinks = this.helpLinks;
-        res.push(this._fixedResults);
-        res.push(this._varResults);
-        res.push(this._sectionResults);
-        return res;
+        this._calcResults.push(this._fixedResults);
+        this._calcResults.push(this._varResults);
+        if(this._sectionResults){
+            this._sectionResults.helpLinks = this.helpLinks;
+            this._calcResults.push(this._sectionResults);
+        }
     }
 }
diff --git a/src/app/formulaire/definition/form-verificateur.ts b/src/app/formulaire/definition/form-verificateur.ts
index b357c4a0d..3bcd463a6 100644
--- a/src/app/formulaire/definition/form-verificateur.ts
+++ b/src/app/formulaire/definition/form-verificateur.ts
@@ -16,6 +16,7 @@ export class FormulaireVerificateur extends FormulaireFixedVar {
     constructor() {
         super();
         this._verificateurResults = new VerificateurResults();
+        this.updateCalcResults();
     }
 
     public get verificateurNub(): Verificateur {
@@ -59,14 +60,17 @@ export class FormulaireVerificateur extends FormulaireFixedVar {
             er.push(sp.result);
         }
         vr.especeResults = er;
-    }
 
+        this.updateCalcResults();
+    }
+    
     public resetFormResults() {
         this._verificateurResults.reset();
+        this.updateCalcResults();
     }
 
-    public get results(): CalculatorResults[] {
-        return [ this._verificateurResults ];
+    protected updateCalcResults() {
+        this._calcResults = [this._verificateurResults];
     }
 
     public get hasResults(): boolean {
-- 
GitLab


From e2a115d6e5d039836ae2ef042b5bd2adfb509bbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 28 Sep 2022 18:26:07 +0200
Subject: [PATCH 11/11] feat: backwater curves: add zoom reset to graphs

refs #554
---
 .../remous-results.component.html             | 14 +++--
 .../remous-results.component.ts               | 53 ++++++++++++++++++-
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html
index bdeaafee6..592644d6d 100644
--- a/src/app/components/remous-results/remous-results.component.html
+++ b/src/app/components/remous-results/remous-results.component.html
@@ -2,6 +2,9 @@
     fxLayoutAlign="center center">
     <div fxFlex="1 1 100%">
         <div class="remous-results-buttons">
+            <button mat-icon-button (click)="resetZoom1()" [disabled]="! zoom1WasChanged" [title]="uitextResetZoomTitle">
+                <mat-icon color="primary">replay</mat-icon>
+            </button>
             <button mat-icon-button (click)="exportAsImage(remousResults)" [title]="uitextExportImageTitle">
                 <mat-icon color="primary">image</mat-icon>
             </button>
@@ -14,8 +17,8 @@
             </button>
         </div>
 
-        <canvas baseChart id="main-chart" ngClass.lt-sm="height300" ngClass.sm="height400" ngClass.md="height400"
-            ngClass.gt-md="height600" [type]="graph1_type" [data]="graph1_data" [options]="graph1_options">
+        <canvas baseChart #chartcanvas1="base-chart" id="main-chart" ngClass.lt-sm="height300" ngClass.sm="height400"
+            ngClass.md="height400" ngClass.gt-md="height600" [type]="graph1_type" [data]="graph1_data" [options]="graph1_options">
         </canvas>
     </div>
 </div>
@@ -24,6 +27,9 @@
     fxLayoutAlign="center center">
     <div fxFlex="1 1 100%">
         <div class="remous-results-buttons">
+            <button mat-icon-button (click)="resetZoom2()" [disabled]="! zoom2WasChanged" [title]="uitextResetZoomTitle">
+                <mat-icon color="primary">replay</mat-icon>
+            </button>
             <button mat-icon-button (click)="exportAsImage(remousResultsExtra)" [title]="uitextExportImageTitle">
                 <mat-icon color="primary">image</mat-icon>
             </button>
@@ -36,7 +42,7 @@
             </button>
         </div>
 
-        <canvas baseChart [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></canvas>
+        <canvas baseChart #chartcanvas2="base-chart" [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></canvas>
     </div>
 </div>
 
@@ -47,4 +53,4 @@
 <div *ngIf="hasData">
     <!-- résultats numériques -->
     <var-results [results]=varResults></var-results>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index cd6baa78f..88a38d366 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";
+import { ChangeDetectorRef, Component, Input, OnChanges, SimpleChanges, ViewChild } from "@angular/core";
 
 import { INumberIterator, CourbeRemousParams, CourbeRemous, ParamDefinition, ParamDomainValue, cLog } from "jalhyd";
 
@@ -11,6 +11,8 @@ import { AppComponent } from "../../app.component";
 import { LineData, ChartData } from "./line-and-chart-data";
 import { fv } from "../../util";
 import { VarResults } from "../../results/var-results";
+
+import { BaseChartDirective } from "ng2-charts";
 import zoomPlugin from 'chartjs-plugin-zoom';
 import { Chart } from "chart.js";
 
@@ -25,6 +27,16 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
 
     private _remousResults: RemousResults;
 
+    @ViewChild('chartcanvas1')
+    private chartComponent1: BaseChartDirective;
+
+    @ViewChild('chartcanvas2')
+    private chartComponent2: BaseChartDirective;
+
+    private _zoom1WasChanged = false;
+
+    private _zoom2WasChanged = false;
+
     /*
     * config du graphique principal
     */
@@ -46,7 +58,8 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
 
     constructor(
         private intlService: I18nService,
-        private formService: FormulaireService
+        private formService: FormulaireService,
+        private cd: ChangeDetectorRef
     ) {
         super();
         Chart.register(zoomPlugin);
@@ -398,6 +411,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
 
         this.graph1_data = gr1.data;
 
+        const that = this;
         this.graph1_options = {
             responsive: true,
             maintainAspectRatio: true,
@@ -454,6 +468,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                             backgroundColor: "rgba(0,0,0,0.25)"
                         },
                         mode: 'xy',
+                        onZoomComplete: function (t: any) { return function () { t.zoom1Complete(); }; }(that)
                     }
                 }
             },
@@ -511,6 +526,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                                 backgroundColor: "rgba(0,0,0,0.25)"
                             },
                             mode: 'xy',
+                            onZoomComplete: function (t: any) { return function () { t.zoom2Complete(); }; }(that)
                         }
                     }
                 },
@@ -533,4 +549,37 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
     public exportAsImage(element: HTMLDivElement) {
         AppComponent.exportAsImage(element.querySelector("canvas"));
     }
+
+    public resetZoom1() {
+        this.chartComponent1.chart.resetZoom();
+        this._zoom1WasChanged = false;
+    }
+
+    public resetZoom2() {
+        this.chartComponent2.chart.resetZoom();
+        this._zoom2WasChanged = false;
+    }
+
+    public zoom1Complete() {
+        this._zoom1WasChanged = true;
+        console.log("detect changes");
+        this.cd.detectChanges();
+    }
+
+    public zoom2Complete() {
+        this._zoom2WasChanged = true;
+        this.cd.detectChanges();
+    }
+
+    public get zoom1WasChanged(): boolean {
+        return this._zoom1WasChanged;
+    }
+
+    public get zoom2WasChanged(): boolean {
+        return this._zoom2WasChanged;
+    }
+
+    public get uitextResetZoomTitle() {
+        return this.intlService.localizeText("INFO_CHART_BUTTON_TITLE_RESET_ZOOM");
+    }
 }
-- 
GitLab