diff --git a/package-lock.json b/package-lock.json index 3accb69910f955df51cbfe025e041f79c68e947f..1df2daaff135bdcb9ffa576532a181ac6c10b43d 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 f9a1a962c6fd968d975d6031441cd5e4b91a8fe6..24abe266b331a17b8ed186399cb51f03809b9105 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", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 468ee73c90db11b7388b49f6d0b2adc719a8fe72..7c57cdce8f41945363e18863eb2a1122c4a7b940 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 9bc8e3bb104543f2a70712755bdc96d76ce18226..76aefb4b68bd64ccfc04c2cc4e8570decf0d2de4 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 7f28b26ddab5397d2453fb115a0c019d286b4ba5..a5cc9fcecbac2ac9ab0baa1346c43253a4c73d09 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,34 +107,36 @@ 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: { precision: ResultsComponentDirective.CHARTS_AXIS_PRECISION } - }] + } }, elements: { line: { 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 cedbcf29399b1b64c0fc89833f8b4cbee6e55830..045e8b49d0e2f618fdffee3ed41a358fc950d61b 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 #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 2d726e9f975d19f3075bc924800f867df01a1134..5bd87e2bb12d5177c109a493bcc92517bef823ce 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 { BaseChartDirective } from "ng2-charts"; import { I18nService } from "../../services/internationalisation.service"; import { ResultsComponentDirective } from "../fixedvar-results/results.component"; @@ -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", @@ -19,8 +23,8 @@ import { Jet, Result } from "jalhyd"; }) export class JetTrajectoryChartComponent extends ResultsComponentDirective implements OnChanges { - @ViewChild(ChartComponent) - private chartComponent; + @ViewChild('chartcanvas') + private chartComponent: BaseChartDirective; private _results: Result; @@ -42,14 +46,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: { @@ -63,30 +69,31 @@ 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"] = { - 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") } - }] + } }; // enable zoom and pan (using "chartjs-plugin-zoom" package) const that = this; @@ -94,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)" @@ -110,12 +116,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 +138,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.min/max in generateScatterChart() this._results = r; } @@ -193,8 +199,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.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.html b/src/app/components/pab-profile-chart/pab-profile-chart.component.html index f7c4d9079569cf669e92ffecf1e18d01684b654b..873035f24e062ddb88b2d2fbf3fba87c0fab6fc0 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 #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 449c050ffc94f34685a9aa280756ced6b9b051fc..35c943ea68f282f7571f17e8838c6d2b3a72c303 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 { BaseChartDirective } from "ng2-charts"; import { I18nService } from "../../services/internationalisation.service"; import { ResultsComponentDirective } from "../fixedvar-results/results.component"; @@ -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", @@ -23,8 +26,8 @@ import { CalculatorResults } from 'app/results/calculator-results'; }) export class PabProfileChartComponent extends ResultsComponentDirective implements OnChanges { - @ViewChild(ChartComponent) - private chartComponent; + @ViewChild('chartcanvas') + private chartComponent: BaseChartDirective; private _results: PabResults; @@ -40,21 +43,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: { @@ -68,30 +73,31 @@ 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"] = { - 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") } - }] + } }; // enable zoom and pan (using "chartjs-plugin-zoom" package) const that = this; @@ -99,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)" @@ -115,12 +120,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/line-and-chart-data.ts b/src/app/components/remous-results/line-and-chart-data.ts index c0c7b1d17b1a6292f905fb1de97de6efba3f2e85..433e147f689e97ead4367d5ce43a93ae4b71e2d3 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.html b/src/app/components/remous-results/remous-results.component.html index 7f9efd5fd03a4a8827d85473bc660943f101a7c4..592644d6d1842bba2e88cdc542a4af7f3c6dc0c5 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,9 +17,9 @@ </button> </div> - <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"> - </chart> + <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> - <chart [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></chart> + <canvas baseChart #chartcanvas2="base-chart" [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></canvas> </div> </div> diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts index b753778b459b0fd9db99057765b099cecfc82bc5..88a38d36647ccd4aee85a011001154ac7898e943 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"; @@ -12,6 +12,10 @@ 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"; + @Component({ selector: "remous-results", templateUrl: "./remous-results.component.html", @@ -23,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 */ @@ -44,9 +58,11 @@ export class RemousResultsComponent extends ResultsComponentDirective implements constructor( private intlService: I18nService, - private formService: FormulaireService + private formService: FormulaireService, + private cd: ChangeDetectorRef ) { super(); + Chart.register(zoomPlugin); } public get remousResults() { @@ -272,18 +288,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 +307,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" ); } @@ -348,11 +364,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 +382,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 +393,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements borderColor: "#77A3CD", pointBackgroundColor: "#77A3CD", pointRadius: 4, - backgroundColor: "#D1D0D4", + backgroundColor: lineAreaColor, showLine: "true" }; } @@ -384,25 +404,22 @@ export class RemousResultsComponent extends ResultsComponentDirective implements borderColor: "#0093BD", pointBackgroundColor: "#0093BD", pointRadius: 4, - backgroundColor: "#D1D0D4", + backgroundColor: lineAreaColor, showLine: "true" }; } this.graph1_data = gr1.data; + const that = this; this.graph1_options = { responsive: true, - maintainAspectRatio: false, + maintainAspectRatio: true, animation: { duration: 0 }, - legend: { - display: true, - position: "bottom" - }, scales: { - xAxes: [{ + x: { gridLines: { display: true, color: "rgba(255,99,132,0.2)", @@ -410,29 +427,55 @@ 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)); + } + } + }, + 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', + onZoomComplete: function (t: any) { return function () { t.zoom1Complete(); }; }(that) } } + }, + elements: { + line: { + fill: true + } } }; @@ -445,29 +488,58 @@ 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)); + } } + }, + 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', + onZoomComplete: function (t: any) { return function () { t.zoom2Complete(); }; }(that) + } + } + }, + elements: { + line: { + fill: true, + backgroundColor: lineAreaColor + }, + point: { + pointBorderColor: extraLineColor, + pointBackgroundColor: lineAreaColor, + radius: 4, + borderWidth: 1 } } }; @@ -477,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"); + } } diff --git a/src/app/components/results-chart/results-chart.component.html b/src/app/components/results-chart/results-chart.component.html index be55ade023ec1c2b38630011af12ef652a515152..8f135402d682a7e9a088196130e0d00937ba99b9 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 #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 a547f1097474621a175fdb755fb4b9dd7c2417c1..bb0c86a0120db83f21857ae0ba97d05c204255cf 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 { BaseChartDirective, NgChartsModule } from "ng2-charts"; import { Observer, ParamFamily, Result } from "jalhyd"; @@ -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", @@ -23,8 +26,8 @@ import { AppComponent } from "../../app.component"; }) export class ResultsChartComponent extends ResultsComponentDirective implements AfterContentInit, Observer, OnChanges { - @ViewChild(ChartComponent) - private chartComponent; + @ViewChild('chartcanvas') + private chartComponent: BaseChartDirective; private _results: PlottableData; @@ -47,12 +50,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: { @@ -66,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)" @@ -250,42 +255,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 +352,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 +407,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 +421,7 @@ export class ResultsChartComponent extends ResultsComponentDirective implements } }; // remove legend - this.graph_options.legend = { + this.graph_options.plugins.legend = { display: false }; } diff --git a/src/app/formulaire/definition/form-courbe-remous.ts b/src/app/formulaire/definition/form-courbe-remous.ts index 304fef0ba260451543d63aea3d0a314bbe2efc6d..3762c846cb3fd3c5a11a21d850746f0a024c9074 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 3fd3ee3a274ab1fedb90e0ae8b2c166701210aea..bacf4f4d1ee97117db288b0ac8188008fc68b6ca 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 7b596ffbf07e355a534a3298fc67bdb6a641b07c..575f7cb100cff6c9f2a3061ce3c27f2812f9e747 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 a8cbc7ac605ee477cc3a4bbdfa10e6744b7bdf18..b28b59b7d21e335b8605e9d7b84ce1851eb4836d 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 af9b7f56d9ea67134a0d682678477961df20f646..b82eea4549cd409a9587cfaaad52f0acc9badc96 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 993a72e8b5fe00c3daf93888ba338a5fa12c73e2..8f317caba59b6b5218a157daccf1b6cc6ffd2884 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 743880b5da19f5ae0542af1402223df2537a29db..7f91f2fca963c76ba3e5bae49cfa8adc511afa8b 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 b357c4a0de658da92bac30bb62669bdd13caeb67..3bcd463a65b77779aea4aa3ba7875ddae91adcac 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 {