From 4ae039bce797dce1d84c41615d4c58bb28089129 Mon Sep 17 00:00:00 2001 From: "mathias.chouet" <mathias.chouet@irstea.fr> Date: Wed, 28 Aug 2019 16:24:16 +0200 Subject: [PATCH] MacrorugoCompound: results table --- src/app/app.module.ts | 8 +- .../calculator-results.component.html | 1 + .../calculator-results.component.ts | 10 + .../calculator.component.html | 26 +- .../calculator.component.ts | 16 +- ...rugo-compound-results-table.component.html | 32 ++ ...rugo-compound-results-table.component.scss | 66 ++++ ...rorugo-compound-results-table.component.ts | 117 +++++++ .../macrorugo-compound-results.component.html | 25 ++ .../macrorugo-compound-results.component.scss | 4 + .../macrorugo-compound-results.component.ts | 322 ++++++++++++++++++ .../pab-results/pab-results.component.html | 4 +- .../pab-results/pab-results.component.ts | 16 +- .../variable-results-selector.component.html} | 2 +- .../variable-results-selector.component.scss} | 0 .../variable-results-selector.component.ts} | 34 +- .../concrete/form-macrorugo-compound.ts | 8 +- .../definition/form-compute-fixedvar.ts | 23 -- .../form-compute-macrorugo-compound.ts | 42 +++ .../formulaire/definition/form-compute-pab.ts | 17 +- src/app/formulaire/definition/form-compute.ts | 24 ++ .../form-result-macrorugo-compound.ts | 33 ++ src/app/results/macrorugo-compound-results.ts | 114 +++++++ src/app/results/multidimension-results.ts | 13 + src/app/results/pab-results.ts | 10 +- .../plottable-macrorugo-compound-results.ts | 141 ++++++++ src/locale/messages.en.json | 1 + src/locale/messages.fr.json | 1 + 28 files changed, 1016 insertions(+), 94 deletions(-) create mode 100644 src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html create mode 100644 src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss create mode 100644 src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts create mode 100644 src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html create mode 100644 src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.scss create mode 100644 src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts rename src/app/components/{pab-results/pab-variable-results-selector.component.html => variable-results-selector/variable-results-selector.component.html} (76%) rename src/app/components/{pab-results/pab-variable-results-selector.component.scss => variable-results-selector/variable-results-selector.component.scss} (100%) rename src/app/components/{pab-results/pab-variable-results-selector.component.ts => variable-results-selector/variable-results-selector.component.ts} (71%) create mode 100644 src/app/formulaire/definition/form-compute-macrorugo-compound.ts create mode 100644 src/app/formulaire/definition/form-result-macrorugo-compound.ts create mode 100644 src/app/results/macrorugo-compound-results.ts create mode 100644 src/app/results/multidimension-results.ts create mode 100644 src/app/results/plottable-macrorugo-compound-results.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 26158718f..9b3247c78 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -85,8 +85,10 @@ import { ParamLinkComponent } from "./components/param-link/param-link.component import { SelectModelFieldLineComponent } from "./components/select-model-field-line/select-model-field-line.component"; import { PabProfileGraphComponent } from "./components/pab-profile-graph/pab-profile-graph.component"; import { PabTableComponent } from "./components/pab-table/pab-table.component"; -import { PabVariableResultsSelectorComponent } from "./components/pab-results/pab-variable-results-selector.component"; +import { VariableResultsSelectorComponent } from "./components/variable-results-selector/variable-results-selector.component"; import { QuicknavComponent } from "./components/quicknav/quicknav.component"; +import { MacrorugoCompoundResultsTableComponent } from "./components/macrorugo-compound-results/macrorugo-compound-results-table.component"; +import { MacrorugoCompoundResultsComponent } from "./components/macrorugo-compound-results/macrorugo-compound-results.component"; import { DialogConfirmEmptySessionComponent } from "./components/dialog-confirm-empty-session/dialog-confirm-empty-session.component"; import { DialogConfirmCloseCalcComponent } from "./components/dialog-confirm-close-calc/dialog-confirm-close-calc.component"; @@ -196,7 +198,9 @@ const appRoutes: Routes = [ PabResultsComponent, PabResultsTableComponent, PabTableComponent, - PabVariableResultsSelectorComponent, + VariableResultsSelectorComponent, + MacrorugoCompoundResultsComponent, + MacrorugoCompoundResultsTableComponent, ParamComputedComponent, ParamFieldLineComponent, ParamLinkComponent, diff --git a/src/app/components/calculator-results/calculator-results.component.html b/src/app/components/calculator-results/calculator-results.component.html index be99ed81b..93748fe04 100644 --- a/src/app/components/calculator-results/calculator-results.component.html +++ b/src/app/components/calculator-results/calculator-results.component.html @@ -2,5 +2,6 @@ <section-results></section-results> <remous-results></remous-results> <pab-results></pab-results> + <macrorugo-compound-results></macrorugo-compound-results> <fixedvar-results></fixedvar-results> </div> diff --git a/src/app/components/calculator-results/calculator-results.component.ts b/src/app/components/calculator-results/calculator-results.component.ts index cf74d342c..9dd4576c5 100644 --- a/src/app/components/calculator-results/calculator-results.component.ts +++ b/src/app/components/calculator-results/calculator-results.component.ts @@ -4,6 +4,7 @@ import { FixedVarResultsComponent } from "../../components/fixedvar-results/fixe import { SectionResultsComponent } from "../../components/section-results/section-results.component"; import { RemousResultsComponent } from "../../components/remous-results/remous-results.component"; import { PabResultsComponent } from "../../components/pab-results/pab-results.component"; +import { MacrorugoCompoundResultsComponent } from "../macrorugo-compound-results/macrorugo-compound-results.component"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; @Component({ @@ -37,6 +38,12 @@ export class CalculatorResultsComponent implements AfterViewChecked { @ViewChild(PabResultsComponent, { static: true }) private pabResultsComponent: PabResultsComponent; + /** + * composant d'affichage des résultats des passes à macrorugosités complexes + */ + @ViewChild(MacrorugoCompoundResultsComponent, { static: true }) + private mrcResultsComponent: PabResultsComponent; + /** * événement émis à la fin du dessin de la vue */ @@ -50,11 +57,13 @@ export class CalculatorResultsComponent implements AfterViewChecked { this.sectionResultsComponent.results = undefined; this.remousResultsComponent.results = undefined; this.pabResultsComponent.results = undefined; + this.mrcResultsComponent.results = undefined; } else { this.fixedVarResultsComponent.results = f.results; this.sectionResultsComponent.results = f.results; this.remousResultsComponent.results = f.results; this.pabResultsComponent.results = f.results; + this.mrcResultsComponent.results = f.results; } } @@ -63,6 +72,7 @@ export class CalculatorResultsComponent implements AfterViewChecked { this.sectionResultsComponent.updateView(); this.remousResultsComponent.updateView(); this.pabResultsComponent.updateView(); + this.mrcResultsComponent.updateView(); } public ngAfterViewChecked() { diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html index 3fff1f268..7770790c0 100644 --- a/src/app/components/generic-calculator/calculator.component.html +++ b/src/app/components/generic-calculator/calculator.component.html @@ -29,7 +29,7 @@ </mat-card-header> - <quicknav [fxHide.gt-sm]="! isPAB" [items]="quicknavItems" [currentItem]="'input'" [align]="'left'"></quicknav> + <quicknav [fxHide.gt-sm]="! isWide" [items]="quicknavItems" [currentItem]="'input'" [align]="'left'"></quicknav> <form> @@ -39,15 +39,15 @@ <calc-name id="calculator-name" [title]="uitextCalculatorName"></calc-name> <div id="calc-cards-container" class="container" - [fxLayout]="isPAB ? 'column' : 'row wrap'" - [fxLayoutAlign]="isPAB ? 'space-around stretch' : 'space-around start'"> + [fxLayout]="isWide ? 'column' : 'row wrap'" + [fxLayoutAlign]="isWide ? 'space-around stretch' : 'space-around start'"> <!-- chapitres --> <mat-card id="calc-card-field-sets" - [class.pab-field-sets]="isPAB" - [fxFlex.gt-sm]="isPAB ? '1 0 auto' : '1 0 400px'" - [fxFlex.lt-md]="isPAB ? '1 0 auto' : '1 0 500px'" - [fxFlex.lt-sm]="isPAB ? '1 0 auto' : '1 0 300px'"> + [class.pab-field-sets]="isWide" + [fxFlex.gt-sm]="isWide ? '1 0 auto' : '1 0 400px'" + [fxFlex.lt-md]="isWide ? '1 0 auto' : '1 0 500px'" + [fxFlex.lt-sm]="isWide ? '1 0 auto' : '1 0 300px'"> <ng-template ngFor let-fe [ngForOf]="formElements"> <field-set *ngIf="isFieldset(fe)" [style.display]="getElementStyleDisplay(fe.id)" [fieldSet]=fe @@ -75,16 +75,16 @@ <!-- résultats --> <mat-card id="calc-card-results" - [class.pab-results]="isPAB" - [fxFlex.gt-sm]="isPAB ? '1 0 auto' : '1 0 400px'" - [fxFlex.lt-md]="isPAB ? '1 0 auto' : '1 0 500px'" - [fxFlex.lt-sm]="isPAB ? '1 0 auto' : '1 0 300px'"> + [class.pab-results]="isWide" + [fxFlex.gt-sm]="isWide ? '1 0 auto' : '1 0 400px'" + [fxFlex.lt-md]="isWide ? '1 0 auto' : '1 0 500px'" + [fxFlex.lt-sm]="isWide ? '1 0 auto' : '1 0 300px'"> <div id="fake-results-anchor"></div> - <quicknav [ngClass.lt-xs]="'extraSmall'" [fxHide.gt-sm]="! isPAB" [items]="quicknavItems" [currentItem]="'results'" [align]="'left'"></quicknav> + <quicknav [ngClass.lt-xs]="'extraSmall'" [fxHide.gt-sm]="! isWide" [items]="quicknavItems" [currentItem]="'results'" [align]="'left'"></quicknav> - <mat-card-header *ngIf="! isPAB" [fxHide.lt-md]="! isPAB"> + <mat-card-header *ngIf="! isWide" [fxHide.lt-md]="! isWide"> <mat-card-title> <h1 [innerHTML]="uitextResultsTitle"></h1> </mat-card-title> diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index a686bdf08..19e8926e4 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -205,7 +205,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, public get quicknavItems() { const elts = [ "input", "results" ]; - if (this.isPAB && this.hasResults) { + if (this.isWide && this.hasResults) { elts.push("charts"); } return elts; @@ -470,6 +470,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, } // for "one wide column" layout + public get isWide() { + return (this.isPAB || this.isMRC); + } + + // true if current Nub is PAB public get isPAB() { return ( this._formulaire @@ -478,6 +483,15 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, ); } + // true if current Nub is MacroRugoCompound + public get isMRC() { + return ( + this._formulaire + && this._formulaire.currentNub + && this._formulaire.currentNub.calcType === CalculatorType.MacroRugoCompound + ); + } + // for "generate PAB" button public get isPABCloisons() { return ( diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html new file mode 100644 index 000000000..1e1df2713 --- /dev/null +++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html @@ -0,0 +1,32 @@ +<!-- @TODO copied from var-results.component.html > merge ?--> +<div class="macrorugo-compound-results-table-container" #mrcResultsTable fxLayout="row wrap" fxLayoutAlign="center center"> + <div fxFlex="1 1 100%"> + <div class="macrorugo-compound-results-table-buttons"> + <button mat-icon-button (click)="exportAsSpreadsheet()" [title]="uitextExportAsSpreadsheet"> + <mat-icon color="primary">file_download</mat-icon> + </button> + <button mat-icon-button *ngIf="! isFullscreen" (click)="setFullscreen(mrcResultsTable)" [title]="uitextEnterFSTitle"> + <mat-icon color="primary" class="scaled12">fullscreen</mat-icon> + </button> + <button mat-icon-button *ngIf="isFullscreen" (click)="exitFullscreen()" [title]="uitextExitFSTitle"> + <mat-icon color="primary" class="scaled12">fullscreen_exit</mat-icon> + </button> + </div> + + <div class="macrorugo-compound-results-table-scrollable-container" [ngClass]="{'full-height': isFullscreen}"> + <!-- scrollable --> + <div class="macrorugo-compound-results-table-inner-container" #tableContainer> + + <table mat-table [dataSource]="dataSet"> + <ng-container *ngFor="let h of headers; let i = index" [matColumnDef]="h"> + <th mat-header-cell *matHeaderCellDef>{{ h }}</th> + <td mat-cell *matCellDef="let element" [innerHTML]="element[i]"></td> + </ng-container> + + <tr mat-header-row *matHeaderRowDef="headers"></tr> + <tr mat-row *matRowDef="let row; columns: headers;"></tr> + </table> + </div> + </div> + </div> +</div> diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss new file mode 100644 index 000000000..14c20aa01 --- /dev/null +++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss @@ -0,0 +1,66 @@ +:host { + display: block; + margin-bottom: 1.5em; +} + +.macrorugo-compound-results-table-container { + background-color: white; +} + +.macrorugo-compound-results-table-buttons { + padding-right: 4px; + padding-top: 4px; + text-align: right; + background-color: white; + + button { + margin-left: 3px; + width: auto; + + mat-icon { + &.scaled12 { + transform: scale(1.2) + } + } + } +} + +.macrorugo-compound-results-table-scrollable-container { + overflow-x: scroll; + border: solid #ccc 1px; + + &.full-height { + height: calc(100vh - 40px); // rend le mode plein-écran scrollable verticalement, sinon ça dépasse + } +} + +table.mat-table { + + .mat-header-row { + height: 40px; + } + + .mat-row { + height: 32px; + + &:nth-child(odd) { + background-color: #f4f4f4; + } + } + + ::ng-deep .mat-cell { + padding: 5px; + + .inner-cell-line { + display: block; + white-space: nowrap; + line-height: 20px; + } + } + + ::ng-deep .mat-header-cell { + font-size: 1em; + color: black; + padding: 5px; + } +} diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts new file mode 100644 index 000000000..9102984c0 --- /dev/null +++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts @@ -0,0 +1,117 @@ +import { Component, ViewChild, ElementRef } from "@angular/core"; + +import { MacroRugo } from "jalhyd"; + +import * as XLSX from "xlsx"; + +import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { ResultsComponent } from "../fixedvar-results/results.component"; +import { MacrorugoCompoundResults } from "../../results/macrorugo-compound-results"; + +@Component({ + selector: "macrorugo-compound-results-table", + templateUrl: "./macrorugo-compound-results-table.component.html", + styleUrls: [ + "./macrorugo-compound-results-table.component.scss" + ] +}) +export class MacrorugoCompoundResultsTableComponent extends ResultsComponent { + + /** résultats non mis en forme */ + private _mrcResults: MacrorugoCompoundResults; + + /** entêtes des colonnes */ + private _headers: string[]; + + /** résultats mis en forme */ + private _dataSet: any[]; + + @ViewChild("tableContainer", { static: false }) + table: ElementRef; + + constructor( + protected appSetupService: ApplicationSetupService, + protected intlService: I18nService + ) { + super(); + } + + public set results(r: MacrorugoCompoundResults) { + this._mrcResults = r; + + this._dataSet = []; + if ( + this._mrcResults + && this._mrcResults.childrenResults + && this._mrcResults.childrenResults.length > 0 + && ! this._mrcResults.hasOnlyErrors() + ) { + const pr = this._mrcResults; + const nDigits = this.appSetupService.displayDigits; + // when a parameter is variating, index of the variating parameter + // values to build the data from + const vi = pr.variableIndex; + + // refresh headers here if language changed + this._headers = pr.headers; + + // lines 1 - n-1 + for (let i = 0; i < pr.childrenResults.length; i++) { + if ( + pr.childrenResults[i].resultElements[vi].vCalc + ) { + const res = pr.childrenResults[i].resultElements[vi].values; + const nub = (pr.childrenResults[i].sourceNub as MacroRugo); + this._dataSet.push([ + i + 1, // n° radier + nub.prms.ZF1.singleValue.toFixed(nDigits), // @TODO what if ZF1 or B varies ? + nub.prms.B.singleValue.toFixed(nDigits), + res.Q.toFixed(nDigits), + res.ZF2.toFixed(nDigits), + res.Vdeb.toFixed(nDigits), + res.Fr.toFixed(nDigits), + res.Vmax.toFixed(nDigits), + res.PV.toFixed(nDigits), + this.intlService.localizeText("INFO_ENUM_MACRORUGOFLOWTYPE_" + res.ENUM_MacroRugoFlowType), + res.Q_GuideTech.toFixed(nDigits), + (res.V_GuideTech !== undefined ? res.V_GuideTech.toFixed(nDigits) : "-"), + res.xCenter.toFixed(nDigits) + ]); + } + } + } + } + + public get headers() { + return this._headers; + } + + /** + * Returns a combination of parameters and results for mat-table + */ + public get dataSet() { + return this._dataSet; + } + + public exportAsSpreadsheet() { + // automagic <table> extraction + const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(this.table.nativeElement); + const wb: XLSX.WorkBook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, "default"); + // save and download + XLSX.writeFile(wb, "MacrorugoCompoundResults.xlsx"); + } + + public get uitextExportAsSpreadsheet() { + return this.intlService.localizeText("INFO_RESULTS_EXPORT_AS_SPREADSHEET"); + } + + public get uitextEnterFSTitle() { + return this.intlService.localizeText("INFO_GRAPH_BUTTON_TITLE_ENTER_FS"); + } + + public get uitextExitFSTitle() { + return this.intlService.localizeText("INFO_GRAPH_BUTTON_TITLE_EXIT_FS"); + } +} diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html new file mode 100644 index 000000000..9d29b23ea --- /dev/null +++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html @@ -0,0 +1,25 @@ +<div class="container"> + + <log #generalLog [logTitle]="uitextGeneralLogTitle">log général</log> + + <variable-results-selector [results]="mrcResults" (indexChange)="variableIndexChanged()"> + </variable-results-selector> + + <log #iterationLog></log> + + <div> + <!-- tableau de résultats --> + <macrorugo-compound-results-table *ngIf="hasDisplayableResults" [results]="mrcResults"></macrorugo-compound-results-table> + </div> + + <quicknav *ngIf="hasDisplayableResults" [items]="[ 'input', 'results', 'charts' ]" + [currentItem]="'charts'" [align]="'left'"></quicknav> + + <div id="macrorugo-compound-graphs-container" class="container" fxLayout="row wrap" fxLayoutAlign="space-around start"> + <!-- <pab-profile-graph *ngIf="hasDisplayableResults" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px"> + </pab-profile-graph> --> + <!-- <results-graph *ngIf="hasDisplayableResults" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px"> + </results-graph> --> + </div> + +</div> diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.scss b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.scss new file mode 100644 index 000000000..6f5eb10d5 --- /dev/null +++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.scss @@ -0,0 +1,4 @@ +results-graph { + margin-left: 1em; + margin-right: 1em; +} diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts new file mode 100644 index 000000000..db564243e --- /dev/null +++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts @@ -0,0 +1,322 @@ +import { Component, ViewChild, DoCheck } from "@angular/core"; + +import { Result, cLog, Message, MessageCode, MessageSeverity } from "jalhyd"; + +import { LogComponent } from "../../components/log/log.component"; +import { CalculatorResults } from "../../results/calculator-results"; +import { NgParameter } from "../../formulaire/ngparam"; +import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; +import { PlottableData } from "../../results/plottable-data"; +import { ResultsGraphComponent } from "../results-graph/results-graph.component"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { VariableResultsSelectorComponent } from "../variable-results-selector/variable-results-selector.component"; +import { MacrorugoCompoundResultsTableComponent } from "./macrorugo-compound-results-table.component"; +import { MacrorugoCompoundResults } from "../../results/macrorugo-compound-results"; +import { PlottableMacrorugoCompoundResults } from "../../results/plottable-macrorugo-compound-results"; + +@Component({ + selector: "macrorugo-compound-results", + templateUrl: "./macrorugo-compound-results.component.html", + styleUrls: [ + "./macrorugo-compound-results.component.scss" + ] +}) +export class MacrorugoCompoundResultsComponent implements DoCheck { + + /** résultats non mis en forme */ + private _mrcResults: MacrorugoCompoundResults; + + /** résultats mis en forme pour le graphique de données (classique) */ + private _plottableResults: PlottableMacrorugoCompoundResults; + + /** true si les résultats doiventt être remis à jour */ + private _doUpdate = false; + + @ViewChild(MacrorugoCompoundResultsTableComponent, { static: false }) + private mrcResultsTableComponent: MacrorugoCompoundResultsTableComponent; + + @ViewChild(VariableResultsSelectorComponent, { static: false }) + private variableResultsSelectorComponent: VariableResultsSelectorComponent; + + @ViewChild("generalLog", { static: false }) + private generalLogComponent: LogComponent; + + @ViewChild("iterationLog", { static: false }) + private iterationLogComponent: LogComponent; + + @ViewChild(ResultsGraphComponent, { static: false }) + private resultsGraphComponent: ResultsGraphComponent; + + constructor( + private appSetupService: ApplicationSetupService, + private i18nService: I18nService, + ) { + this._plottableResults = new PlottableMacrorugoCompoundResults(); + } + + public set results(rs: CalculatorResults[]) { + this._mrcResults = undefined; + if (rs.length > 0 && rs[0] instanceof MacrorugoCompoundResults) { + this._mrcResults = rs[0] as MacrorugoCompoundResults; + } + this.updateView(); + } + + /** + * update results table and chart when the variable index changed (event sent by + * VariableResultsSelectorComponent); variable index is already set in + * mrcResults at this time + */ + public variableIndexChanged() { + this.updateView(); + } + + public updateView() { + if (this.iterationLogComponent) { + this.iterationLogComponent.log = undefined; + } + if (this.generalLogComponent) { + this.generalLogComponent.log = undefined; + } + if (this.mrcResultsTableComponent) { + this.mrcResultsTableComponent.results = undefined; + } + if (this.variableResultsSelectorComponent) { + this.variableResultsSelectorComponent.results = undefined; + } + if (this.resultsGraphComponent) { + this.resultsGraphComponent.results = undefined; + } + // set _doUpdate flag so that results are rebuilt on the next Angular display cycle + this._doUpdate = false; + if (this._mrcResults !== undefined) { + this._doUpdate = this._doUpdate || this._mrcResults.hasResults || this._mrcResults.hasLog; + } + } + + public ngDoCheck() { + if (this._doUpdate) { + this._doUpdate = !this.updateResults(); + } + } + + private mergeGlobalLog(result: Result, log: cLog) { + if (result) { + if (result.hasGlobalLog()) { + log.addLog(result.globalLog); + } + // if no parameter is varying, 1st element log is considered "global" + if (this.mrcResults.variatedParameters.length === 0) { + if (result.hasResultElements() && result.resultElement.hasLog()) { + log.addLog(result.log); + } + } + } + } + + /** + * Returns the number of errors, warnings, infos among children logs + */ + private logStats(): any { + const ret = { + info: 0, + warning: 0, + error: 0 + }; + if (this._mrcResults.result && this._mrcResults.result.hasLog()) { + for (const re of this._mrcResults.result.resultElements) { + if (re.hasLog()) { + for (const m of re.log.messages) { + const s = m.getSeverity(); + switch (s) { + case MessageSeverity.INFO: + ret.info ++; + break; + case MessageSeverity.WARNING: + ret.warning ++; + break; + case MessageSeverity.ERROR: + ret.error ++; + break; + } + } + } + } + } + for (const cr of this._mrcResults.childrenResults) { + if (cr && cr.hasLog()) { + for (const re of cr.resultElements) { + if (re.hasLog()) { + for (const m of re.log.messages) { + const s = m.getSeverity(); + switch (s) { + case MessageSeverity.INFO: + ret.info ++; + break; + case MessageSeverity.WARNING: + ret.warning ++; + break; + case MessageSeverity.ERROR: + ret.error ++; + break; + } + } + } + } + } + } + return ret; + } + + /* + * Retourne les logs à afficher dans le composant de log global, au dessus + * du sélecteur d'itération : messages globaux et / ou résumé des messages + * spécifiques à chaque ResultElement + */ + private get globalLog(): cLog { + const l = new cLog(); + if (this._mrcResults && this.mrcResults.variatedParameters.length > 0) { + this.mergeGlobalLog(this._mrcResults.result, l); + // un problème avec la MRC en général / les cloisons, à une étape quelconque ? + if ( + (this.mrcResults.hasLog) + && l.messages.length === 0 // existing global messages make generic message below useless + ) { + const logStats = this.logStats(); + const m = new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED); + m.extraVar.info = "" + logStats.info; // to avoid displaying fixed number of digits + m.extraVar.warning = "" + logStats.warning; + m.extraVar.error = "" + logStats.error; + l.add(m); + // l.add(new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED)); + } + } // sinon pas de log global (aucun paramètre ne varie) + return l; + } + + /** + * Retourne les logs à afficher dans le composant de log global, au dessus + * du sélecteur d'itération : messages globaux et / ou résumé des messages + * spécifiques à chaque ResultElement + */ + private get iterationLog(): cLog { + const l = new cLog(); + if (this._mrcResults) { + if (this.mrcResults.variatedParameters.length > 0) { + // A. si un paramètre varie + const vi = this._mrcResults.variableIndex; + // log de la MRC pour l'itération en cours + if ( + this._mrcResults.result + && this._mrcResults.result.hasResultElements() + && this._mrcResults.result.resultElements[vi] + && this._mrcResults.result.resultElements[vi].hasLog() + ) { + l.addLog(this._mrcResults.result.resultElements[vi].log); + } + // logs des enfants pour l'itération en cours + for (const cr of this._mrcResults.childrenResults) { + if (cr && cr.hasResultElements() && cr.resultElements[vi].hasLog()) { + l.addLog(cr.resultElements[vi].log); + } + } + } else { + // B. si aucun paramètre ne varie + this.mergeGlobalLog(this._mrcResults.result, l); // faut bien mettre le log global quelque part + // logs des enfants + for (const cr of this._mrcResults.childrenResults) { + if (cr && cr.hasResultElements() && cr.resultElement.hasLog()) { + l.addLog(cr.resultElement.log); + } + } + } + } + return l; + } + + /** + * met à jour l'affichage des résultats + * @returns true si les résultats ont pu être mis à jour + */ + private updateResults() { + let mrcUpdated: boolean; + let resultsGraphUpdated: boolean; + let profileGraphUpdated: boolean; + let selectorUpdated: boolean; + + // results or not, there might be a log + const logUpdated = (this.iterationLogComponent !== undefined || this.generalLogComponent !== undefined); // gne ? + if (logUpdated) { + // order of logs is important ! + this.iterationLogComponent.log = this.iterationLog; + this.generalLogComponent.log = this.globalLog; + } + + console.log("update ====>", this._mrcResults); + if (this.hasResults) { + mrcUpdated = this.mrcResultsTableComponent !== undefined; + if (mrcUpdated) { + this.mrcResultsTableComponent.results = this._mrcResults; + } + selectorUpdated = this.variableResultsSelectorComponent !== undefined; + if (selectorUpdated) { + this.variableResultsSelectorComponent.results = this._mrcResults; + } + resultsGraphUpdated = this.resultsGraphComponent !== undefined; + if (resultsGraphUpdated) { + this.resultsGraphComponent.results = this.plottableResults; + this.resultsGraphComponent.updateView(); + } + } else { + mrcUpdated = true; + resultsGraphUpdated = true; + profileGraphUpdated = true; + selectorUpdated = true; + } + + return mrcUpdated && logUpdated && resultsGraphUpdated && profileGraphUpdated && selectorUpdated; + } + + public get mrcResults() { + return this._mrcResults; + } + + public formattedLabel(p: NgParameter): string { + return CalculatorResults.paramLabel(p, false); + } + + public formattedValue(p: NgParameter): string { + const nDigits = this.appSetupService.displayDigits; + return p.getValue().toFixed(nDigits); + } + + public get hasResults(): boolean { + return this._mrcResults && this._mrcResults.hasResults; + } + + public get hasDisplayableResults(): boolean { + let ret = this._mrcResults && this._mrcResults.hasResults; + if ( + this._mrcResults + && this._mrcResults.variatedParameters + && this._mrcResults.variatedParameters.length > 0 + ) { + ret = ret + && this._mrcResults.variableIndex !== undefined + && this._mrcResults.result.resultElements[this._mrcResults.variableIndex] !== undefined + && this._mrcResults.result.resultElements[this._mrcResults.variableIndex].ok; + } + return ret; + } + + public get uitextGeneralLogTitle(): string { + return this.i18nService.localizeText("INFO_TITREJOURNAL_GLOBAL"); + } + + /** builds a set of PlottableData from MacrorugoCompoundResults, to feed the graph */ + protected get plottableResults(): PlottableData { + this._plottableResults.setMrcResults(this.mrcResults); + return this._plottableResults; + } + +} diff --git a/src/app/components/pab-results/pab-results.component.html b/src/app/components/pab-results/pab-results.component.html index 2e31dc126..d601347bd 100644 --- a/src/app/components/pab-results/pab-results.component.html +++ b/src/app/components/pab-results/pab-results.component.html @@ -2,8 +2,8 @@ <log #generalLog [logTitle]="uitextGeneralLogTitle">log général</log> - <pab-variable-results-selector [results]="pabResults" (indexChange)="variableIndexChanged()"> - </pab-variable-results-selector> + <variable-results-selector [results]="pabResults" (indexChange)="variableIndexChanged()"> + </variable-results-selector> <log #iterationLog></log> diff --git a/src/app/components/pab-results/pab-results.component.ts b/src/app/components/pab-results/pab-results.component.ts index 510867ca6..fefa3a36b 100644 --- a/src/app/components/pab-results/pab-results.component.ts +++ b/src/app/components/pab-results/pab-results.component.ts @@ -8,12 +8,13 @@ import { NgParameter } from "../../formulaire/ngparam"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; import { PabResultsTableComponent } from "./pab-results-table.component"; import { PabResults } from "../../results/pab-results"; -import { PabVariableResultsSelectorComponent } from "./pab-variable-results-selector.component"; +import { VariableResultsSelectorComponent } from "../variable-results-selector/variable-results-selector.component"; import { PlottableData } from "../../results/plottable-data"; import { PlottablePabResults } from "../../results/plottable-pab-results"; import { ResultsGraphComponent } from "../results-graph/results-graph.component"; import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { PabProfileGraphComponent } from "../pab-profile-graph/pab-profile-graph.component"; +import { VarResults } from "../../results/var-results"; @Component({ selector: "pab-results", @@ -36,8 +37,8 @@ export class PabResultsComponent implements DoCheck { @ViewChild(PabResultsTableComponent, { static: false }) private pabResultsTableComponent: PabResultsTableComponent; - @ViewChild(PabVariableResultsSelectorComponent, { static: false }) - private pabVariableResultsSelectorComponent: PabVariableResultsSelectorComponent; + @ViewChild(VariableResultsSelectorComponent, { static: false }) + private variableResultsSelectorComponent: VariableResultsSelectorComponent; @ViewChild("generalLog", { static: false }) private generalLogComponent: LogComponent; @@ -85,8 +86,8 @@ export class PabResultsComponent implements DoCheck { if (this.pabResultsTableComponent) { this.pabResultsTableComponent.results = undefined; } - if (this.pabVariableResultsSelectorComponent) { - this.pabVariableResultsSelectorComponent.results = undefined; + if (this.variableResultsSelectorComponent) { + this.variableResultsSelectorComponent.results = undefined; } if (this.resultsGraphComponent) { this.resultsGraphComponent.results = undefined; @@ -272,6 +273,7 @@ export class PabResultsComponent implements DoCheck { * @returns true si les résultats ont pu être mis à jour */ private updateResults() { + console.log("UPD RES PAB", this._pabResults); let pabUpdated: boolean; let resultsGraphUpdated: boolean; let profileGraphUpdated: boolean; @@ -290,9 +292,9 @@ export class PabResultsComponent implements DoCheck { if (pabUpdated) { this.pabResultsTableComponent.results = this._pabResults; } - selectorUpdated = this.pabVariableResultsSelectorComponent !== undefined; + selectorUpdated = this.variableResultsSelectorComponent !== undefined; if (selectorUpdated) { - this.pabVariableResultsSelectorComponent.results = this._pabResults; + this.variableResultsSelectorComponent.results = this._pabResults; } resultsGraphUpdated = this.resultsGraphComponent !== undefined; if (resultsGraphUpdated) { diff --git a/src/app/components/pab-results/pab-variable-results-selector.component.html b/src/app/components/variable-results-selector/variable-results-selector.component.html similarity index 76% rename from src/app/components/pab-results/pab-variable-results-selector.component.html rename to src/app/components/variable-results-selector/variable-results-selector.component.html index c02043692..757776ab8 100644 --- a/src/app/components/pab-results/pab-variable-results-selector.component.html +++ b/src/app/components/variable-results-selector/variable-results-selector.component.html @@ -1,4 +1,4 @@ -<div class="pab-variable-results-selector" *ngIf="hasVariableResults" fxLayout="row wrap" fxLayoutAlign="center center"> +<div class="pabvariable-results-selector" *ngIf="hasVariableResults" fxLayout="row wrap" fxLayoutAlign="center center"> <div fxFlex="1 1 100%"> <mat-form-field> <mat-select id="pab-variating-element" [placeholder]="label" [(value)]="selectedValue"> diff --git a/src/app/components/pab-results/pab-variable-results-selector.component.scss b/src/app/components/variable-results-selector/variable-results-selector.component.scss similarity index 100% rename from src/app/components/pab-results/pab-variable-results-selector.component.scss rename to src/app/components/variable-results-selector/variable-results-selector.component.scss diff --git a/src/app/components/pab-results/pab-variable-results-selector.component.ts b/src/app/components/variable-results-selector/variable-results-selector.component.ts similarity index 71% rename from src/app/components/pab-results/pab-variable-results-selector.component.ts rename to src/app/components/variable-results-selector/variable-results-selector.component.ts index 4986bfbf8..901c77ebb 100644 --- a/src/app/components/pab-results/pab-variable-results-selector.component.ts +++ b/src/app/components/variable-results-selector/variable-results-selector.component.ts @@ -1,20 +1,20 @@ import { Component, Output, EventEmitter } from "@angular/core"; -import { PabResults } from "../../results/pab-results"; import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; +import { MultiDimensionResults } from "../../results/multidimension-results"; @Component({ - selector: "pab-variable-results-selector", - templateUrl: "./pab-variable-results-selector.component.html", + selector: "variable-results-selector", + templateUrl: "./variable-results-selector.component.html", styleUrls: [ - "./pab-variable-results-selector.component.scss" + "./variable-results-selector.component.scss" ] }) -export class PabVariableResultsSelectorComponent { +export class VariableResultsSelectorComponent { /** résultats non mis en forme */ - private _pabResults: PabResults; + private _results: MultiDimensionResults; private _selectedValue: number; @@ -34,23 +34,23 @@ export class PabVariableResultsSelectorComponent { this._selectedValue = 0; } - public set results(r: PabResults) { - this._pabResults = r; + public set results(r: MultiDimensionResults) { + this._results = r; - if (this._pabResults) { + if (this._results) { // pre-extract variable parameters values this.varValues = []; const nDigits = this.appSetupService.displayDigits; // find longest list this.size = 0; - for (let i = 0; i < this._pabResults.variatedParameters.length; i++) { - const vs = this._pabResults.variatedParameters[i].valuesIterator.count(); + for (let i = 0; i < this._results.variatedParameters.length; i++) { + const vs = this._results.variatedParameters[i].valuesIterator.count(); if (vs > this.size) { this.size = vs; } } // get extended values lists for each variable parameter - for (const v of this._pabResults.variatedParameters) { + for (const v of this._results.variatedParameters) { const vv = []; const iter = v.getExtendedValuesIterator(this.size); while (iter.hasNext) { @@ -64,9 +64,9 @@ export class PabVariableResultsSelectorComponent { public get hasVariableResults(): boolean { return ( - this._pabResults - && this._pabResults.hasResults - && this._pabResults.variatedParameters.length > 0 + this._results + && this._results.hasResults + && this._results.variatedParameters.length > 0 ); } @@ -81,7 +81,7 @@ export class PabVariableResultsSelectorComponent { protected entryLabel(index: number): string { let i = 0; return this.varValues.map((vv) => { - const vp = this._pabResults.variatedParameters[i]; + const vp = this._results.variatedParameters[i]; i++; let value = "0"; value = vv[index]; @@ -94,7 +94,7 @@ export class PabVariableResultsSelectorComponent { } public set selectedValue(v: number) { - this._pabResults.variableIndex = v; + this._results.variableIndex = v; this.indexChange.emit(); } diff --git a/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts b/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts index 3d62b3b50..7f495c4d7 100644 --- a/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts +++ b/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts @@ -1,13 +1,13 @@ import { IObservable, MacroRugo, MacrorugoCompound, Nub, Props, Session } from "jalhyd"; import { FormulaireBase } from "./form-base"; -import { FormResultFixedVar } from "../form-result-fixedvar"; -import { FormComputeFixedVar } from "../form-compute-fixedvar"; import { FieldSet } from "../../fieldset"; import { FieldsetContainer } from "../../fieldset-container"; import { FormulaireNode } from "../../formulaire-node"; import { FieldsetTemplate } from "../../fieldset-template"; import { NgParameter } from "../../ngparam"; +import { FormResultMacrorugoCompound } from "../form-result-macrorugo-compound"; +import { FormComputeMacrorugoCompound } from "../form-compute-macrorugo-compound"; /** * Formulaire pour les passes à macrorugosités complexes @@ -19,14 +19,14 @@ export class FormulaireMacrorugoCompound extends FormulaireBase { constructor() { super(); - this._formResult = new FormResultFixedVar(this); + this._formResult = new FormResultMacrorugoCompound(this); // default properties this._props["inclinedApron"] = false; // remove obsolete observer set by super() this.removeObserver(this._formCompute); - this._formCompute = new FormComputeFixedVar(this, (this._formResult as FormResultFixedVar)); + this._formCompute = new FormComputeMacrorugoCompound(this, (this._formResult as FormResultMacrorugoCompound)); } public get mrcNub(): MacrorugoCompound { diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts index ede113a8f..ba74fda4f 100644 --- a/src/app/formulaire/definition/form-compute-fixedvar.ts +++ b/src/app/formulaire/definition/form-compute-fixedvar.ts @@ -14,29 +14,6 @@ export class FormComputeFixedVar extends FormCompute { return this._formResult as FormResultFixedVar; } - private getVariatedParameters(): NgParameter[] { - let res: NgParameter[] = []; - // find variated local parameters - res = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.VAR); - // add variated linked parameters - const pms = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.LINK); - for (const p of pms) { - if (p.paramDefinition.hasMultipleValues) { - res.push(p); - } - } - return res; - } - - private getComputedParameter(): NgParameter { - const cpd = this._formBase.currentNub.calculatedParam; - let ngparam = this._formBase.getParamFromSymbol(cpd.symbol); - if (ngparam === undefined) { // calculated parameter is not displayed on screen - ngparam = new NgParameter(cpd, this._formBase); - } - return ngparam; - } - protected compute() { this.runNubCalc(this._formBase.currentNub); this.reaffectResultComponents(); diff --git a/src/app/formulaire/definition/form-compute-macrorugo-compound.ts b/src/app/formulaire/definition/form-compute-macrorugo-compound.ts new file mode 100644 index 000000000..4b6de1561 --- /dev/null +++ b/src/app/formulaire/definition/form-compute-macrorugo-compound.ts @@ -0,0 +1,42 @@ +import { Result, MacrorugoCompound } from "jalhyd"; + +import { FormulaireDefinition } from "./form-definition"; +import { FormCompute } from "./form-compute"; +import { FormResultMacrorugoCompound } from "./form-result-macrorugo-compound"; +import { NgParameter, ParamRadioConfig } from "../ngparam"; + +export class FormComputeMacrorugoCompound extends FormCompute { + + constructor(formBase: FormulaireDefinition, formResult: FormResultMacrorugoCompound) { + super(formBase, formResult); + } + + protected get formResult(): FormResultMacrorugoCompound { + return this._formResult as FormResultMacrorugoCompound; + } + + protected compute() { + this.runNubCalc(this._formBase.currentNub); + this.reaffectResultComponents(); + } + + protected reaffectResultComponents() { + const mrc: MacrorugoCompound = (this._formBase.currentNub as MacrorugoCompound); + const computedParam: NgParameter = this.getComputedParameter(); + const varParams: NgParameter[] = this.getVariatedParameters(); + + // résultat de calcul de la passe à macrorugo complexe + const mrcr = this.formResult.mrcResults; + mrcr.calculatedParameter = computedParam; + mrcr.result = mrc.result; + if (varParams) { + mrcr.variatedParameters = varParams; + } + // résultat de chaque enfant + const cr: Result[] = []; + for (const c of mrc.children) { + cr.push(c.result); + } + mrcr.childrenResults = cr; + } +} diff --git a/src/app/formulaire/definition/form-compute-pab.ts b/src/app/formulaire/definition/form-compute-pab.ts index bcde3d155..445ad0b5d 100644 --- a/src/app/formulaire/definition/form-compute-pab.ts +++ b/src/app/formulaire/definition/form-compute-pab.ts @@ -15,17 +15,6 @@ export class FormComputePab extends FormCompute { return this._formResult as FormResultPab; } - private getVariatedParameters(): NgParameter[] { - const res = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.VAR); - const pms = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.LINK); - for (const p of pms) { - if (p.paramDefinition.hasMultipleValues) { - res.push(p); - } - } - return res; - } - protected compute() { this.runNubCalc(this._formBase.currentNub); this.reaffectResultComponents(); @@ -46,7 +35,7 @@ export class FormComputePab extends FormCompute { for (const c of pab.children) { cr.push(c.result); } - pabr.cloisonsResults = cr, + pabr.cloisonsResults = cr; // résultat de la cloison aval pabr.cloisonAvalResults = pab.downWall.result; @@ -74,8 +63,4 @@ export class FormComputePab extends FormCompute { pabr.variatedParameters = varParams; } } - - private getComputedParameter(): NgParameter { - return this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL); - } } diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts index af5c587cd..14a21c5d6 100644 --- a/src/app/formulaire/definition/form-compute.ts +++ b/src/app/formulaire/definition/form-compute.ts @@ -2,6 +2,7 @@ import { Nub, Result, ParamDomainValue, Observer, ParamDefinition } from "jalhyd import { FormResult } from "./form-result"; import { FormulaireDefinition } from "./form-definition"; +import { NgParameter, ParamRadioConfig } from "../ngparam"; export abstract class FormCompute implements Observer { @@ -91,6 +92,29 @@ export abstract class FormCompute implements Observer { return nub.CalcSerie(init, this.getParameterRefid(computedParam)); } + protected getComputedParameter(): NgParameter { + const cpd = this._formBase.currentNub.calculatedParam; + let ngparam = this._formBase.getParamFromSymbol(cpd.symbol); + if (ngparam === undefined) { // calculated parameter is not displayed on screen + ngparam = new NgParameter(cpd, this._formBase); + } + return ngparam; + } + + protected getVariatedParameters(): NgParameter[] { + let res: NgParameter[] = []; + // find variated local parameters + res = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.VAR); + // add variated linked parameters + const pms = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.LINK); + for (const p of pms) { + if (p.paramDefinition.hasMultipleValues) { + res.push(p); + } + } + return res; + } + /** * Triggers computation of the Nub, updates form results */ diff --git a/src/app/formulaire/definition/form-result-macrorugo-compound.ts b/src/app/formulaire/definition/form-result-macrorugo-compound.ts new file mode 100644 index 000000000..73ba7e9d2 --- /dev/null +++ b/src/app/formulaire/definition/form-result-macrorugo-compound.ts @@ -0,0 +1,33 @@ +import { FormulaireDefinition } from "./form-definition"; +import { FormResult } from "./form-result"; +import { CalculatorResults } from "../../results/calculator-results"; +import { MacrorugoCompoundResults } from "../../results/macrorugo-compound-results"; + +export class FormResultMacrorugoCompound extends FormResult { + + protected _formBase: FormulaireDefinition; + + protected _mrcResults: MacrorugoCompoundResults; + + constructor(base: FormulaireDefinition) { + super(); + this._formBase = base; + this._mrcResults = new MacrorugoCompoundResults(); + } + + public get mrcResults() { + return this._mrcResults; + } + + public resetResults() { + this._mrcResults.reset(); + } + + public get results(): CalculatorResults[] { + return [ this._mrcResults ]; + } + + public get hasResults(): boolean { + return this._mrcResults.hasResults; + } +} diff --git a/src/app/results/macrorugo-compound-results.ts b/src/app/results/macrorugo-compound-results.ts new file mode 100644 index 000000000..ec1275b92 --- /dev/null +++ b/src/app/results/macrorugo-compound-results.ts @@ -0,0 +1,114 @@ +import { Result } from "jalhyd"; + +import { ServiceFactory } from "../services/service-factory"; +import { MultiDimensionResults } from "./multidimension-results"; + +export class MacrorugoCompoundResults extends MultiDimensionResults { + + /** résultats des modules MacroRugo enfants */ + public childrenResults: Result[]; + + /** symboles des colonnes de résultat */ + protected _columns: string[]; + + public constructor() { + super(); + this.reset(); + // standard headers + this._columns = [ + "RADIER_N", + "ZF1", + "B", + "Q", + "ZF2", + "Vdeb", + "Fr", + "Vmax", + "PV", + "ENUM_MacroRugoFlowType", + "Q_GuideTech", + "V_GuideTech", + "xCenter" + ]; + } + + /** headers symbols */ + public get columns() { + return this._columns; + } + + /** translated headers texts */ + public get headers() { + return this._columns.map((h) => { + // calculator type for translation + const sn = this.result.sourceNub; + let ct = sn.calcType; + if (sn.parent) { + ct = sn.parent.calcType; + } + return ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct , h); + }); + } + + public reset() { + super.reset(); + this.childrenResults = []; + } + + /** + * Returns true if at least one log message is present in the PAB result or any + * of the children results + */ + public get hasLog(): boolean { + if (this.childrenResults) { + for (const cr of this.childrenResults) { + if (cr && cr.hasLog()) { + return true; + } + } + } + return (this.result && this.result.hasLog()); + } + + // do not test result.ok else log messages will prevent partial results from being displayed + public get hasResults(): boolean { + return this.result !== undefined && ! this.result.hasOnlyErrors; + } + + /** retourne true si au moins un calcul a échoué (le log a un code négatif) */ + public hasError(): boolean { + let err = false; + // log principal + err = (err || this.result.hasErrorMessages()); + // logs des enfants + for (const c of this.childrenResults) { + err = (err || c.hasErrorMessages()); + } + + return err; + } + + /** retourne true si le calcul à l'itération i a échoué */ + public iterationHasError(i: number): boolean { + let err = this.result.resultElements[i].hasErrorMessages(); + // logs des cloisons + for (const c of this.childrenResults) { + err = (err || c.resultElements[i].hasErrorMessages()); + } + + return err; + } + + /** retourne true si tous les calculs ont échoué */ + public hasOnlyErrors(): boolean { + let err = true; + // log principal + err = (err && this.result.hasOnlyErrors); + // logs des cloisons + for (const c of this.childrenResults) { + err = (err && c.hasOnlyErrors); + } + + return err; + } +} diff --git a/src/app/results/multidimension-results.ts b/src/app/results/multidimension-results.ts new file mode 100644 index 000000000..86c42164c --- /dev/null +++ b/src/app/results/multidimension-results.ts @@ -0,0 +1,13 @@ +import { CalculatedParamResults } from "./param-calc-results"; +import { PlottableData } from "./plottable-data"; +import { NgParameter } from "../formulaire/ngparam"; + + +export class MultiDimensionResults extends CalculatedParamResults/* implements PlottableData */ { + + /** paramètres variés */ + public variatedParameters: NgParameter[]; + + /** index de la valeur du paramètre varié à afficher dans les résultats */ + public variableIndex = 0; +} diff --git a/src/app/results/pab-results.ts b/src/app/results/pab-results.ts index a81d37158..d407ae8a4 100644 --- a/src/app/results/pab-results.ts +++ b/src/app/results/pab-results.ts @@ -1,10 +1,10 @@ import { Result } from "jalhyd"; -import { CalculatedParamResults } from "./param-calc-results"; import { NgParameter } from "../formulaire/ngparam"; import { ServiceFactory } from "../services/service-factory"; +import { MultiDimensionResults } from "./multidimension-results"; -export class PabResults extends CalculatedParamResults { +export class PabResults extends MultiDimensionResults { /** résultats des modules Cloisons avant chaque bassin */ public cloisonsResults: Result[]; @@ -18,12 +18,6 @@ export class PabResults extends CalculatedParamResults { * */ public Z2: number[]; - /** paramètres variés */ - public variatedParameters: NgParameter[]; - - /** index de la valeur du paramètre varié à afficher dans les résultats */ - public variableIndex = 0; - /** symboles des colonnes de résultat */ protected _columns: string[]; diff --git a/src/app/results/plottable-macrorugo-compound-results.ts b/src/app/results/plottable-macrorugo-compound-results.ts new file mode 100644 index 000000000..0be1264f1 --- /dev/null +++ b/src/app/results/plottable-macrorugo-compound-results.ts @@ -0,0 +1,141 @@ +import { PlottableData } from "./plottable-data"; +import { GraphType } from "./graph-type"; +import { ServiceFactory } from "../services/service-factory"; +import { MacrorugoCompoundResults } from "./macrorugo-compound-results"; + +export class PlottableMacrorugoCompoundResults implements PlottableData { + + public graphType: GraphType = GraphType.Scatter; + public chartX: string; + public chartY: string; + + protected mrcResults: MacrorugoCompoundResults; + + public constructor(mrcResults?: MacrorugoCompoundResults) { + if (mrcResults) { + this.setMrcResults(mrcResults); + } + // axes par défaut + this.chartX = this.chartX || "CLOISON"; + this.chartY = this.chartY || "YMOY"; + } + + /** reaffect mrcResults, for ex. when objet was contructed with empty mrcResults */ + public setMrcResults(mrcResults: MacrorugoCompoundResults) { + this.mrcResults = mrcResults; + } + + /** + * Returns the label to display, for an element of getAvailableChartAxis() + * @param symbol parameter / result symbol (ex: "Q") + */ + public getChartAxisLabel(symbol: string): string { + if (symbol === "x") { // specific case for wall abscissa + return ServiceFactory.instance.i18nService.localizeText("INFO_LIB_ABSCISSE_CLOISON"); + } else { + return this.mrcResults.headers[this.mrcResults.columns.indexOf(symbol)]; + } + } + + public expandLabelFromSymbol(symbol: string): string { + return symbol; + } + + /** + * Returns a list of plottable parameters / result elements, that can be defined + * as X or Y chart axis + */ + public getAvailableChartAxis(): string[] { + const axis = []; + axis.push("x"); // wall abscissa + for (const c of this.mrcResults.columns) { + if (c.indexOf("ENUM_") === -1) { // ENUM variables are not plottable + axis.push(c); + } + } + return axis; + } + + public getAvailableXAxis(): string[] { + return this.getAvailableChartAxis(); + } + + public getAvailableYAxis(): string[] { + return this.getAvailableChartAxis(); + } + + // just to implement interface + public getVariatingParametersSymbols(): string[] { + return []; + } + + /** + * Returns the series of values for the required symbol + * @param symbol parameter / result symbol (ex: "Q") + */ + public getValuesSeries(symbol: string): number[] { + const data: number[] = []; + const pr = this.mrcResults; + const l = this.mrcResults.childrenResults.length; + // when a parameter is variating, index of the variating parameter + // values to build the data from + const vi = this.mrcResults.variableIndex; + + if (this.mrcResults.iterationHasError(vi)) { + return []; + } + + switch (symbol) { + case "RADIER_N": + data.push(undefined); + for (let i = 0; i <= l; i++) { // <= for one extra step (downwall) + data.push(i + 1); + } + break; + + case "DH": + case "ZRAM": + /* case "Q": + data.push(undefined); + for (let i = 0; i < l; i++) { + const er = pr.cloisonsResults[i].resultElements[vi].getValue(symbol); + data.push(er); + } + const zrAval = pr.cloisonAvalResults.resultElements[vi].getValue(symbol); + data.push(zrAval); + break; + + case "Z": + for (let i = 0; i < l; i++) { + data.push(pr.cloisonsResults[i].resultElements[vi].vCalc); + } + data.push(pr.cloisonAvalResults.resultElements[vi].vCalc); + data.push(pr.Z2[vi]); + break; */ + + case "PV": + case "YMOY": + case "ZRMB": + case "QA": + data.push(undefined); + for (let i = 0; i < l; i++) { + const er = pr.childrenResults[i].resultElements[vi].getValue(symbol); + data.push(er); + } + data.push(undefined); + break; + + /* case "x": // wall abscissa + data.push(undefined); + for (let i = 0; i < l; i++) { + const er = pr.cloisonsResults[i].resultElements[vi].getValue(symbol); + data.push(er); + } + const erXdw = pr.cloisonAvalResults.resultElements[vi].getValue(symbol); + data.push(erXdw); + break; */ + } + + return data; + } +} diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 2a22bfec4..adcc569ba 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -217,6 +217,7 @@ "INFO_LIB_R": "Hydraulic radius", "INFO_LIB_S": "Orifice area", "INFO_LIB_RADIER": "Basin bottom", + "INFO_LIB_RADIER_N": "Apron #", "INFO_LIB_SELECT_LOIDEBIT": "Stage-discharge law", "INFO_LIB_SELECT_LOIDEBIT1_KIVI": "Kindsvater-Carter and Villemonte", "INFO_LIB_SELECT_LOIDEBIT1": "Stage-discharge law", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index 7155a166c..e5c5de4bf 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -215,6 +215,7 @@ "INFO_LIB_QA": "Débit d'attrait", "INFO_LIB_R": "Rayon hydraulique", "INFO_LIB_RADIER": "Radier", + "INFO_LIB_RADIER_N": "Radier n°", "INFO_LIB_S": "Surface de l'orifice", "INFO_LIB_SELECT_LOIDEBIT": "Loi de débit", "INFO_LIB_SELECT_LOIDEBIT1_KIVI": "Kindsvater-Carter et Villemonte", -- GitLab