diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index 9848d1ec62f9eac669d1baf51eaf36412abd764f..5ffd2279448489e00135e5ee06add47f7667dc05 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -39,9 +39,11 @@ export class VarResultsComponent {
 
         if (this._varResults) {
             const nDigits = this.appSetupService.displayDigits;
-            for (let i = 0; i < this._varResults.xValues.length; i++) {
-                const pval = this._varResults.xValues[i].toFixed(nDigits);
+            let i = 0;
+            for (const x of this._varResults.variatedParameter.valuesIterator) {
+                const pval = x.toFixed(nDigits);
                 this._results.push({ "param": pval, "result": this._varResults.resultElements[i] });
+                i++
             }
 
             this._headers.push(CalculatorResults.paramLabel(this._varResults.variatedParameter, false));
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 51df675e6978975bf3c820d9d7bef531d87e5265..5ec1d3de026458141c26c41424b4188ab5fbe3dd 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
@@ -4,6 +4,7 @@ import { InternationalisationService } from "../../services/internationalisation
 import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam";
 import { NgParamInputComponent } from "../ngparam-input/ngparam-input.component";
 import { FormulaireService } from "../../services/formulaire/formulaire.service";
+import { ParamValueMode } from "jalhyd";
 
 @Component({
     selector: "param-field-line",
@@ -166,6 +167,20 @@ export class ParamFieldLineComponent implements OnChanges {
     private onRadio = new EventEmitter<any>();
 
     private onRadioClick(option: string) {
+        switch (option) {
+            case "fix":
+                this._param.valueMode = ParamValueMode.SINGLE;
+                break;
+
+            case "var":
+                this._param.valueMode = ParamValueMode.MINMAX; // min/max par défaut
+                break;
+
+            case "cal":
+                this._param.valueMode = ParamValueMode.CALCUL;
+                break;
+        }
+
         this.onRadio.emit({
             "param": this._param,
             "option": option
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index d22884898f53c35610adf723b136f97522885701..c553ecc73958877ab31f633c1cb1c986f79ed5e1 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild } from "@angular/core";
 
-import { Result, ArrayReverseIterator, ResultElement, ParamValueIterator } from "jalhyd";
+import { Result, ArrayReverseIterator, ResultElement } from "jalhyd";
 
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { LogComponent } from "../../components/log/log.component";
@@ -167,9 +167,11 @@ export class RemousResultsComponent {
             });
 
             let minXflu; // abscisse de début de la courbe fluviale
-            const itXFlu: ParamValueIterator = this._remousResults.xValues.getValuesIterator();
+            this._remousResults.xValues.initIterator();
             for (let re of this._remousResults.result.resultElements) {
-                const x = itXFlu.next;
+                if (!this._remousResults.xValues.hasNext)
+                    throw new Error("RemousResultsComponent.connectRessaut() : erreur interne (itérateur sur x)")
+                const x = this._remousResults.xValues.next;
                 if (re.getExtraResult("flu") != undefined) {
                     minXflu = x;
                     break;
@@ -187,9 +189,11 @@ export class RemousResultsComponent {
 
             let maxXtor; // abscisse de fin de la courbe torrentielle
             const itRE = new ArrayReverseIterator<ResultElement>(this._remousResults.result.resultElements);
-            const itXTor: ParamValueIterator = this._remousResults.xValues.getValuesIterator(true);
+            this._remousResults.xValues.initIterator();
             for (let r of itRE) {
-                const x = itXTor.next().value;
+                if (!this._remousResults.xValues.hasNext)
+                    throw new Error("RemousResultsComponent.connectRessaut() : erreur interne (itérateur sur x)")
+                const x = this._remousResults.xValues.next;
                 if (r.getExtraResult("tor") != undefined) {
                     maxXtor = x;
                     break;
@@ -218,7 +222,9 @@ export class RemousResultsComponent {
         let labs: number[] = [];
         if (this._remousResults.result.ok) {
             var xmax = -1e8;
-            for (let x of this._remousResults.xValues.getValuesIterator()) {
+            this._remousResults.xValues.initIterator();
+            while (this._remousResults.xValues.hasNext) {
+                const x = this._remousResults.xValues.next;
                 labs.push(x);
                 xmax = Math.max(x, xmax);
             }
@@ -262,10 +268,12 @@ export class RemousResultsComponent {
                 lineExtra = gr1.newLine(2);
         }
 
-        const itX = this._remousResults.xValues.getValuesIterator();
+        this._remousResults.xValues.initIterator();
         for (let re of this._remousResults.result.resultElements) {
-            const x = itX.next().value;
+            if (!this._remousResults.xValues.hasNext)
+                throw new Error("RemousResultsComponent.generateGraph() : erreur interne (itérateur sur x)")
 
+            const x = this._remousResults.xValues.next;
             const yExtra = re.getExtraResult("tRes");
             if (yExtra != undefined)
                 lineExtra.mapPoint(x, yExtra);
diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts
index 7f8700b967387ce7ce84c9235a84af539e1ee116..b24994a399ab2eb0f99b8129f51873871e73faab 100644
--- a/src/app/components/results-graph/results-graph.component.ts
+++ b/src/app/components/results-graph/results-graph.component.ts
@@ -68,12 +68,13 @@ export class ResultsGraphComponent {
     private generateLineGraph() {
         let labs = [];
         let dat = [];
-        for (let i = 0; i < this._results.xValues.length; i++) {
-            const x = this._results.xValues[i];
+        let i = 0;
+        for (const x of this._results.variatedParameter.valuesIterator) {
             labs.push(String(x));
 
             const y = this._results.yValues[i];
             dat.push(y);
+            i++;
         }
 
         this.graph_options.title.text = this._results.graphTitle;
@@ -95,12 +96,14 @@ export class ResultsGraphComponent {
     private generateBarGraph() {
         let labs = [];
         let dat = [];
-        for (let i = 0; i < this._results.xValues.length; i++) {
-            const x = this._results.xValues[i];
+        let i = 0;
+        for (const x of this._results.variatedParameter.valuesIterator) {
             labs.push(x);
 
             const y = this._results.yValues[i];
             dat.push(y);
+
+            i++;
         }
 
         this.graph_options.title.text = this._results.graphTitle;
@@ -128,10 +131,11 @@ export class ResultsGraphComponent {
      */
     private generateScatterGraph() {
         let dat = [];
-        for (let i = 0; i < this._results.xValues.length; i++) {
-            const x = this._results.xValues[i];
+        let i = 0;
+        for (const x of this._results.variatedParameter.valuesIterator) {
             const y = this._results.yValues[i];
             dat.push({ x: x, y: y });
+            i++;
         }
 
         this.graph_options.title.text = this._results.graphTitle;
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 8a7070d00abc5f91ef54a72f0870982e50289a31..44f3de56eb2f83300f29fc04108529b59d04f10b 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -1,13 +1,8 @@
 import { CalculatorType } from "jalhyd";
 
 import { FormResultFixedVar } from "../form-result-fixedvar";
-import { FormResultSection } from "../form-result-section";
-import { FormulaireElement } from "../../formulaire-element";
-import { NgParameter, ParamRadioConfig } from "../../ngparam";
-import { Field } from "../../field";
 import { ParamService } from "../../../services/param/param.service";
 import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
-import { FormDefSection } from "../form-def-section";
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormComputeLechaptCalmon } from "../form-compute-lechapt-calmon";
 import { FormulaireDefinition } from "../form-definition";
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 65fffaca8b2a8f65b133af7ead0d405fe747ddbb..6b9dd4d4823f34b37b32e5965af27d1929dcc399 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -52,10 +52,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
                 break;
         }
 
-        if (prec == undefined)
-            return nub.Calc(this.getParameterRefid(p), init);
-
-        return nub.Calc(this.getParameterRefid(p), init, prec);
+        return nub.CalcSerie(prec, init);
     }
 
     /**
@@ -83,53 +80,41 @@ export abstract class FormComputeFixedVar extends FormCompute {
         this.formResult.addFixedParameters();
 
         let varParam: NgParameter = this.getVariatedParameter();
+        this.initParametersValueMode(nub, computedParam, varParam, varParam && varParam.valueMode);
+
+
         if (varParam == undefined) {
             // pas de paramètre à varier
 
-            let res: Result = this.runNubCalc(nub, computedParam, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
             this.formResult.fixedResults.result = res;
             this.formResult.fixedResults.calculatedParameter = computedParam;
         }
         else {
             // il y a un paramètre à varier
 
-            this.formResult.varResults.variatedParameter = varParam;
-            this.formResult.varResults.calculatedParameter = computedParam;
-
-            const result = new Result();
-
+            const nubVarParam = nub.getParameter(varParam.symbol);
             switch (varParam.valueMode) {
-                case ParamValueMode.MINMAX:
-                    this.formResult.graphType = GraphType.Scatter;
-
-                    let min: number = +varParam.minValue;
-                    let max: number = +varParam.maxValue;
-                    let step: number = +varParam.stepValue;
-
-                    for (let val = min; val <= max; val += step) {
-                        this.setParameterValue(nub, varParam, val);
-
-                        let res: Result = this.runNubCalc(nub, computedParam, computePrec);
-                        result.resultElements.push(res.resultElement);
-                        result.addLog(res.log);
-                    }
+                case ParamValueMode.LISTE:
+                    nubVarParam.paramValues.setValues(varParam.paramDefinition.paramValues.valueList);
                     break;
 
-                case ParamValueMode.LISTE:
-                    this.formResult.graphType = GraphType.Histogram;
+                case ParamValueMode.MINMAX:
+                    const min = varParam.paramDefinition.paramValues.min;
+                    const max = varParam.paramDefinition.paramValues.max;
+                    const step = varParam.paramDefinition.paramValues.step;
+                    nubVarParam.paramValues.setValues(min, max, step);
+                    break;
+            }
 
-                    for (let val of varParam.valueList) {
-                        this.setParameterValue(nub, varParam, val);
+            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
 
-                        let res: Result = this.runNubCalc(nub, computedParam, computePrec);
-                        result.resultElements.push(res.resultElement);
-                        result.addLog(res.log);
-                    }
 
-                    break;
-            }
+            this.formResult.varResults.variatedParameter = varParam;
+            this.formResult.varResults.calculatedParameter = computedParam;
 
-            this.formResult.varResults.result = result;
+      
+            this.formResult.varResults.result = res;
             this.formResult.graphTitle = computedParam.symbol + " = f( " + varParam.symbol + " )";
             this.formResult.varResults.update(false);
         }
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index ae5ca83e53650e81c378a98eee8528410d685359..ea59f851b099ade60eb418059dab410a0d333472 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -1,6 +1,7 @@
 import { FormResult } from "./form-result";
-import { ParamsEquation, ComputeNode } from "jalhyd";
+import { ParamsEquation, ComputeNode, ParamValueMode, Nub } from "jalhyd";
 import { FormulaireDefinition } from "./form-definition";
+import { NgParameter } from "../ngparam";
 
 export abstract class FormCompute {
     constructor(protected _formBase: FormulaireDefinition, protected _formResult: FormResult) {
@@ -14,6 +15,17 @@ export abstract class FormCompute {
         return this._formResult;
     }
 
+    /**
+     * 
+     * @param nub initialise le mode de génération de valeurs des paramètres d'un Nub
+     * @param computedParam paramètre à calculer
+     * @param variatedParam paramètre à varier
+     * @param variatedMode mode de génération du paramètre à varier
+     */
+    protected initParametersValueMode(nub: Nub, computedParam: NgParameter, variatedParam?: NgParameter, variatedMode?: ParamValueMode) {
+        nub.initParametersValueMode(computedParam.paramDefinition, variatedParam && variatedParam.paramDefinition, variatedMode);
+    }
+
     public doCompute() {
         this._formResult.resetResults();
 
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 20ee43cdfe9402a528e66abecc8d85376192a0b9..be2c7489580b0fccbe9c9b3bbb48f6a2c4096bdd 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -41,8 +41,6 @@ export class NgParameter extends InputField {
     public radioConfig: ParamRadioConfig;
     public radioState: ParamRadioConfig;
 
-    private _values: ParamValues;
-
     /**
      * true si ce paramètre est celui par défaut dans un formulaire (cf. fichier de conf des calculettes, objet "options", champ "idCal")
      */
@@ -62,7 +60,6 @@ export class NgParameter extends InputField {
 
     constructor(private _paramDef: ParamDefinition, isTmpl = false) {
         super(isTmpl);
-        this._values = new ParamValues();
     }
 
     get symbol(): string {
@@ -83,6 +80,14 @@ export class NgParameter extends InputField {
         this._confId = id;
     }
 
+    private get _paramValues() {
+        return this._paramDef.paramValues;
+    }
+
+    public get paramDefinition() {
+        return this._paramDef;
+    }
+
     /**
      * notification envoyée après la modification de la valeur du paramètre
      */
@@ -198,14 +203,14 @@ export class NgParameter extends InputField {
     }
 
     public get valueMode() {
-        return this._values.valueMode;
+        return this._paramDef.valueMode;
     }
 
     public set valueMode(m: ParamValueMode) {
         // undefined si on clique en dehors du select après l'avoir ouvert (cad sans avoir fait de sélection)
         // et au même niveau, cad à côté du bouton et non à côté du menu déroulant
         if (m != undefined)
-            this._values.valueMode = m;
+            this._paramValues.valueMode = m;
     }
 
     /**
@@ -215,7 +220,7 @@ export class NgParameter extends InputField {
         if (v == undefined)
             return false;
 
-        if (this._values.valueMode == ParamValueMode.MINMAX)
+        if (this._paramValues.valueMode == ParamValueMode.MINMAX)
             try {
                 this.checkValue(v);
             }
@@ -231,62 +236,62 @@ export class NgParameter extends InputField {
     }
 
     public checkMin(min: number): boolean {
-        return this.isMinMaxDomainValid(min) && (min < this._values.max);
+        return this.isMinMaxDomainValid(min) && (min < this._paramValues.max);
     }
 
     public checkMax(max: number): boolean {
-        return this.isMinMaxDomainValid(max) && (this._values.min < max);
+        return this.isMinMaxDomainValid(max) && (this._paramValues.min < max);
     }
 
     public get isMinMaxValid(): boolean {
-        return this.checkMinMax(this._values.min, this._values.max);
+        return this.checkMinMax(this._paramValues.min, this._paramValues.max);
     }
 
     public get minValue() {
-        return this._values.min;
+        return this._paramValues.min;
     }
 
     public set minValue(v: number) {
-        this._values.min = v;
+        this._paramValues.min = v;
     }
 
     public get maxValue() {
-        return this._values.max;
+        return this._paramValues.max;
     }
 
     public set maxValue(v: number) {
-        this._values.max = v;
+        this._paramValues.max = v;
     }
 
     public checkStep(step: number): boolean {
-        return this.isMinMaxValid && this._values.stepRefValue.intervalHasValue(step);
+        return this.isMinMaxValid && this._paramValues.stepRefValue.intervalHasValue(step);
     }
 
     public get stepRefValue(): Pair {
-        return this._values.stepRefValue;
+        return this._paramValues.stepRefValue;
     }
 
     public get stepValue() {
-        return this._values.step;
+        return this._paramValues.step;
     }
 
     public set stepValue(v: number) {
-        this._values.step = v;
+        this._paramValues.step = v;
     }
 
     public get valueList() {
-        return this._values.valueList;
+        return this._paramValues.valueList;
     }
 
     public set valueList(l: number[]) {
-        this._values.valueList = l;
+        this._paramValues.valueList = l;
     }
 
     private get isListValid(): boolean {
-        if (this._values.valueList == undefined)
+        if (this._paramValues.valueList == undefined)
             return false;
 
-        for (let v of this._values.valueList)
+        for (let v of this._paramValues.valueList)
             try {
                 this.checkValue(v);
             }
@@ -297,15 +302,15 @@ export class NgParameter extends InputField {
     }
 
     private get isRangeValid(): boolean {
-        switch (this._values.valueMode) {
+        switch (this._paramValues.valueMode) {
             case ParamValueMode.LISTE:
                 return this.isListValid;
 
             case ParamValueMode.MINMAX:
-                return this.checkStep(this._values.step);
+                return this.checkStep(this._paramValues.step);
         }
 
-        throw new Error(`"NgParameter.isRangeValid() : valeur ${this._values.valueMode} de ParamValueMode non prise en compte`);
+        throw new Error(`"NgParameter.isRangeValid() : valeur ${ParamValueMode[this._paramValues.valueMode]} de ParamValueMode non prise en compte`);
     }
 
     private get isValueValid(): boolean {
@@ -381,7 +386,7 @@ export class NgParameter extends InputField {
     }
 
     public get valuesIterator(): ParamValueIterator {
-        return this._values.getValuesIterator();
+        return this._paramValues.getValuesIterator();
     }
 
     public updateLocalisation(loc: StringMap) {
@@ -401,7 +406,7 @@ export class NgParameter extends InputField {
         n.radioConfig = this.radioConfig;
         n.radioState = this.radioState;
         n.isDefault = this.isDefault;
-        this._values.copyMembers(n._values);
+        this._paramValues.copyMembers(n._paramValues);
     }
 
     /**
diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts
index 3aba5fbf0ce5d1bc60e0907e978ea090088a3d2a..5f6484fb524fb4411ee5f55085267615dbd8fbf4 100644
--- a/src/app/results/var-results.ts
+++ b/src/app/results/var-results.ts
@@ -55,11 +55,6 @@ export class VarResults extends CalculatedParamResults {
      */
     public graphType: GraphType = GraphType.Scatter;
 
-    /**
-     * tableau des abscisses du graphe des résultats variés
-     */
-    private _xValues: number[] = [];
-
     /**
      * tableau des ordonnées du graphe des résultats variés
      */
@@ -75,7 +70,6 @@ export class VarResults extends CalculatedParamResults {
         this._variableParamHeader = undefined;
         this._variableResultHeader = undefined;
         this._extraResultHeaders = [];
-        this._xValues = [];
         this._yValues = [];
         this._graphTitle = undefined;
     }
@@ -96,10 +90,6 @@ export class VarResults extends CalculatedParamResults {
         return this._variableResultHeader;
     }
 
-    public get xValues() {
-        return this._xValues;
-    }
-
     public get yValues() {
         return this._yValues;
     }
@@ -127,10 +117,6 @@ export class VarResults extends CalculatedParamResults {
         if (this._calculatedParam)
             this._variableResultHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
 
-        // valeurs du paramètre à varier
-        for (const x of this.variatedParameter.valuesIterator)
-            this._xValues.push(x);
-
         // valeurs du paramètre à calculer
         for (const r of this._result.resultElements)
             this._yValues.push(r.vCalc);
diff --git a/src/app/services/observer.ts b/src/app/services/observer.ts
index 6a1e85b468eacc4e78df1f5336fc78582f465d5e..b7ecdb17cb2843bf61eb680f1f6c65152b9fae7f 100644
--- a/src/app/services/observer.ts
+++ b/src/app/services/observer.ts
@@ -30,7 +30,7 @@ export class Observable implements IObservable {
      * ajoute un observateur à la liste
      */
     public addObserver(o: Observer) {
-        if (!this._observers.includes(o))
+        if (this._observers.indexOf(o) == -1)
             this._observers.push(o);
     }