From b703c7e26b4f92789dfdfcee4a72994862b0e4f3 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Tue, 16 Jan 2018 17:36:35 +0100 Subject: [PATCH 01/10] =?UTF-8?q?ticket=20#47=20:=20ajout=20d'un=20mode=20?= =?UTF-8?q?"liste=20de=20valeur"=20pour=20les=20param=C3=A8tres=20=C3=A0?= =?UTF-8?q?=20varier=20-=20composants=20NgParamMinComponent,=20NgParamMaxC?= =?UTF-8?q?omponent,=20NgParamStepComponent=20chacun=20dans=20leur=20fichi?= =?UTF-8?q?er=20-=20cr=C3=A9ation=20d'un=20composant=20ValueListComponent?= =?UTF-8?q?=20pour=20g=C3=A9rer=20le=20"mode=20min/max/pas"=20et=20"liste?= =?UTF-8?q?=20de=20valeurs"=20-=20NgParameter=20:=20ajout=20d'un=20enum=20?= =?UTF-8?q?pour=20indiquer=20le=20mode=20de=20g=C3=A9n=C3=A9ration=20des?= =?UTF-8?q?=20valeurs=20=C3=A0=20varier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.module.ts | 7 +- .../param-field-line.component.html | 12 +- .../param-field-line.component.ts | 365 +----------------- src/app/formulaire/formulaire-definition.ts | 45 ++- src/app/formulaire/ngparam.ts | 17 + src/index.html | 4 +- 6 files changed, 60 insertions(+), 390 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c7a5daded..cdec1aedb 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -16,7 +16,11 @@ import { ApplicationSetupService } from "./services/app-setup/app-setup.service" import { AppComponent } from './app.component'; import { NgParamInputComponent } from './components/ngparam-input/ngparam-input.component'; import { FieldSetComponent } from './components/field-set/field-set.component'; -import { ParamFieldLineComponent, NgParamMinComponent, NgParamMaxComponent, NgParamStepComponent } from './components/param-field-line/param-field-line.component'; +import { ParamFieldLineComponent } from './components/param-field-line/param-field-line.component'; +import { NgParamMinComponent } from './components/param-values/ngparam-min.component'; +import { NgParamMaxComponent } from './components/param-values/ngparam-max.component'; +import { NgParamStepComponent } from './components/param-values/ngparam-step.component'; +import { ParamValuesComponent, ValueListComponent } from './components/param-values/param-values.component'; import { SelectFieldLineComponent } from './components/select-field-line/select-field-line.component'; import { CheckFieldLineComponent } from './components/check-field-line/check-field-line.component'; // import { AlertDialog } from './components/alert-dialog/alert-dialog.component'; @@ -62,6 +66,7 @@ const appRoutes: Routes = [ NgParamInputComponent, FieldSetComponent, ParamFieldLineComponent, NgParamMinComponent, NgParamMaxComponent, NgParamStepComponent, + ParamValuesComponent, ValueListComponent, SelectFieldLineComponent, CheckFieldLineComponent, LogComponent, CalculatorListComponent, diff --git a/src/app/components/param-field-line/param-field-line.component.html b/src/app/components/param-field-line/param-field-line.component.html index 7b34c4ecd..753b689b3 100644 --- a/src/app/components/param-field-line/param-field-line.component.html +++ b/src/app/components/param-field-line/param-field-line.component.html @@ -29,14 +29,4 @@ </div> </div> -<div *ngIf="isRadioVarChecked" class="row"> - <div class="col-12 col-sm-4"> - <ngparam-min [title]="uitextValeurMini" (onChange)="onMinChanged($event)"></ngparam-min> - </div> - <div class="col-12 col-sm-4"> - <ngparam-max [title]="uitextValeurMaxi" (onChange)="onMaxChanged($event)"></ngparam-max> - </div> - <div class="col-12 col-sm-4"> - <ngparam-step [title]="uitextPasVariation" (onChange)="onStepChanged($event)"></ngparam-step> - </div> -</div> \ No newline at end of file +<param-values *ngIf="isRadioVarChecked" [param]="_param"></param-values> \ No newline at end of file diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts index eaea2232e..6e7a402ee 100644 --- a/src/app/components/param-field-line/param-field-line.component.ts +++ b/src/app/components/param-field-line/param-field-line.component.ts @@ -1,229 +1,9 @@ -import { Component, ViewChild, Input, Output, DoCheck, EventEmitter } from "@angular/core"; - -import { NumericalString, ParamDomainValue, Pair } from "jalhyd"; +import { Component, ViewChild, Input, Output, EventEmitter } from "@angular/core"; import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam"; import { GenericInputComponent } from "../generic-input/generic-input.component"; -@Component({ - selector: "ngparam-min", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class NgParamMinComponent extends GenericInputComponent { - /** - * valeur actuelle du minimum - */0.49999999995 - private _currentValue: number; - - /** - * reférence (valeur mini pour le minimum) - */ - private _refValue: Pair; - - @Output() - private onChange = new EventEmitter<string>(); - - public isInit: boolean; - - constructor(private intlService: InternationalisationService) { - super(); - } - - public set refValue(v: Pair) { - this._refValue = v; - } - - protected getModelValue(): any { - return this._currentValue; - } - - protected setModelValue(v: any) { - this._currentValue = v; - this.onChange.emit("value"); - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg = undefined; - let valid = false; - - if (!this._refValue.intervalHasValue(v)) - msg = "La valeur n'est pas dans " + this._refValue.toString(); - else - valid = true; - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - if (typeof (v) == "number") - return String(v); - return undefined; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid: boolean = false; - let msg: string = undefined; - - let v: NumericalString = new NumericalString(ui); - if (!v.isNumerical) - msg = "Veuillez entrer une valeur numérique"; - else - valid = true; - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string): any { - return +ui; - } -} - -@Component({ - selector: "ngparam-max", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class NgParamMaxComponent extends GenericInputComponent { - /** - * valeur actuelle du maximum - */ - private _currentValue: number; - - /** - * reférence (valeur maxi pour le maximum) - */ - private _refValue: Pair; - - @Output() - private onChange = new EventEmitter<string>(); - - constructor(private intlService: InternationalisationService) { - super(); - } - - public set refValue(v: Pair) { - this._refValue = v; - } - - protected getModelValue(): any { - return this._currentValue; - } - - protected setModelValue(v: any) { - this._currentValue = v; - this.onChange.emit("value"); - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg = undefined; - let valid = false; - - if (!this._refValue.intervalHasValue(v)) - msg = "La valeur n'est pas dans " + this._refValue.toString(); - else - valid = true; - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - if (typeof (v) == "number") - return String(v); - return undefined; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid: boolean = false; - let msg: string = undefined; - - let v: NumericalString = new NumericalString(ui); - if (!v.isNumerical) - msg = "Veuillez entrer une valeur numérique"; - else - valid = true; - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - return +ui; - } -} - -@Component({ - selector: "ngparam-step", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class NgParamStepComponent extends GenericInputComponent { - /** - * valeur actuelle du pas - */ - private _currentValue: number; - - /** - * reférence (valeur maxi pour le pas) - */ - private _refValue: Pair; - - @Output() - private onChange = new EventEmitter<string>(); - - constructor(private intlService: InternationalisationService) { - super(); - } - - public set refValue(v: Pair) { - this._refValue = v; - } - - protected getModelValue(): any { - return this._currentValue; - } - - protected setModelValue(v: any) { - this._currentValue = v; - this.onChange.emit("value"); - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg = undefined; - let valid = false; - - if (!this._refValue.intervalHasValue(v)) - msg = "La valeur n'est pas dans " + this._refValue.toString(); - else { - valid = v > 0; - if (!valid) - msg = "La valeur ne peut pas être <= 0"; - } - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - if (typeof (v) == "number") - return String(v); - return "<invalid>"; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid: boolean = false; - let msg: string = undefined; - - let v: NumericalString = new NumericalString(ui); - if (!v.isNumerical) - msg = "Veuillez entrer une valeur numérique"; - else - valid = true; - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - return +ui; - } -} - @Component({ selector: "param-field-line", templateUrl: "./param-field-line.component.html", @@ -244,142 +24,13 @@ export class NgParamStepComponent extends GenericInputComponent { }` ] }) -export class ParamFieldLineComponent implements DoCheck { +export class ParamFieldLineComponent { @Input("param") private _param: NgParameter; - /** - * composant de saisie du minimum - */ - @ViewChild(NgParamMinComponent) - private _minComponent: NgParamMinComponent; - - /** - * composant de saisie du maximum - */ - @ViewChild(NgParamMaxComponent) - private _maxComponent: NgParamMaxComponent; - - /** - * composant de saisie du pas de variation - */ - @ViewChild(NgParamStepComponent) - private _stepComponent: NgParamStepComponent; - constructor(private intlService: InternationalisationService) { } - private getDefaultMin(): number { - switch (this._param.domain.domain) { - case ParamDomainValue.ANY: - case ParamDomainValue.NOT_NULL: - return -10; - - default: - return this._param.domain.minValue; - } - } - - private getDefaultMax(): number { - switch (this._param.domain.domain) { - case ParamDomainValue.INTERVAL: - return this._param.domain.maxValue; - - default: - return 10; - } - } - - private initMinMaxStep() { - // valeur pour min (celle déjà définie ou celle déduite du domaine de définition) - let min: number = this._param.minValue; - let ok = min != undefined - if (ok) { - try { - // on la vérifie - this._param.checkValue(min); - ok = true; - } - catch (e) { - ok = false; - } - } - if (!ok) - min = this.getDefaultMin(); - - // valeur pour max (celle déjà définie ou celle déduite du domaine de définition) - let max: number = this._param.maxValue; - ok = max != undefined - if (ok) { - try { - // on la vérifie - this._param.checkValue(max); - ok = true; - } - catch (e) { - ok = false; - } - } - if (!ok) - min = this.getDefaultMax(); - - this._minComponent.refValue = new Pair(this._param.domain.minValue, max); - this._minComponent.model = min; - - this._maxComponent.refValue = new Pair(min, this._param.domain.maxValue); - this._maxComponent.model = max; - - this.updateStepComponentRef(); - - let step = this._param.stepValue; - if (step == undefined) - step = (max - min) / 20; - if (min == -Infinity || max == Infinity) - step = 10; - this._stepComponent.model = step; - } - - private onMinChanged(val: string) { - this.updateStepComponentRef(); - - this._maxComponent.refValue = new Pair(this._minComponent.model, this._param.domain.maxValue); - this._maxComponent.validateModel(); - - if (this._minComponent.validateModel()) - this._param.minValue = this._minComponent.model; - } - - private onMaxChanged(val: string) { - this.updateStepComponentRef(); - - this._minComponent.refValue = new Pair(this._param.domain.minValue, this._maxComponent.model); - this._minComponent.validateModel(); - - if (this._maxComponent.validateModel()) - this._param.maxValue = this._maxComponent.model; - } - - private onStepChanged(val: string) { - if (this._stepComponent.validateModel()) - this._param.stepValue = this._stepComponent.model; - } - - public ngDoCheck() { - // initialisation des champs min/max/step à l'apparition de ces contrôles - if (this._minComponent != undefined && !this._minComponent.isInit) { - this._minComponent.isInit = true; - this.initMinMaxStep(); - } - } - - /** - * met à jour la valeur de référence du composant gérant le pas de variation - */ - private updateStepComponentRef() { - this._stepComponent.refValue = new Pair(1e-9, this._maxComponent.model - this._minComponent.model); - this._stepComponent.validateModel(); - } - private get title(): string { let t = ""; if (this._param.label != undefined) @@ -397,18 +48,6 @@ export class ParamFieldLineComponent implements DoCheck { return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER"); } - private get uitextValeurMini() { - return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMINI"); - } - - private get uitextValeurMaxi() { - return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMAXI"); - } - - private get uitextPasVariation() { - return this.intlService.localizeText("INFO_PARAMFIELD_PASVARIATION"); - } - private get uitextParamCalculer() { return this.intlService.localizeText("INFO_PARAMFIELD_PARAMCALCULER"); } diff --git a/src/app/formulaire/formulaire-definition.ts b/src/app/formulaire/formulaire-definition.ts index 00fe09485..fc847e626 100644 --- a/src/app/formulaire/formulaire-definition.ts +++ b/src/app/formulaire/formulaire-definition.ts @@ -7,7 +7,7 @@ import { ParamService } from "../services/param/param.service"; import { InternationalisationService } from "../services/internationalisation/internationalisation.service"; import { ApplicationSetupService } from "../services/app-setup/app-setup.service"; import { Field } from "./field"; -import { NgParameter, ParamRadioConfig } from "./ngparam"; +import { NgParameter, ParamRadioConfig, ParamValueMode } from "./ngparam"; import { InputField } from "./input-field"; import { CheckField } from "./check-field"; import { SelectField } from "./select-field"; @@ -1117,20 +1117,39 @@ export class FormulaireDefinition extends Observable { this._fixVarResults.setVariableParamHeaderFromParameter(varParam, !rg); this._fixVarResults.setVariableResultHeaderFromParameter(computedParam); - let min: number = +varParam.minValue; - let max: number = +varParam.maxValue; - let step: number = +varParam.stepValue; + switch (varParam.valueMode) { + case ParamValueMode.MINMAX: + let min: number = +varParam.minValue; + let max: number = +varParam.maxValue; + let step: number = +varParam.stepValue; - for (let val = min; val <= max; val += step) { - prms[varParam.symbol].v = val; + for (let val = min; val <= max; val += step) { + prms[varParam.symbol].v = val; - let res: Result = this.runNubCalc(nub, computedParam, computePrec); - if (res.ok) { - this._fixVarResults.addVarResult(val, res.vCalc); - } - else { - this._fixVarResults.addLogMessages(res.log); - } + let res: Result = this.runNubCalc(nub, computedParam, computePrec); + if (res.ok) { + this._fixVarResults.addVarResult(val, res.vCalc); + } + else { + this._fixVarResults.addLogMessages(res.log); + } + } + break; + + case ParamValueMode.LISTE: + for (let val of varParam.valueList) { + prms[varParam.symbol].v = val; + + let res: Result = this.runNubCalc(nub, computedParam, computePrec); + if (res.ok) { + this._fixVarResults.addVarResult(val, res.vCalc); + } + else { + this._fixVarResults.addLogMessages(res.log); + } + } + + break; } this._fixVarResults.graphTitle = computedParam.symbol + " = f( " + varParam.symbol + " )"; diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index 2db893c26..703ac0696 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -24,6 +24,21 @@ export enum ParamRadioConfig { }; +/** + * mode de génération des valeurs d'entrée lors d'un calcul avec plusieurs valeurs + */ +export enum ParamValueMode { + /** + * min, max, pas + */ + MINMAX, + + /** + * liste de valeurs discrètes + */ + LISTE +} + /** * classe englobante de ParamDefinition (champs supplémentaires pour l'affichage, radio boutons, ...) */ @@ -35,6 +50,8 @@ export class NgParameter extends InputField { public minValue: number; // valeur min dans le cas ParamRadioConfig.VAR public maxValue: number; // valeur max dans le cas ParamRadioConfig.VAR public stepValue: number; // pas de progression dans le cas ParamRadioConfig.VAR + public valueList: number[]; + public valueMode: ParamValueMode = ParamValueMode.MINMAX; constructor(private _paramDef: ParamDefinition, formId: number) { super(_paramDef.computeNodeType, _paramDef.symbol, formId); diff --git a/src/index.html b/src/index.html index 100a73f14..ec92ef2fa 100644 --- a/src/index.html +++ b/src/index.html @@ -14,8 +14,8 @@ <!-- ressources pour faire fonctionner le toggler de la navbar --> <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script> - <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" - crossorigin="anonymous"></script> --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" + crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script> -- GitLab From d4de914c5f0508647d8d829f82a52bc2458e1d0b Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Tue, 16 Jan 2018 17:47:05 +0100 Subject: [PATCH 02/10] =?UTF-8?q?ticket=20#47=20:=20ajout=20du=20r=C3=A9pe?= =?UTF-8?q?rtoire=20src/app/components/param-values/=20oubli=C3=A9=20dans?= =?UTF-8?q?=20le=20commit=20pr=C3=A9c=C3=A9dent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../param-values/ngparam-max.component.ts | 77 +++++ .../param-values/ngparam-min.component.ts | 79 +++++ .../param-values/ngparam-step.component.ts | 80 +++++ .../param-values/param-values.component.html | 24 ++ .../param-values/param-values.component.ts | 321 ++++++++++++++++++ 5 files changed, 581 insertions(+) create mode 100644 src/app/components/param-values/ngparam-max.component.ts create mode 100644 src/app/components/param-values/ngparam-min.component.ts create mode 100644 src/app/components/param-values/ngparam-step.component.ts create mode 100644 src/app/components/param-values/param-values.component.html create mode 100644 src/app/components/param-values/param-values.component.ts diff --git a/src/app/components/param-values/ngparam-max.component.ts b/src/app/components/param-values/ngparam-max.component.ts new file mode 100644 index 000000000..1db61f59a --- /dev/null +++ b/src/app/components/param-values/ngparam-max.component.ts @@ -0,0 +1,77 @@ +import { Component, Output, EventEmitter } from "@angular/core"; + +import { NumericalString, Pair } from "jalhyd"; + +import { GenericInputComponent } from "../generic-input/generic-input.component"; +import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "ngparam-max", + templateUrl: "../generic-input/generic-input.component.html" +}) +export class NgParamMaxComponent extends GenericInputComponent { + /** + * valeur actuelle du maximum + */ + private _currentValue: number; + + /** + * reférence (valeur maxi pour le maximum) + */ + private _refValue: Pair; + + @Output() + private onChange = new EventEmitter<string>(); + + constructor(private intlService: InternationalisationService) { + super(); + } + + public set refValue(v: Pair) { + this._refValue = v; + } + + protected getModelValue(): any { + return this._currentValue; + } + + protected setModelValue(v: any) { + this._currentValue = v; + this.onChange.emit("value"); + } + + protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg = undefined; + let valid = false; + + if (!this._refValue.intervalHasValue(v)) + msg = "La valeur n'est pas dans " + this._refValue.toString(); + else + valid = true; + + return { isValid: valid, message: msg }; + } + + protected modelToUI(v: any): string { + if (typeof (v) == "number") + return String(v); + return undefined; + } + + protected validateUIValue(ui: string): { isValid: boolean, message: string } { + let valid: boolean = false; + let msg: string = undefined; + + let v: NumericalString = new NumericalString(ui); + if (!v.isNumerical) + msg = "Veuillez entrer une valeur numérique"; + else + valid = true; + + return { isValid: valid, message: msg }; + } + + protected uiToModel(ui: string) { + return +ui; + } +} diff --git a/src/app/components/param-values/ngparam-min.component.ts b/src/app/components/param-values/ngparam-min.component.ts new file mode 100644 index 000000000..ca6749eb4 --- /dev/null +++ b/src/app/components/param-values/ngparam-min.component.ts @@ -0,0 +1,79 @@ +import { Component, Output, EventEmitter } from "@angular/core"; + +import { NumericalString, Pair } from "jalhyd"; + +import { GenericInputComponent } from "../generic-input/generic-input.component"; +import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "ngparam-min", + templateUrl: "../generic-input/generic-input.component.html" +}) +export class NgParamMinComponent extends GenericInputComponent { + /** + * valeur actuelle du minimum + */0.49999999995 + private _currentValue: number; + + /** + * reférence (valeur mini pour le minimum) + */ + private _refValue: Pair; + + @Output() + private onChange = new EventEmitter<string>(); + + public isInit: boolean; + + constructor(private intlService: InternationalisationService) { + super(); + } + + public set refValue(v: Pair) { + this._refValue = v; + } + + protected getModelValue(): any { + return this._currentValue; + } + + protected setModelValue(v: any) { + this._currentValue = v; + this.onChange.emit("value"); + } + + protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg = undefined; + let valid = false; + + if (!this._refValue.intervalHasValue(v)) + msg = "La valeur n'est pas dans " + this._refValue.toString(); + else + valid = true; + + return { isValid: valid, message: msg }; + } + + protected modelToUI(v: any): string { + if (typeof (v) == "number") + return String(v); + return undefined; + } + + protected validateUIValue(ui: string): { isValid: boolean, message: string } { + let valid: boolean = false; + let msg: string = undefined; + + let v: NumericalString = new NumericalString(ui); + if (!v.isNumerical) + msg = "Veuillez entrer une valeur numérique"; + else + valid = true; + + return { isValid: valid, message: msg }; + } + + protected uiToModel(ui: string): any { + return +ui; + } +} diff --git a/src/app/components/param-values/ngparam-step.component.ts b/src/app/components/param-values/ngparam-step.component.ts new file mode 100644 index 000000000..e34225e94 --- /dev/null +++ b/src/app/components/param-values/ngparam-step.component.ts @@ -0,0 +1,80 @@ +import { Component, Output, EventEmitter } from "@angular/core"; + +import { NumericalString, Pair } from "jalhyd"; + +import { GenericInputComponent } from "../generic-input/generic-input.component"; +import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "ngparam-step", + templateUrl: "../generic-input/generic-input.component.html" +}) +export class NgParamStepComponent extends GenericInputComponent { + /** + * valeur actuelle du pas + */ + private _currentValue: number; + + /** + * reférence (valeur maxi pour le pas) + */ + private _refValue: Pair; + + @Output() + private onChange = new EventEmitter<string>(); + + constructor(private intlService: InternationalisationService) { + super(); + } + + public set refValue(v: Pair) { + this._refValue = v; + } + + protected getModelValue(): any { + return this._currentValue; + } + + protected setModelValue(v: any) { + this._currentValue = v; + this.onChange.emit("value"); + } + + protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg = undefined; + let valid = false; + + if (!this._refValue.intervalHasValue(v)) + msg = "La valeur n'est pas dans " + this._refValue.toString(); + else { + valid = v > 0; + if (!valid) + msg = "La valeur ne peut pas être <= 0"; + } + + return { isValid: valid, message: msg }; + } + + protected modelToUI(v: any): string { + if (typeof (v) == "number") + return String(v); + return "<invalid>"; + } + + protected validateUIValue(ui: string): { isValid: boolean, message: string } { + let valid: boolean = false; + let msg: string = undefined; + + let v: NumericalString = new NumericalString(ui); + if (!v.isNumerical) + msg = "Veuillez entrer une valeur numérique"; + else + valid = true; + + return { isValid: valid, message: msg }; + } + + protected uiToModel(ui: string) { + return +ui; + } +} diff --git a/src/app/components/param-values/param-values.component.html b/src/app/components/param-values/param-values.component.html new file mode 100644 index 000000000..40b434a6e --- /dev/null +++ b/src/app/components/param-values/param-values.component.html @@ -0,0 +1,24 @@ +<div class="row"> + <div class="btn-group col-12 col-sm-3" dropdown (click)="onSelect($event)"> + <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> + {{currentLabel}} + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" *ngFor="let e of _valueModes" [value]=e.value>{{e.label}}</a> + </div> + </div> + + <div *ngIf="!isList" class="col-12 col-sm-3"> + <ngparam-min [title]="uitextValeurMini" (onChange)="onMinChanged($event)"></ngparam-min> + </div> + <div *ngIf="!isList" class="col-12 col-sm-3"> + <ngparam-max [title]="uitextValeurMaxi" (onChange)="onMaxChanged($event)"></ngparam-max> + </div> + <div *ngIf="!isList" class="col-12 col-sm-3"> + <ngparam-step [title]="uitextPasVariation" (onChange)="onStepChanged($event)"></ngparam-step> + </div> + + <div *ngIf="isList" class="col-12 col-sm-9"> + <value-list title="valeurs séparées par ';'" (onChange)="onListChanged($event)"></value-list> + </div> +</div> \ No newline at end of file diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts new file mode 100644 index 000000000..46a24c045 --- /dev/null +++ b/src/app/components/param-values/param-values.component.ts @@ -0,0 +1,321 @@ +import { Component, Input, Output, EventEmitter, ViewChild, DoCheck } from "@angular/core"; + +import { ParamDomainValue, Pair } from "jalhyd"; + +import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { NgParameter, ParamValueMode } from "../../formulaire/ngparam"; +import { GenericInputComponent } from "../generic-input/generic-input.component"; +import { NgParamMinComponent } from "./ngparam-min.component"; +import { NgParamMaxComponent } from "./ngparam-max.component"; +import { NgParamStepComponent } from "./ngparam-step.component"; + + +@Component({ + selector: "value-list", + templateUrl: "../generic-input/generic-input.component.html" +}) +export class ValueListComponent extends GenericInputComponent { + @Output() + private onChange = new EventEmitter<string>(); + + public _list: number[]; + + public isInit; + + constructor(private intlService: InternationalisationService) { + super(); + this._list = []; + } + + protected getModelValue(): any { + return this._list; + } + + protected setModelValue(l: any) { + if (typeof (l) == "number") { + this._list = []; + this._list.push(l); + } + else + this._list = l; + this.onChange.emit("value"); + } + + protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg = undefined; + let valid = false; + + if (v instanceof Array) { + valid = true; + for (let e of v) { + valid = valid && (typeof (e) == "number") + if (!valid) { + msg = "La valeur n'est pas une liste de nombres" + break; + } + } + } + + return { isValid: valid, message: msg }; + } + + protected modelToUI(v: any): string { + let res = ""; + for (let e of v) { + if (res != "") + res += ";"; + res += String(e); + } + return res; + } + + protected validateUIValue(ui: string): { isValid: boolean, message: string } { + let valid: boolean = false; + let msg: string = undefined; + + let tmp: string[] = ui.split(";"); + let res = true; + for (let v of tmp) { + let isnum = v != "" && (+v == +v); + res = res && isnum; + if (!res) + break; + } + + if (!res) + msg = "Veuillez entrer une liste de nombres"; + else + valid = true; + + return { isValid: valid, message: msg }; + } + + protected uiToModel(ui: string) { + let tmp: string[] = ui.split(";"); + let res = []; + for (let v of tmp) + res.push(+v); + return res; + } +} + +@Component({ + selector: "param-values", + templateUrl: "./param-values.component.html", + styles: [ + `.btn-on { + color:#505050; + border: 3px solid #505050; + background-color:white; + text-transform: uppercase; + font-size: 0.8em; + }`, + `.btn-off { + color:white; + border: 3px solid #505050; + background-color:#505050; + text-transform: uppercase; + font-size: 0.8em; + }` + ] +}) +export class ParamValuesComponent implements DoCheck { + @Input("param") + private _param: NgParameter; + + /** + * true si liste de valeur, false si min/max/pas + */ + private _list: boolean; + + private _valueModes = []; + + /** + * composant de saisie du minimum + */ + @ViewChild(NgParamMinComponent) + private _minComponent: NgParamMinComponent; + + /** + * composant de saisie du maximum + */ + @ViewChild(NgParamMaxComponent) + private _maxComponent: NgParamMaxComponent; + + /** + * composant de saisie du pas de variation + */ + @ViewChild(NgParamStepComponent) + private _stepComponent: NgParamStepComponent; + + /** + * composant de saisie d'une liste de valeurs + */ + @ViewChild(ValueListComponent) + private _listComponent: ValueListComponent; + + constructor(private intlService: InternationalisationService) { + this._valueModes.push({ "value": ParamValueMode.MINMAX, "label": "Min/max" }); + this._valueModes.push({ "value": ParamValueMode.LISTE, "label": "Liste" }); + } + + private getDefaultMin(): number { + switch (this._param.domain.domain) { + case ParamDomainValue.ANY: + case ParamDomainValue.NOT_NULL: + return -10; + + default: + return this._param.domain.minValue; + } + } + + private getDefaultMax(): number { + switch (this._param.domain.domain) { + case ParamDomainValue.INTERVAL: + return this._param.domain.maxValue; + + default: + return 10; + } + } + + private initMinMaxStep() { + // valeur pour min (celle déjà définie ou celle déduite du domaine de définition) + let min: number = this._param.minValue; + let ok = min != undefined + if (ok) { + try { + // on la vérifie + this._param.checkValue(min); + ok = true; + } + catch (e) { + ok = false; + } + } + if (!ok) + min = this.getDefaultMin(); + + // valeur pour max (celle déjà définie ou celle déduite du domaine de définition) + let max: number = this._param.maxValue; + ok = max != undefined + if (ok) { + try { + // on la vérifie + this._param.checkValue(max); + ok = true; + } + catch (e) { + ok = false; + } + } + if (!ok) + min = this.getDefaultMax(); + + this._minComponent.refValue = new Pair(this._param.domain.minValue, max); + this._minComponent.model = min; + + this._maxComponent.refValue = new Pair(min, this._param.domain.maxValue); + this._maxComponent.model = max; + + this.updateStepComponentRef(); + + let step = this._param.stepValue; + if (step == undefined) + step = (max - min) / 20; + if (min == -Infinity || max == Infinity) + step = 10; + this._stepComponent.model = step; + } + + private onMinChanged(val: string) { + this.updateStepComponentRef(); + + this._maxComponent.refValue = new Pair(this._minComponent.model, this._param.domain.maxValue); + this._maxComponent.validateModel(); + + if (this._minComponent.validateModel()) + this._param.minValue = this._minComponent.model; + } + + private onMaxChanged(val: string) { + this.updateStepComponentRef(); + + this._minComponent.refValue = new Pair(this._param.domain.minValue, this._maxComponent.model); + this._minComponent.validateModel(); + + if (this._maxComponent.validateModel()) + this._param.maxValue = this._maxComponent.model; + } + + private onStepChanged(val: string) { + if (this._stepComponent.validateModel()) + this._param.stepValue = this._stepComponent.model; + } + + private onListChanged(val: string) { + if (this._listComponent.validateModel()) + this._param.valueList = this._listComponent.model; + } + + public ngDoCheck() { + // initialisation des champs min/max/step à l'apparition de ces contrôles + if (this._minComponent != undefined && !this._minComponent.isInit) { + this._minComponent.isInit = true; + this.initMinMaxStep(); + } + + if (this._listComponent != undefined && !this._listComponent.isInit) { + this._listComponent.isInit = true; + + this._listComponent.model = []; + if (this._param.isDefined) + this._listComponent.model.push(this._param.getValue()); + } + } + + /** + * met à jour la valeur de référence du composant gérant le pas de variation + */ + private updateStepComponentRef() { + this._stepComponent.refValue = new Pair(1e-9, this._maxComponent.model - this._minComponent.model); + this._stepComponent.validateModel(); + } + + private get uitextValeurMini() { + return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMINI"); + } + + private get uitextValeurMaxi() { + return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMAXI"); + } + + private get uitextPasVariation() { + return this.intlService.localizeText("INFO_PARAMFIELD_PASVARIATION"); + } + + private get isList(): boolean { + return this._param.valueMode == ParamValueMode.LISTE; + } + + /** + * valeur courante affichée dans le select + */ + private get currentLabel(): string { + // return this._list ? "Liste" : "Min/max/pas"; + return ParamValueMode[this._param.valueMode]; + } + + private onSelect(event: any) { + // for (let a of event.target.attributes) + // if (a.name == "value") { + // var val = a.value; + // break; + // } + + // // this._currentLabel = event.target.text; + // this._list = val == "list"; + this._param.valueMode = event.target.value; + } +} -- GitLab From 3918fda01856567e744baf35415d17f9372d5c58 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Tue, 16 Jan 2018 18:53:40 +0100 Subject: [PATCH 03/10] =?UTF-8?q?ticket=20#47=20:=20param=C3=A8tre=20?= =?UTF-8?q?=C3=A0=20varier=20:=20ajout=20d'une=20coche=20"histogramme"=20p?= =?UTF-8?q?our=20tracer=20un=20histogramme=20plut=C3=B4t=20qu'un=20graphe?= =?UTF-8?q?=20XY=20(liste=20de=20valeurs)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixedvar-results.component.ts | 91 ++++++++++++++++++- .../param-values/param-values.component.html | 9 +- .../param-values/param-values.component.ts | 11 +-- src/app/formulaire/formulaire-definition.ts | 6 +- src/app/formulaire/ngparam.ts | 1 + src/app/results/fixed-var-results.ts | 25 +++++ 6 files changed, 125 insertions(+), 18 deletions(-) diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts index 802f66825..f1774af39 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.ts +++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts @@ -4,7 +4,7 @@ import { InternationalisationService } from "../../services/internationalisation import { ApplicationSetupService } from '../../services/app-setup/app-setup.service'; import { LogComponent } from '../../components/log/log.component'; import { cLog } from "jalhyd"; -import { FixedVarResults } from "../../results/fixed-var-results"; +import { FixedVarResults, GraphType } from "../../results/fixed-var-results"; @Component({ selector: "fixedvar-results", @@ -48,7 +48,7 @@ export class FixedVarResultsComponent { /* * config du graphe */ - private graph_type = "line"; + private graph_type: string; private graph_data = {}; private graph_options = { responsive: true, @@ -62,7 +62,8 @@ export class FixedVarResultsComponent { title: { display: true, text: "" - } + }, + scales: {} }; /** @@ -102,7 +103,23 @@ export class FixedVarResultsComponent { this._varResults.push({ "param": r["param"].toFixed(nDigits), "result": r["result"].toFixed(nDigits) }); this.logComponent.log = this._results.log; - this.generateGraph(); + + switch (this._results.graphType) { + case GraphType.Histogram: + this.graph_type = "bar"; + this.generateBarGraph(); + break; + + case GraphType.HistoLine: + this.graph_type = "line"; + this.generateLineGraph(); + break; + + default: + this.graph_type = "scatter"; + this.generateScatterGraph(); + break; + } } /** * affichage de la table des résultats fixés @@ -139,7 +156,35 @@ export class FixedVarResultsComponent { // this.logComponent.addLogEntries(l); // } - private generateGraph() { + /** + * génère les données d'un graphe de type "line" + */ + private generateLineGraph() { + let labs = []; + let dat = []; + for (let i in this._results.varResults) { + let r = this._results.varResults[i]; + labs.push(r["param"]); + dat.push(this._results.varGraph[i]); + } + + this.graph_options.title.text = this._results.graphTitle; + + this.graph_data = { + labels: labs, + datasets: [ + { + label: "", + data: dat + } + ] + }; + } + + /** + * génère les données d'un graphe de type "bar" + */ + private generateBarGraph() { let labs = []; let dat = []; for (let i in this._results.varResults) { @@ -149,6 +194,13 @@ export class FixedVarResultsComponent { } this.graph_options.title.text = this._results.graphTitle; + this.graph_options.scales = { + xAxes: [{ + gridLines: { + offsetGridLines: true + } + }] + }; this.graph_data = { labels: labs, @@ -161,6 +213,35 @@ export class FixedVarResultsComponent { }; } + /** + * génère les données d'un graphe de type "scatter" + */ + private generateScatterGraph() { + let dat = []; + for (let i in this._results.varResults) { + let r = this._results.varResults[i]; + dat.push({ x: r["param"], y: this._results.varGraph[i] }); + + } + + this.graph_options.title.text = this._results.graphTitle; + this.graph_options.scales = { + xAxes: [{ + type: 'linear', + position: 'bottom' + }] + }; + + this.graph_data = { + datasets: [ + { + label: "", + data: dat + } + ] + }; + } + // public reset(fixed: boolean) { // this._results.reset(); // this.logComponent.reset(); diff --git a/src/app/components/param-values/param-values.component.html b/src/app/components/param-values/param-values.component.html index 40b434a6e..231911877 100644 --- a/src/app/components/param-values/param-values.component.html +++ b/src/app/components/param-values/param-values.component.html @@ -1,5 +1,5 @@ <div class="row"> - <div class="btn-group col-12 col-sm-3" dropdown (click)="onSelect($event)"> + <div class="btn-group col-12 col-sm-3" dropdown (click)="onSelectValueMode($event)"> <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> {{currentLabel}} </button> @@ -18,7 +18,12 @@ <ngparam-step [title]="uitextPasVariation" (onChange)="onStepChanged($event)"></ngparam-step> </div> - <div *ngIf="isList" class="col-12 col-sm-9"> + <div *ngIf="isList" class="col-12 col-sm-6"> <value-list title="valeurs séparées par ';'" (onChange)="onListChanged($event)"></value-list> </div> + + <div *ngIf="isList" class="col-12 col-sm-3"> + <input type="checkbox" name="histogram" [(ngModel)]="_param.histogramMode">Histogramme + <br/> + </div> </div> \ No newline at end of file diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts index 46a24c045..5bfea4209 100644 --- a/src/app/components/param-values/param-values.component.ts +++ b/src/app/components/param-values/param-values.component.ts @@ -303,19 +303,10 @@ export class ParamValuesComponent implements DoCheck { * valeur courante affichée dans le select */ private get currentLabel(): string { - // return this._list ? "Liste" : "Min/max/pas"; return ParamValueMode[this._param.valueMode]; } - private onSelect(event: any) { - // for (let a of event.target.attributes) - // if (a.name == "value") { - // var val = a.value; - // break; - // } - - // // this._currentLabel = event.target.text; - // this._list = val == "list"; + private onSelectValueMode(event: any) { this._param.valueMode = event.target.value; } } diff --git a/src/app/formulaire/formulaire-definition.ts b/src/app/formulaire/formulaire-definition.ts index fc847e626..a83a91287 100644 --- a/src/app/formulaire/formulaire-definition.ts +++ b/src/app/formulaire/formulaire-definition.ts @@ -19,7 +19,7 @@ import { FormulaireElement } from "./formulaire-element"; import { ValueDependency } from "./value-dependency"; import { ValueDependencyCondition } from "./value-dependency-condition"; import { ExistenceDependency } from "./existence-dependency"; -import { FixedVarResults } from "../results/fixed-var-results"; +import { FixedVarResults, GraphType } from "../results/fixed-var-results"; import { SectionResults } from "../results/section-results"; import { RemousResults } from "../results/remous-results"; import { StringMap } from "../stringmap"; @@ -1119,6 +1119,8 @@ export class FormulaireDefinition extends Observable { switch (varParam.valueMode) { case ParamValueMode.MINMAX: + this._fixVarResults.graphType = GraphType.Scatter; + let min: number = +varParam.minValue; let max: number = +varParam.maxValue; let step: number = +varParam.stepValue; @@ -1137,6 +1139,8 @@ export class FormulaireDefinition extends Observable { break; case ParamValueMode.LISTE: + this._fixVarResults.graphType = varParam.histogramMode ? GraphType.Histogram : GraphType.Scatter; + for (let val of varParam.valueList) { prms[varParam.symbol].v = val; diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index 703ac0696..a662906de 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -52,6 +52,7 @@ export class NgParameter extends InputField { public stepValue: number; // pas de progression dans le cas ParamRadioConfig.VAR public valueList: number[]; public valueMode: ParamValueMode = ParamValueMode.MINMAX; + public histogramMode: boolean = false; // A VIRER et deplacer dans FixVarResults constructor(private _paramDef: ParamDefinition, formId: number) { super(_paramDef.computeNodeType, _paramDef.symbol, formId); diff --git a/src/app/results/fixed-var-results.ts b/src/app/results/fixed-var-results.ts index 33b49bb07..97d16be54 100644 --- a/src/app/results/fixed-var-results.ts +++ b/src/app/results/fixed-var-results.ts @@ -3,6 +3,26 @@ import { cLog } from "jalhyd"; import { NgParameter } from "../formulaire/ngparam"; import { CalculatorResults } from "./calculator-results"; +/** + * type de graphe + */ +export enum GraphType { + /** + * histogramme + */ + Histogram, + + /** + * points indépendants reliés par une courbe + */ + HistoLine, + + /** + * graphe XY classique + */ + Scatter, +} + export class FixedVarResults extends CalculatorResults { /** * résultats fixed (true) ou variés (false) @@ -34,6 +54,11 @@ export class FixedVarResults extends CalculatorResults { */ private _graphTitle: string; + /** + * type de graphe + */ + public graphType: GraphType = GraphType.Scatter; + /** * tableau de valeurs du graphe des résultats variés */ -- GitLab From b62242ebecc9e2213343e5d1f9c147087b26d89c Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Thu, 18 Jan 2018 16:11:26 +0100 Subject: [PATCH 04/10] =?UTF-8?q?ticket=20#47=20:=20corrige=20"initialiser?= =?UTF-8?q?=20les=20valeurs=20min/max=20=C3=A0=20la=20moiti=C3=A9=20et=20a?= =?UTF-8?q?u=20double=20de=20la=20valeur=20existante=20du=20param=C3=A8tre?= =?UTF-8?q?,=20initialiser=20le=20pas=20=C3=A0=20(max-min)/20"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../param-values/param-values.component.ts | 13 +++----- src/app/formulaire/ngparam.ts | 30 ------------------- 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts index 5bfea4209..0349075f1 100644 --- a/src/app/components/param-values/param-values.component.ts +++ b/src/app/components/param-values/param-values.component.ts @@ -211,22 +211,17 @@ export class ParamValuesComponent implements DoCheck { } } if (!ok) - min = this.getDefaultMax(); + max = this.getDefaultMax(); this._minComponent.refValue = new Pair(this._param.domain.minValue, max); - this._minComponent.model = min; + this._minComponent.model = this._param.getValue() / 2; this._maxComponent.refValue = new Pair(min, this._param.domain.maxValue); - this._maxComponent.model = max; + this._maxComponent.model = this._param.getValue() * 2; this.updateStepComponentRef(); - let step = this._param.stepValue; - if (step == undefined) - step = (max - min) / 20; - if (min == -Infinity || max == Infinity) - step = 10; - this._stepComponent.model = step; + this._stepComponent.model = (this._maxComponent.model - this._minComponent.model) / 20; } private onMinChanged(val: string) { diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index a662906de..16dd165eb 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -56,32 +56,6 @@ export class NgParameter extends InputField { constructor(private _paramDef: ParamDefinition, formId: number) { super(_paramDef.computeNodeType, _paramDef.symbol, formId); - switch (this._paramDef.getDomain().domain) { - case ParamDomainValue.ANY: - this.minValue = -10; - this.maxValue = 10; - this.stepValue = 0.5; - break; - - case ParamDomainValue.POS: - case ParamDomainValue.NOT_NULL: - this.minValue = 0.01; - this.maxValue = 10; - this.stepValue = 0.5; - break; - - case ParamDomainValue.INTERVAL: - this.minValue = this._paramDef.getDomain().minValue; - this.maxValue = this._paramDef.getDomain().maxValue; - this.stepValue = (this.maxValue - this.minValue) / 10; - break; - - case ParamDomainValue.POS_NULL: - this.minValue = 0; - this.maxValue = 10; - this.stepValue = 0.5; - break; - } } get symbol(): string { @@ -92,10 +66,6 @@ export class NgParameter extends InputField { return this._paramDef.getDomain(); } - // get alias(): string { - // return this._paramDef.symbolAlias; - // } - public getValue() { return this._paramDef.v; } -- GitLab From 30e391067e6f3e0a132c71d04cd1f41f58957860 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Thu, 18 Jan 2018 16:19:43 +0100 Subject: [PATCH 05/10] =?UTF-8?q?ticket=20#47=20:=20points=20du=20graph=20?= =?UTF-8?q?XY=20(param=C3=A8tre=20=C3=A0=20varier)=20trac=C3=A9s=20en=20no?= =?UTF-8?q?ir=20plut=C3=B4t=20qu'en=20gris?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/fixedvar-results/fixedvar-results.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts index f1774af39..890766abc 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.ts +++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts @@ -236,7 +236,9 @@ export class FixedVarResultsComponent { datasets: [ { label: "", - data: dat + data: dat, + borderColor: '#000000', + backgroundColor: '#000000' } ] }; -- GitLab From a486f542703306e2bbfdd428247b6ef6217bcf5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= <francois.grand@irstea.fr> Date: Fri, 19 Jan 2018 07:05:05 +0100 Subject: [PATCH 06/10] =?UTF-8?q?ticket=20#47=20:=20extraction=20d'un=20co?= =?UTF-8?q?mposant=20d'affichage=20du=20graphe=20des=20r=C3=A9sultats=20Re?= =?UTF-8?q?sultsGraphComponent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.module.ts | 5 +- .../fixedvar-results.component.html | 7 +- .../fixedvar-results.component.ts | 226 +++--------------- .../results-graph.component.html | 6 + .../results-graph/results-graph.component.ts | 160 +++++++++++++ 5 files changed, 204 insertions(+), 200 deletions(-) create mode 100644 src/app/components/results-graph/results-graph.component.html create mode 100644 src/app/components/results-graph/results-graph.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index cdec1aedb..545d930ee 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -32,6 +32,7 @@ import { GenericCalculatorComponent } from './components/generic-calculator/calc import { CalcCanvasComponent } from './components/canvas/canvas.component'; import { SectionCanvasComponent } from './components/section-canvas/section-canvas.component'; import { RemousResultsComponent } from './components/remous-results/remous-results.component'; +import { ResultsGraphComponent } from './components/results-graph/results-graph.component'; import { LogComponent } from './components/log/log.component'; import { CalculatorListComponent } from './components/calculator-list/calculator-list.component'; import { ApplicationSetupComponent } from './components/app-setup/app-setup.component'; @@ -66,7 +67,7 @@ const appRoutes: Routes = [ NgParamInputComponent, FieldSetComponent, ParamFieldLineComponent, NgParamMinComponent, NgParamMaxComponent, NgParamStepComponent, - ParamValuesComponent, ValueListComponent, + ParamValuesComponent, ValueListComponent, SelectFieldLineComponent, CheckFieldLineComponent, LogComponent, CalculatorListComponent, @@ -74,7 +75,7 @@ const appRoutes: Routes = [ BaseParamInputComponent, GenericCalculatorComponent, // AlertDialog, - CalculatorResultsComponent, FixedVarResultsComponent, SectionResultsComponent, RemousResultsComponent, + CalculatorResultsComponent, FixedVarResultsComponent, SectionResultsComponent, RemousResultsComponent, ResultsGraphComponent, CalcCanvasComponent, SectionCanvasComponent ], // entryComponents: [AlertDialog], diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.html b/src/app/components/fixedvar-results/fixedvar-results.component.html index c9b33f435..f17d9e8eb 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.html +++ b/src/app/components/fixedvar-results/fixedvar-results.component.html @@ -4,12 +4,7 @@ </div> </div> -<div class="row"> - <div class="col-8 mx-auto"> - <chart *ngIf="showVarResults" [type]="graph_type" [data]="graph_data" [options]="graph_options"> - </chart> - </div> -</div> +<results-graph *ngIf="showVarResults"></results-graph> <!-- classe conditionnelle : diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts index 890766abc..27b225369 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.ts +++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts @@ -1,10 +1,10 @@ -import { Component, ViewChild } from "@angular/core"; +import { Component, ViewChild, DoCheck } from "@angular/core"; import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; import { ApplicationSetupService } from '../../services/app-setup/app-setup.service'; import { LogComponent } from '../../components/log/log.component'; -import { cLog } from "jalhyd"; -import { FixedVarResults, GraphType } from "../../results/fixed-var-results"; +import { FixedVarResults } from "../../results/fixed-var-results"; +import { ResultsGraphComponent } from "../results-graph/results-graph.component"; @Component({ selector: "fixedvar-results", @@ -29,7 +29,7 @@ import { FixedVarResults, GraphType } from "../../results/fixed-var-results"; ` ] }) -export class FixedVarResultsComponent { +export class FixedVarResultsComponent implements DoCheck { /** * résultats non mis en forme */ @@ -45,26 +45,10 @@ export class FixedVarResultsComponent { */ private _varResults: Object[]; - /* - * config du graphe - */ - private graph_type: string; - private graph_data = {}; - private graph_options = { - responsive: true, - maintainAspectRatio: true, - animation: { - duration: 0 - }, - legend: { - display: false - }, - title: { - display: true, - text: "" - }, - scales: {} - }; + /** + * true si le graphe des résultats doit être remis à jour + */ + private _updateResultsGraph: boolean; /** * composant journal @@ -72,6 +56,9 @@ export class FixedVarResultsComponent { @ViewChild(LogComponent) private logComponent: LogComponent; + @ViewChild(ResultsGraphComponent) + private resultsGraphComponent: ResultsGraphComponent; + constructor( private intlService: InternationalisationService, private appSetupService: ApplicationSetupService @@ -79,48 +66,44 @@ export class FixedVarResultsComponent { public set results(r: FixedVarResults) { this._results = r; - this.updateView(); + this._updateResultsGraph = true; } public updateView() { this._fixedResults = []; this._varResults = []; this.logComponent.log = undefined; - if (this._results != undefined) - this.generateResults(); + this.generateResults(); + this._updateResultsGraph = true; } - private generateResults() { - const nDigits = this.appSetupService.displayDigits; - const prec = this.appSetupService.displayPrecision; - - for (let r of this._results.fixedResults) { - let v = r["value"]; - this._fixedResults.push({ "label": r["label"], "value": v.toFixed(nDigits) }); + public ngDoCheck() { + if (this._updateResultsGraph) { + if (this.resultsGraphComponent != undefined) { + this.resultsGraphComponent.results = this._results; + this.resultsGraphComponent.updateView(); + this._updateResultsGraph = false; + } } + } - for (let r of this._results.varResults) - this._varResults.push({ "param": r["param"].toFixed(nDigits), "result": r["result"].toFixed(nDigits) }); - - this.logComponent.log = this._results.log; + private generateResults() { + if (this._results != undefined) { + const nDigits = this.appSetupService.displayDigits; + const prec = this.appSetupService.displayPrecision; - switch (this._results.graphType) { - case GraphType.Histogram: - this.graph_type = "bar"; - this.generateBarGraph(); - break; + for (let r of this._results.fixedResults) { + let v = r["value"]; + this._fixedResults.push({ "label": r["label"], "value": v.toFixed(nDigits) }); + } - case GraphType.HistoLine: - this.graph_type = "line"; - this.generateLineGraph(); - break; + for (let r of this._results.varResults) + this._varResults.push({ "param": r["param"].toFixed(nDigits), "result": r["result"].toFixed(nDigits) }); - default: - this.graph_type = "scatter"; - this.generateScatterGraph(); - break; + this.logComponent.log = this._results.log; } } + /** * affichage de la table des résultats fixés */ @@ -143,147 +126,6 @@ export class FixedVarResultsComponent { return this.intlService.localizeText("INFO_CALCULATOR_VALEURS"); } - // public addFixedResult(p: NgParameter, v: number, fixedPrec: number, displaySymbol: boolean) { - // this._fixedResults.push({ "label": this.paramLabel(p, displaySymbol), "value": v.toFixed(fixedPrec) }); - // } - - // public addVarResult(paramVal: number, resVal: number, fixedPrec: number) { - // this._varResults.push({ "param": paramVal.toFixed(fixedPrec), "result": resVal.toFixed(fixedPrec) }); - // this._varGraph.push(resVal); - // } - - // public addLogMessages(l: cLog) { - // this.logComponent.addLogEntries(l); - // } - - /** - * génère les données d'un graphe de type "line" - */ - private generateLineGraph() { - let labs = []; - let dat = []; - for (let i in this._results.varResults) { - let r = this._results.varResults[i]; - labs.push(r["param"]); - dat.push(this._results.varGraph[i]); - } - - this.graph_options.title.text = this._results.graphTitle; - - this.graph_data = { - labels: labs, - datasets: [ - { - label: "", - data: dat - } - ] - }; - } - - /** - * génère les données d'un graphe de type "bar" - */ - private generateBarGraph() { - let labs = []; - let dat = []; - for (let i in this._results.varResults) { - let r = this._results.varResults[i]; - labs.push(r["param"]); - dat.push(this._results.varGraph[i]); - } - - this.graph_options.title.text = this._results.graphTitle; - this.graph_options.scales = { - xAxes: [{ - gridLines: { - offsetGridLines: true - } - }] - }; - - this.graph_data = { - labels: labs, - datasets: [ - { - label: "", - data: dat - } - ] - }; - } - - /** - * génère les données d'un graphe de type "scatter" - */ - private generateScatterGraph() { - let dat = []; - for (let i in this._results.varResults) { - let r = this._results.varResults[i]; - dat.push({ x: r["param"], y: this._results.varGraph[i] }); - - } - - this.graph_options.title.text = this._results.graphTitle; - this.graph_options.scales = { - xAxes: [{ - type: 'linear', - position: 'bottom' - }] - }; - - this.graph_data = { - datasets: [ - { - label: "", - data: dat, - borderColor: '#000000', - backgroundColor: '#000000' - } - ] - }; - } - - // public reset(fixed: boolean) { - // this._results.reset(); - // this.logComponent.reset(); - // } - - // public setVariableParamHeader(h: string) { - // this._variableParamHeader = h; - // } - - // public setVariableParamHeaderFromParameter(p: NgParameter, displaySymbol: boolean) { - // this._variableParamHeader = this.paramLabel(p, displaySymbol); - // } - - // public setVariableResultHeader(h: string) { - // this._variableResultHeader = h; - // } - - // public setVariableResultHeaderFromParameter(p: NgParameter) { - // this._variableResultHeader = this.paramLabel(p, true); - // } - - // public setGraphTitle(t: string) { - // this.graph_options.title.text = t; - // } - - // private paramLabel(p: NgParameter, displaySymbol: boolean): string { - // let res = ""; - // if (displaySymbol) - // res += p.symbol; - // if (p.label != undefined && p.label != "") - // if (p.symbol != p.label || !displaySymbol) { - // if (res.length > 0) - // res += ":"; - // res += p.label; - // } - // if (p.unit != undefined && p.unit != "") - // res += " (" + p.unit + ")"; - // return res; - // } - private getFixedResultClass(i: number) { if (this._results.isFixed && i == this._results.fixedResults.length - 1) return "font-weight-bold"; diff --git a/src/app/components/results-graph/results-graph.component.html b/src/app/components/results-graph/results-graph.component.html new file mode 100644 index 000000000..b34ec9a0d --- /dev/null +++ b/src/app/components/results-graph/results-graph.component.html @@ -0,0 +1,6 @@ +<div class="row"> + <div class="col-12"> + <chart [type]="graph_type" [data]="graph_data" [options]="graph_options"> + </chart> + </div> +</div> \ No newline at end of file diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts new file mode 100644 index 000000000..bc85c2a18 --- /dev/null +++ b/src/app/components/results-graph/results-graph.component.ts @@ -0,0 +1,160 @@ +import { Component, AfterViewInit, EventEmitter, Output } from '@angular/core'; + +import { FixedVarResults, GraphType } from "../../results/fixed-var-results"; + +@Component({ + selector: 'results-graph', + templateUrl: './results-graph.component.html' +}) +export class ResultsGraphComponent { //implements AfterViewInit { + private _results: FixedVarResults; + + /* + * config du graphe + */ + private graph_type: string; + private graph_data = {}; + private graph_options = { + responsive: true, + maintainAspectRatio: true, + animation: { + duration: 0 + }, + legend: { + display: false + }, + title: { + display: true, + text: "" + } + // scales: {} + }; + + /** + * événement émis à la fin de la création de la vue + */ + // @Output() + // private onViewInit = new EventEmitter(); + + public set results(r: FixedVarResults) { + this._results = r; + // this.updateView(); + } + + // http://www.chartjs.org/docs/latest/charts/line.html#dataset-properties + // showLine + + public updateView() { + switch (this._results.graphType) { + case GraphType.Histogram: + this.graph_type = "bar"; + this.generateBarGraph(); + break; + + case GraphType.HistoLine: + this.graph_type = "line"; + this.generateLineGraph(); + break; + + default: + this.graph_type = "scatter"; + this.generateScatterGraph(); + break; + } + } + + // public ngAfterViewInit() { + // this.onViewInit.emit(); + // } + + /** + * génère les données d'un graphe de type "line" + */ + private generateLineGraph() { + let labs = []; + let dat = []; + for (let i in this._results.varResults) { + let r = this._results.varResults[i]; + labs.push(r["param"]); + dat.push(this._results.varGraph[i]); + } + + this.graph_options.title.text = this._results.graphTitle; + + this.graph_data = { + labels: labs, + datasets: [ + { + label: "", + data: dat + } + ] + }; + } + + /** + * génère les données d'un graphe de type "bar" + */ + private generateBarGraph() { + let labs = []; + let dat = []; + for (let i in this._results.varResults) { + let r = this._results.varResults[i]; + labs.push(r["param"]); + dat.push(this._results.varGraph[i]); + } + + this.graph_options.title.text = this._results.graphTitle; + this.graph_options["scales"] = { + xAxes: [{ + gridLines: { + offsetGridLines: true + } + }] + }; + + this.graph_data = { + labels: labs, + datasets: [ + { + label: "", + data: dat + } + ] + }; + } + + /** + * génère les données d'un graphe de type "scatter" + */ + private generateScatterGraph() { + let dat = []; + for (let i in this._results.varResults) { + let r = this._results.varResults[i]; + dat.push({ x: r["param"], y: this._results.varGraph[i] }); + } + + this.graph_options.title.text = this._results.graphTitle; + this.graph_options["scales"] = { + xAxes: [{ + type: 'linear', + position: 'bottom' + }], + yAxes: [{ + type: 'linear', + position: 'left' + }] + }; + + this.graph_data = { + datasets: [ + { + label: "", + data: dat, + // borderColor: '#000000', + // backgroundColor: '#000000' + } + ] + }; + } +} \ No newline at end of file -- GitLab From 6e6a2bf5b3382d2e77ec15e19a3fd974cd22ae19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= <francois.grand@irstea.fr> Date: Fri, 19 Jan 2018 07:08:48 +0100 Subject: [PATCH 07/10] =?UTF-8?q?Correction=20d'un=20bug=20d'initialisatio?= =?UTF-8?q?n=20du=20min/max=20pour=20les=20param=C3=A8tres=20=C3=A0=20vari?= =?UTF-8?q?er=20par=20ex=20:=20conduite=20distributrice,=20calculer=20Pert?= =?UTF-8?q?e=20de=20charge,=20varier=20Longueur=20du=20tuyau,=20"calculer"?= =?UTF-8?q?=20->=20pas=20de=20graphe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../param-values/param-values.component.ts | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts index 0349075f1..e0f63c158 100644 --- a/src/app/components/param-values/param-values.component.ts +++ b/src/app/components/param-values/param-values.component.ts @@ -158,28 +158,7 @@ export class ParamValuesComponent implements DoCheck { this._valueModes.push({ "value": ParamValueMode.MINMAX, "label": "Min/max" }); this._valueModes.push({ "value": ParamValueMode.LISTE, "label": "Liste" }); } - - private getDefaultMin(): number { - switch (this._param.domain.domain) { - case ParamDomainValue.ANY: - case ParamDomainValue.NOT_NULL: - return -10; - - default: - return this._param.domain.minValue; - } - } - - private getDefaultMax(): number { - switch (this._param.domain.domain) { - case ParamDomainValue.INTERVAL: - return this._param.domain.maxValue; - - default: - return 10; - } - } - + private initMinMaxStep() { // valeur pour min (celle déjà définie ou celle déduite du domaine de définition) let min: number = this._param.minValue; @@ -195,7 +174,7 @@ export class ParamValuesComponent implements DoCheck { } } if (!ok) - min = this.getDefaultMin(); + min = this._param.getValue() / 2; // valeur pour max (celle déjà définie ou celle déduite du domaine de définition) let max: number = this._param.maxValue; @@ -211,13 +190,13 @@ export class ParamValuesComponent implements DoCheck { } } if (!ok) - max = this.getDefaultMax(); + max = this._param.getValue() * 2; this._minComponent.refValue = new Pair(this._param.domain.minValue, max); - this._minComponent.model = this._param.getValue() / 2; + this._minComponent.model = min; this._maxComponent.refValue = new Pair(min, this._param.domain.maxValue); - this._maxComponent.model = this._param.getValue() * 2; + this._maxComponent.model = max; this.updateStepComponentRef(); -- GitLab From 3e609701d34dcaf20e7c65a611b48badeda3f8ad Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Fri, 19 Jan 2018 11:17:05 +0100 Subject: [PATCH 08/10] =?UTF-8?q?cr=C3=A9ation=20d'un=20composant=20g?= =?UTF-8?q?=C3=A9n=C3=A9rique=20de=20gestion=20de=20liste=20d=C3=A9roulant?= =?UTF-8?q?e=20(GenericSelectComponent)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generic-select.component.html | 8 +++ .../generic-select.component.ts | 58 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/app/components/generic-select/generic-select.component.html create mode 100644 src/app/components/generic-select/generic-select.component.ts diff --git a/src/app/components/generic-select/generic-select.component.html b/src/app/components/generic-select/generic-select.component.html new file mode 100644 index 000000000..58262b7c2 --- /dev/null +++ b/src/app/components/generic-select/generic-select.component.html @@ -0,0 +1,8 @@ +<div class="btn-group" dropdown (click)="onSelect($event)"> + <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> + {{currentLabel}} + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" *ngFor="let e of entries" [value]=entryValue(e)>{{entryLabel(e)}}</a> + </div> +</div> \ No newline at end of file diff --git a/src/app/components/generic-select/generic-select.component.ts b/src/app/components/generic-select/generic-select.component.ts new file mode 100644 index 000000000..3c0c0b311 --- /dev/null +++ b/src/app/components/generic-select/generic-select.component.ts @@ -0,0 +1,58 @@ +import { Component, Input, Output, EventEmitter } from "@angular/core"; + +import { SelectField, } from "../../formulaire/select-field"; +import { SelectEntry } from "../../formulaire/select-entry"; +import { FormulaireService } from "../../services/formulaire/formulaire.service"; + +/* + exemple de template : + <div class="btn-group col-12 col-sm-9" dropdown (click)="onSelect($event)"> + <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> + {{currentLabel}} + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" *ngFor="let e of entries" [value]=e.value>{{e.label}}</a> + </div> + </div> +*/ + +export abstract class GenericSelectComponent { + // valeur actuellement sélectionnée + // la valeur est le code non affiché repérant une entrée de la liste (cf. [value] dans le templace) + private _selectedValue: any; + + /** + * selected value event + */ + @Output() + private selectChange = new EventEmitter<string>(); + + private get currentLabel(): string { + if (this._selectedValue != undefined) + for (let e of this.entries) + if (this.entryValue(e) == this._selectedValue) + return this.entryLabel(e); + + return "<no selection>"; + } + + private onSelect(event: any) { + this._selectedValue = event.target.value; + this.selectChange.emit(this._selectedValue); + } + + /** + * liste des objets sélectionnables + */ + protected abstract get entries(): any[]; + + /** + * calcule la "valeur" d'une entrée + */ + protected abstract entryValue(entry: any): string; + + /** + * calcule l'étiquette d'une entrée (ce qui est affiché dans la liste déroulante) + */ + protected abstract entryLabel(entry: any): string; +} -- GitLab From 0d3acc1520a7d27bf2d120622cdb2c159ce4d16f Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Fri, 19 Jan 2018 12:12:17 +0100 Subject: [PATCH 09/10] =?UTF-8?q?ticket=20#47=20:=20r=C3=A9solution=20de?= =?UTF-8?q?=20"D=C3=A9placer=20la=20coche=20histogramme=20aupr=C3=A8s=20du?= =?UTF-8?q?=20graphique"=20r=C3=A9solution=20de=20"Mettre=20le=20graphe=20?= =?UTF-8?q?en=20scatter=20par=20d=C3=A9faut=20pour=20min,=20max,=20pas=20e?= =?UTF-8?q?t=20en=20histogramme=20en=20valeurs=20libres"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.module.ts | 5 +- .../generic-select.component.html | 2 +- .../generic-select.component.ts | 25 +++++----- .../param-values/param-values.component.html | 5 -- .../results-graph.component.html | 6 +++ .../results-graph/results-graph.component.ts | 48 +++++++++++++------ src/app/formulaire/formulaire-definition.ts | 2 +- src/app/formulaire/ngparam.ts | 1 - 8 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 545d930ee..9c8da9ef4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -32,7 +32,7 @@ import { GenericCalculatorComponent } from './components/generic-calculator/calc import { CalcCanvasComponent } from './components/canvas/canvas.component'; import { SectionCanvasComponent } from './components/section-canvas/section-canvas.component'; import { RemousResultsComponent } from './components/remous-results/remous-results.component'; -import { ResultsGraphComponent } from './components/results-graph/results-graph.component'; +import { ResultsGraphComponent, GraphTypeSelectComponent } from './components/results-graph/results-graph.component'; import { LogComponent } from './components/log/log.component'; import { CalculatorListComponent } from './components/calculator-list/calculator-list.component'; import { ApplicationSetupComponent } from './components/app-setup/app-setup.component'; @@ -75,7 +75,8 @@ const appRoutes: Routes = [ BaseParamInputComponent, GenericCalculatorComponent, // AlertDialog, - CalculatorResultsComponent, FixedVarResultsComponent, SectionResultsComponent, RemousResultsComponent, ResultsGraphComponent, + CalculatorResultsComponent, FixedVarResultsComponent, SectionResultsComponent, RemousResultsComponent, + ResultsGraphComponent, GraphTypeSelectComponent, CalcCanvasComponent, SectionCanvasComponent ], // entryComponents: [AlertDialog], diff --git a/src/app/components/generic-select/generic-select.component.html b/src/app/components/generic-select/generic-select.component.html index 58262b7c2..3506521b3 100644 --- a/src/app/components/generic-select/generic-select.component.html +++ b/src/app/components/generic-select/generic-select.component.html @@ -3,6 +3,6 @@ {{currentLabel}} </button> <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of entries" [value]=entryValue(e)>{{entryLabel(e)}}</a> + <a class="dropdown-item" *ngFor="let e of entries" [value]=e>{{entryLabel(e)}}</a> </div> </div> \ No newline at end of file diff --git a/src/app/components/generic-select/generic-select.component.ts b/src/app/components/generic-select/generic-select.component.ts index 3c0c0b311..7dd5f113a 100644 --- a/src/app/components/generic-select/generic-select.component.ts +++ b/src/app/components/generic-select/generic-select.component.ts @@ -6,19 +6,20 @@ import { FormulaireService } from "../../services/formulaire/formulaire.service" /* exemple de template : - <div class="btn-group col-12 col-sm-9" dropdown (click)="onSelect($event)"> + +<div class="btn-group" dropdown (click)="onSelect($event)"> <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> {{currentLabel}} </button> <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of entries" [value]=e.value>{{e.label}}</a> + <a class="dropdown-item" *ngFor="let e of entries" [value]=e>{{entryLabel(e)}}</a> </div> - </div> +</div> */ export abstract class GenericSelectComponent { // valeur actuellement sélectionnée - // la valeur est le code non affiché repérant une entrée de la liste (cf. [value] dans le templace) + // la valeur repère une entrée de la liste (cf. [value] dans le template) private _selectedValue: any; /** @@ -27,11 +28,14 @@ export abstract class GenericSelectComponent { @Output() private selectChange = new EventEmitter<string>(); + public set selectedValue(v: any) { + this._selectedValue = v; + } + private get currentLabel(): string { - if (this._selectedValue != undefined) - for (let e of this.entries) - if (this.entryValue(e) == this._selectedValue) - return this.entryLabel(e); + for (let e of this.entries) + if (e == this._selectedValue) + return this.entryLabel(e); return "<no selection>"; } @@ -46,11 +50,6 @@ export abstract class GenericSelectComponent { */ protected abstract get entries(): any[]; - /** - * calcule la "valeur" d'une entrée - */ - protected abstract entryValue(entry: any): string; - /** * calcule l'étiquette d'une entrée (ce qui est affiché dans la liste déroulante) */ diff --git a/src/app/components/param-values/param-values.component.html b/src/app/components/param-values/param-values.component.html index 231911877..e3adf9e93 100644 --- a/src/app/components/param-values/param-values.component.html +++ b/src/app/components/param-values/param-values.component.html @@ -21,9 +21,4 @@ <div *ngIf="isList" class="col-12 col-sm-6"> <value-list title="valeurs séparées par ';'" (onChange)="onListChanged($event)"></value-list> </div> - - <div *ngIf="isList" class="col-12 col-sm-3"> - <input type="checkbox" name="histogram" [(ngModel)]="_param.histogramMode">Histogramme - <br/> - </div> </div> \ No newline at end of file diff --git a/src/app/components/results-graph/results-graph.component.html b/src/app/components/results-graph/results-graph.component.html index b34ec9a0d..316485524 100644 --- a/src/app/components/results-graph/results-graph.component.html +++ b/src/app/components/results-graph/results-graph.component.html @@ -3,4 +3,10 @@ <chart [type]="graph_type" [data]="graph_data" [options]="graph_options"> </chart> </div> +</div> + +<div class="row"> + <div class="col-4 mx-auto"> + <graph-type (selectChange)="onGraphTypeSelectChange($event)"></graph-type> + </div> </div> \ No newline at end of file diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts index bc85c2a18..d52baff5c 100644 --- a/src/app/components/results-graph/results-graph.component.ts +++ b/src/app/components/results-graph/results-graph.component.ts @@ -1,6 +1,26 @@ -import { Component, AfterViewInit, EventEmitter, Output } from '@angular/core'; +import { Component, AfterViewInit, EventEmitter, Output, ViewChild } from '@angular/core'; import { FixedVarResults, GraphType } from "../../results/fixed-var-results"; +import { GenericSelectComponent } from '../generic-select/generic-select.component'; + +@Component({ + selector: "graph-type", + templateUrl: "../generic-select/generic-select.component.html" +}) +export class GraphTypeSelectComponent extends GenericSelectComponent { + private _entries: GraphType[] = [GraphType.Histogram, GraphType.Scatter]; + private _entriesLabels: string[] = ["Histogramme", "XY"]; + + protected get entries(): any[] { + return this._entries; + } + + protected entryLabel(entry: any): string { + // return entry; + const i = this._entries.indexOf(entry); + return this._entriesLabels[i]; + } +} @Component({ selector: 'results-graph', @@ -9,6 +29,11 @@ import { FixedVarResults, GraphType } from "../../results/fixed-var-results"; export class ResultsGraphComponent { //implements AfterViewInit { private _results: FixedVarResults; + private _currentGraphType: GraphType; + + @ViewChild(GraphTypeSelectComponent) + private _graphTypeComponent: GraphTypeSelectComponent; + /* * config du graphe */ @@ -27,25 +52,19 @@ export class ResultsGraphComponent { //implements AfterViewInit { display: true, text: "" } - // scales: {} }; - /** - * événement émis à la fin de la création de la vue - */ - // @Output() - // private onViewInit = new EventEmitter(); - public set results(r: FixedVarResults) { this._results = r; - // this.updateView(); + this._currentGraphType = r.graphType; + this._graphTypeComponent.selectedValue = this._currentGraphType; } // http://www.chartjs.org/docs/latest/charts/line.html#dataset-properties // showLine public updateView() { - switch (this._results.graphType) { + switch (this._currentGraphType) { case GraphType.Histogram: this.graph_type = "bar"; this.generateBarGraph(); @@ -63,9 +82,10 @@ export class ResultsGraphComponent { //implements AfterViewInit { } } - // public ngAfterViewInit() { - // this.onViewInit.emit(); - // } + private onGraphTypeSelectChange(event) { + this._currentGraphType = event; + this.updateView(); + } /** * génère les données d'un graphe de type "line" @@ -157,4 +177,4 @@ export class ResultsGraphComponent { //implements AfterViewInit { ] }; } -} \ No newline at end of file +} diff --git a/src/app/formulaire/formulaire-definition.ts b/src/app/formulaire/formulaire-definition.ts index a83a91287..8bd2ed0b6 100644 --- a/src/app/formulaire/formulaire-definition.ts +++ b/src/app/formulaire/formulaire-definition.ts @@ -1139,7 +1139,7 @@ export class FormulaireDefinition extends Observable { break; case ParamValueMode.LISTE: - this._fixVarResults.graphType = varParam.histogramMode ? GraphType.Histogram : GraphType.Scatter; + this._fixVarResults.graphType = GraphType.Histogram; for (let val of varParam.valueList) { prms[varParam.symbol].v = val; diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index 16dd165eb..9d94db8e4 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -52,7 +52,6 @@ export class NgParameter extends InputField { public stepValue: number; // pas de progression dans le cas ParamRadioConfig.VAR public valueList: number[]; public valueMode: ParamValueMode = ParamValueMode.MINMAX; - public histogramMode: boolean = false; // A VIRER et deplacer dans FixVarResults constructor(private _paramDef: ParamDefinition, formId: number) { super(_paramDef.computeNodeType, _paramDef.symbol, formId); -- GitLab From 67ce4489c12f2b6bf9cd2e83115571b77837fb98 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Fri, 19 Jan 2018 12:20:38 +0100 Subject: [PATCH 10/10] =?UTF-8?q?ticket=20#47=20:=20r=C3=A9solution=20de?= =?UTF-8?q?=20"Relier=20les=20points=20en=20mode=20scatter"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/results-graph/results-graph.component.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts index d52baff5c..83b55ff98 100644 --- a/src/app/components/results-graph/results-graph.component.ts +++ b/src/app/components/results-graph/results-graph.component.ts @@ -60,9 +60,6 @@ export class ResultsGraphComponent { //implements AfterViewInit { this._graphTypeComponent.selectedValue = this._currentGraphType; } - // http://www.chartjs.org/docs/latest/charts/line.html#dataset-properties - // showLine - public updateView() { switch (this._currentGraphType) { case GraphType.Histogram: @@ -171,8 +168,9 @@ export class ResultsGraphComponent { //implements AfterViewInit { { label: "", data: dat, - // borderColor: '#000000', - // backgroundColor: '#000000' + borderColor: "#808080", // couleur de la ligne + backgroundColor: "rgba(0,0,0,0)", // couleur de remplissage sous la courbe : transparent + showLine: "true" } ] }; -- GitLab