diff --git a/jalhyd_branch b/jalhyd_branch
index 507bddeeb2094e69036adf32012a679ff60c197d..94f89b3b03cef0d6963c4d0d2b1be518876e8eb7 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1,2 +1 @@
-33-ajout-du-calcul-d-une-passe-a-bassin
-
+62-fonctionnalite-plusieurs-parametres-qui-varient-nghyd-126
\ No newline at end of file
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
index 8fbe604a524054fb39e7dc0727076d78e1e348b9..43f8a3a0f3565893efd03a7ae3ba2616cbc4ff10 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
@@ -105,6 +105,15 @@
         </form>
     </div>
 
+    <mat-form-field>
+      <mat-select [placeholder]="uitextExtensionStrategy" [(value)]="selectedExtensionStrategy"
+        data-testid="variable-extension-strategy-select">
+          <mat-option *ngFor="let e of extensionStrategies" [value]="e.value">
+              {{ e.label }}
+          </mat-option>
+      </mat-select>
+    </mat-form-field>
+
   </div>
 
   <div mat-dialog-content *ngIf="viewChart">
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
index bb9168725ae178f4ac4e7e95fbf6e51ce306831f..803de5b0be298d58fe5de40432f1fa401afa4a6d 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
@@ -3,7 +3,7 @@ import { Inject, Component, OnInit } from "@angular/core";
 import { FormBuilder, FormGroup, Validators } from "@angular/forms";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
 import { NgParameter } from "../../formulaire/ngparam";
-import { ParamValueMode } from "jalhyd";
+import { ParamValueMode, ExtensionStrategy } from "jalhyd";
 import { sprintf } from "sprintf-js";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 
@@ -23,6 +23,9 @@ export class DialogEditParamValuesComponent implements OnInit {
     /** available decimal separators */
     public decimalSeparators: { label: string; value: string; }[];
 
+    /** available extension strategies */
+    public extensionStrategies: { value: ExtensionStrategy; label: string; }[];
+
     /** current decimal separator */
     public decimalSeparator: string;
 
@@ -76,6 +79,16 @@ export class DialogEditParamValuesComponent implements OnInit {
             }
         ];
         this.decimalSeparator = this.decimalSeparators[0].value;
+        this.extensionStrategies = [
+            {
+                value: ExtensionStrategy.REPEAT_LAST,
+                label: this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY_REPEAT_LAST")
+            },
+            {
+                value: ExtensionStrategy.RECYCLE,
+                label: this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY_RECYCLE")
+            }
+        ];
 
         // chart configuration
         const nDigits = this.appSetupService.displayDigits;
@@ -104,6 +117,11 @@ export class DialogEditParamValuesComponent implements OnInit {
                     }
                 }]
             },
+            elements: {
+                line: {
+                    tension: 0
+                }
+            },
             tooltips: {
                 callbacks: {
                     label: function(tooltipItem) {
@@ -166,6 +184,14 @@ export class DialogEditParamValuesComponent implements OnInit {
         this.param.valueMode = v;
     }
 
+    public get selectedExtensionStrategy() {
+        return this.param.paramDefinition.extensionStrategy;
+    }
+
+    public set selectedExtensionStrategy(es) {
+        this.param.paramDefinition.extensionStrategy = es;
+    }
+
     public get isMinMax() {
         return this.param.valueMode === ParamValueMode.MINMAX;
     }
@@ -407,6 +433,10 @@ export class DialogEditParamValuesComponent implements OnInit {
         return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER");
     }
 
+    public get uitextExtensionStrategy() {
+        return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY");
+    }
+
     public ngOnInit() {
         this.initVariableValues();
     }
diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index 2151ddd92552b66eb6812e0183cb579fd5166085..f737e1d4c03120fa6833e76c3dd0eb8ed21093d8 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -15,6 +15,9 @@ import { ResultsComponent } from "./results.component";
 })
 export class VarResultsComponent extends ResultsComponent {
 
+    /** size of the longest variated parameter */
+    public size: number;
+
     /** résultats non mis en forme */
     protected _varResults: VarResults;
 
@@ -33,54 +36,56 @@ export class VarResultsComponent extends ResultsComponent {
         super();
     }
 
+    /** Refreshes results and builds the dataset */
     public set results(r: VarResults) {
         this._varResults = r;
-
         this._results = [];
         this._headers = [];
 
+        const nDigits = this.appSetupService.displayDigits;
+
         if (this._varResults) {
-            const nDigits = this.appSetupService.displayDigits;
-            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++;
+            // A. build headers
+            for (let i = 0; i < this._varResults.variatedParameters.length; i++) {
+                this._headers.push(this._varResults.variableParamHeaders[i]);
             }
-
-            this._headers.push(this._varResults.variableParamHeader);
             if (this._varResults.calculatedParameterHeader) {
                 this._headers.push(this._varResults.calculatedParameterHeader);
             }
-
             this._headers = this._headers.concat(this._varResults.extraResultHeaders);
-        }
-    }
 
-    public get hasResults(): boolean {
-        return this._varResults && this._varResults.hasResults;
-    }
-
-    public get headers() {
-        return this._headers;
-    }
+            // B. pre-extract variable parameters valueslet longest = 0;
+            const varValues = [];
+            // find longest list
+            this.size = 0;
+            for (let i = 0; i < this._varResults.variatedParameters.length; i++) {
+                const vs = this._varResults.variatedParameters[i].valuesIterator.count();
+                if (vs > this.size) {
+                    this.size = vs;
+                }
+            }
+            // get extended values lists for each variable parameter
+            for (const v of this._varResults.variatedParameters) {
+                const vv = [];
+                const iter = v.getExtendedValuesIterator(this.size);
+                while (iter.hasNext) {
+                    const nv = iter.next();
+                    vv.push(nv.value.toFixed(nDigits));
+                }
+                varValues.push(vv);
+            }
 
-    /**
-     * Returns a combination of and results and extraResults for mat-table
-     */
-    public get dataSet() {
-        const data = [];
-        const nDigits = this.appSetupService.displayDigits;
-        if (this._results) {
-            for (let i = 0; i < this._results.length; i++) {
-                const r = this._results[i];
+            // C. build dataset
+            for (let i = 0; i < this._varResults.resultElements.length; i++) {
                 const re: ResultElement = this._varResults.resultElements[i];
-
                 if (re) {
-                    // for each computation step, build ordered list of : variable param value; result; extra results
+                    // build ordered list of : variable params values; result; extra results
+                    const list = [];
 
-                    // 1. variable param value
-                    const list = [ r.param ];
+                    // 1. variable params values for this computation step
+                    for (const vv of varValues) {
+                        list.push(vv[i]);
+                    }
 
                     // 2. result
                     if (re.vCalc) { // sometimes does no exist (ex: Section Parametree)
@@ -97,11 +102,25 @@ export class VarResultsComponent extends ResultsComponent {
                         }
 
                     }
-                    data.push(list);
+                    this._results.push(list);
                 }
             }
         }
-        return data;
+    }
+
+    public get hasResults(): boolean {
+        return this._varResults && this._varResults.hasResults;
+    }
+
+    public get headers() {
+        return this._headers;
+    }
+
+    /**
+     * Returns a combination of results and extraResults for mat-table
+     */
+    public get dataSet() {
+        return this._results;
     }
 
     public exportAsSpreadsheet() {
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 df956b33acfe059a408a8e6e82390cdb246adfa1..5b105c01f1cb6385820c999c2741629b22654c0d 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
@@ -197,7 +197,7 @@ export class ParamFieldLineComponent implements OnChanges {
         let ret = true;
         if (this.param.paramDefinition.isCalculated) {
             const nub = this.param.paramDefinition.parentNub;
-            const p = nub.findFirstSingleParameter(this.param.paramDefinition);
+            const p = nub.findFirstCalculableParameter(this.param.paramDefinition);
             ret = (p !== undefined);
         }
         return ret;
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index f11fa831b984fb65843f48fe335130c958ceb23d..f5328dc134c1abbd23c1687cf375f4a98c5ae93e 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -368,7 +368,7 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
     }
 
     private get abscisseIterator(): INumberIterator {
-        return this._remousResults.varResults.variatedParameter.paramDefinition.valuesIterator;
+        return this._remousResults.varResults.variatedParameters[0].paramDefinition.valuesIterator;
     }
 
     private connectRessaut(lineFlu: LineData, lineTor: LineData) {
diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts
index efd02528851648f261c58ec55f4d9b3112257253..5cc0a4590950a287b9b2d5a42131b4523f1322dc 100644
--- a/src/app/components/results-graph/results-graph.component.ts
+++ b/src/app/components/results-graph/results-graph.component.ts
@@ -104,7 +104,7 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
     /**
      * Returns a human readable description of any param / result symbol
      */
-    public getChartAxisLabel(symbol: string) {
+    public getChartAxisLabel(symbol: string): string {
         return this._results.getChartAxisLabel(symbol);
     }
 
@@ -135,6 +135,19 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
         this._graphTypeComponent.addObserver(this);
     }
 
+    /**
+     * Calls getChartAxisLabel() and removes the symbol prefix
+     * (cannot rebuild a clean label here)
+     */
+    private axisLabelWithoutSymbol(symbol: string) {
+        let l = this._results.getChartAxisLabel(symbol);
+        const i = l.indexOf(": ");
+        if (i !== -1) {
+            l = l.substring(i + 2);
+        }
+        return l;
+    }
+
     /** forces Angular to rebuild the chart @see bug #137 */
     private forceRebuild() {
         this.displayChart = false;
@@ -172,20 +185,36 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
                 },
                 scaleLabel: {
                     display: true,
-                    labelString: this.chartX
+                    labelString: this.axisLabelWithoutSymbol(this.chartX)
                 }
             }],
             yAxes: [{
                 scaleLabel: {
                     display: true,
-                    labelString: this.chartY
+                    labelString: this.axisLabelWithoutSymbol(this.chartY)
                 }
             }]
         };
+        const that = this;
         this.graph_options["tooltips"] = {
+            displayColors: false,
             callbacks: {
-                label: function(tooltipItem, data) {
-                    return Number(tooltipItem.yLabel).toFixed(nDigits);
+                title: (tooltipItems, data) => {
+                    return this.chartY + " = " + Number(tooltipItems[0].yLabel).toFixed(nDigits);
+                },
+                label: (tooltipItem, data) => {
+                    const lines: string[] = [];
+                    for (const v of that._results.getVariatingParametersSymbols()) {
+                        const series = that._results.getValuesSeries(v);
+                        const line = v + " = " + series[tooltipItem.index].toFixed(nDigits);
+                        if (v === this.chartX) {
+                            lines.unshift("");
+                            lines.unshift(line);
+                        } else {
+                            lines.push(line);
+                        }
+                    }
+                    return lines;
                 }
             }
         };
@@ -224,7 +253,7 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
                 },
                 scaleLabel: {
                     display: true,
-                    labelString: this.chartX
+                    labelString: this.axisLabelWithoutSymbol(this.chartX)
                 }
             }],
             yAxes: [{
@@ -235,14 +264,30 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
                 },
                 scaleLabel: {
                     display: true,
-                    labelString: this.chartY
+                    labelString: this.axisLabelWithoutSymbol(this.chartY)
                 }
             }]
         };
+        const that = this;
         this.graph_options["tooltips"] = {
+            displayColors: false,
             callbacks: {
-                label: function(tooltipItem, data) {
-                    return "(" + Number(tooltipItem.xLabel).toFixed(nDigits) + ", " + Number(tooltipItem.yLabel).toFixed(nDigits) + ")";
+                title: (tooltipItems, data) => {
+                    return this.chartY + " = " + Number(tooltipItems[0].yLabel).toFixed(nDigits);
+                },
+                label: (tooltipItem, data) => {
+                    const lines: string[] = [];
+                    for (const v of that._results.getVariatingParametersSymbols()) {
+                        const series = that._results.getValuesSeries(v);
+                        const line = v + " = " + series[tooltipItem.index].toFixed(nDigits);
+                        if (v === this.chartX) {
+                            lines.unshift("");
+                            lines.unshift(line);
+                        } else {
+                            lines.push(line);
+                        }
+                    }
+                    return lines;
                 }
             }
         };
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 875a52747478bf419389556ca866c3ce033eef8c..08c12186f48d4bda67b88076264f4ed650edd790 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -1,4 +1,4 @@
-import { Nub, Result, ComputeNode } from "jalhyd";
+import { Nub } from "jalhyd";
 
 import { FormCompute } from "./form-compute";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
@@ -14,18 +14,18 @@ export class FormComputeFixedVar extends FormCompute {
         return this._formResult as FormResultFixedVar;
     }
 
-    private getVariatedParameter(): NgParameter {
-        const res = this._formBase.getDisplayedParamFromState(ParamRadioConfig.VAR);
-        if (res !== undefined) {
-            return res;
-        }
-
-        const pms = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.LINK);
-        for (const p of pms) {
-            if (p.paramDefinition.hasMultipleValues) {
-                return p;
+    private getVariatedParameters(): NgParameter[] {
+        let res: NgParameter[] = [];
+        res = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.VAR);
+        if (res.length === 0) {
+            const pms = this._formBase.getDisplayedParamListFromState(ParamRadioConfig.LINK);
+            for (const p of pms) {
+                if (p.paramDefinition.hasMultipleValues) {
+                    res.push(p);
+                }
             }
         }
+        return res;
     }
 
     private getComputedParameter(): NgParameter {
@@ -42,15 +42,15 @@ export class FormComputeFixedVar extends FormCompute {
         const computedParam: NgParameter = this.getComputedParameter();
         this.formResult.resetResults(); // to avoid adding fixed parameters more than once (see below)
         this.formResult.addFixedParameters();
-        const varParam: NgParameter = this.getVariatedParameter();
+        const varParams: NgParameter[] = this.getVariatedParameters();
 
-        if (varParam === undefined) {
+        if (varParams.length === 0) {
             // pas de paramètre à varier
             this.formResult.fixedResults.result = nub.result;
             this.formResult.fixedResults.calculatedParameter = computedParam;
         } else {
             // il y a un paramètre à varier
-            this.formResult.varResults.variatedParameter = varParam;
+            this.formResult.varResults.variatedParameters = varParams;
             this.formResult.varResults.calculatedParameter = computedParam;
 
             this.formResult.varResults.result = nub.result;
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index d30352a577096f548986041f60cde084b368e641..3e833eed46eeac7a0a991bafde36403d373036b9 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -39,10 +39,10 @@ export class FormComputeSectionParametree extends FormCompute {
         const sect: acSection = sectNub.section;
         this._sectionResults.section = sect;
 
-        const varParam = this._formSection.getSectionVariatedParameter();
-        if (varParam) {
+        const varParams = this._formSection.getSectionVariatedParameters();
+        if (varParams.length > 0) {
             // résultats variés avec tous les résultats complémentaires
-            this._varResults.variatedParameter = varParam;
+            this._varResults.variatedParameters = varParams;
             this._varResults.result = sectNub.result;
             this._varResults.update(false);
         } else {
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index 309a06613147474af44c2a683d39d325122842e3..a2c011e8df49e4a62fa8010da406a92e1322c1dd 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -18,8 +18,8 @@ export class FormDefSection {
         return this._sectionSourceId !== undefined;
     }
 
-    public getSectionVariatedParameter(): NgParameter {
-        return this._formBase.getDisplayedParamFromState(ParamRadioConfig.VAR);
+    public getSectionVariatedParameters(): NgParameter[] {
+        return this._formBase.getDisplayedParamListFromState(ParamRadioConfig.VAR);
     }
 
     public getSectionComputedParam(): { symbol: string, label: string } {
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 0154d6ae487375456d7897b826d265f59d6df597..679d3b1f3f4058d76279820637706cf9e3224621 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -237,6 +237,10 @@ export class NgParameter extends InputField implements Observer {
         return this._paramDef.valueList;
     }
 
+    public get inferredValuesList() {
+        return this._paramDef.getInferredValuesList();
+    }
+
     public get isValid() {
         if (this.radioState === undefined) {
             return false;
@@ -296,6 +300,10 @@ export class NgParameter extends InputField implements Observer {
         }
     }
 
+    public getExtendedValuesIterator(size: number): INumberIterator {
+        return this._paramDef.getExtendedValuesIterator(size);
+    }
+
     /**
      * notification envoyée après la modification de la valeur du paramètre
      */
diff --git a/src/app/results/plottable-data.ts b/src/app/results/plottable-data.ts
index 609c388aaaa0cb49556063ce170c88478cec7c26..a5493b94be96bd509ec89ad9c9a61facd54ffa9c 100644
--- a/src/app/results/plottable-data.ts
+++ b/src/app/results/plottable-data.ts
@@ -14,7 +14,13 @@ export interface PlottableData {
      * (usually a variable symbol like "Q", "Z1"…)
      * @param symbol parameter / result symbol (ex: "Q")
      */
-    getChartAxisLabel(symbol: string);
+    getChartAxisLabel(symbol: string): string;
+
+    /**
+     * Returns the translated name of the given symbol (usually an extraResult)
+     * if available, with its unit, but without the symbol itself
+     */
+    expandLabelFromSymbol(symbol: string): string;
 
     /**
      * Returns a list of plottable parameters / result elements, that can be defined
@@ -27,4 +33,10 @@ export interface PlottableData {
      * @param symbol parameter / result symbol (ex: "Q")
      */
     getValuesSeries(symbol: string): any[];
+
+    /**
+     * Returns the list of variating parameters
+     * (used by tooltip functions)
+     */
+    getVariatingParametersSymbols(): string[];
 }
diff --git a/src/app/results/plottable-pab-results.ts b/src/app/results/plottable-pab-results.ts
index c8cdd29641aa9801f8394052f6d888f00bf2dcd7..27e5685d9d0c257798729acf56326acf3c22d1dc 100644
--- a/src/app/results/plottable-pab-results.ts
+++ b/src/app/results/plottable-pab-results.ts
@@ -29,10 +29,14 @@ export class PlottablePabResults implements PlottableData {
      * Returns the label to display, for an element of getAvailableChartAxis()
      * @param symbol parameter / result symbol (ex: "Q")
      */
-    public getChartAxisLabel(symbol: string) {
+    public getChartAxisLabel(symbol: string): string {
         return this.pabResults.headers[this.pabResults.columns.indexOf(symbol)];
     }
 
+    public expandLabelFromSymbol(symbol: string): string {
+        return symbol;
+    }
+
     /**
      * Returns a list of plottable parameters / result elements, that can be defined
      * as X or Y chart axis
@@ -41,6 +45,11 @@ export class PlottablePabResults implements PlottableData {
         return this.pabResults.columns;
     }
 
+    // just to implement interface
+    public getVariatingParametersSymbols(): string[] {
+        return [];
+    }
+
     /**
      * Returns the series of values for the required symbol
      * @param symbol parameter / result symbol (ex: "Q")
diff --git a/src/app/results/remous-results.ts b/src/app/results/remous-results.ts
index 1127bf61fb4b6b2015f46bee279a9dbb3bfccfbe..6d6e1f6e104badd016b4c449f01127e889ee05f0 100644
--- a/src/app/results/remous-results.ts
+++ b/src/app/results/remous-results.ts
@@ -137,7 +137,7 @@ export class RemousResults extends CalculatorResults {
         this._log.addLog(this._result.globalLog);
 
         this._varResults = new VarResults();
-        this._varResults.variatedParameter = new NgParameter(this._xValues, undefined);
+        this._varResults.variatedParameters = [ new NgParameter(this._xValues, undefined) ];
         this._varResults.calculatedParameter
             = new NgParameter(new ParamDefinition(null, "Ligne d'eau", ParamDomainValue.POS_NULL), undefined);
         this._varResults.result = this._result;
diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts
index 891f7c008aa8375fef89edc1c1b5469eafb942a8..b01195b15a1cd932d5b18b4fdf6d8ae9cd9fd795 100644
--- a/src/app/results/var-results.ts
+++ b/src/app/results/var-results.ts
@@ -8,14 +8,14 @@ import { GraphType } from "./graph-type";
 
 export class VarResults extends CalculatedParamResults implements PlottableData {
     /**
-     * paramètre varié
+     * paramètres variés
      */
-    private _variatedParam: NgParameter;
+    private _variatedParams: NgParameter[];
 
     /**
-     * titre de la 1ère colonne des résultats variés
+     * titre des colonnes des résultats variés
      */
-    private _variableParamHeader: string;
+    private _variableParamHeaders: string[];
 
     /**
      * clés des résultats complémentaires
@@ -41,6 +41,12 @@ export class VarResults extends CalculatedParamResults implements PlottableData
      */
     public chartY: string;
 
+    /** size of the longest variated parameter */
+    public size: number;
+
+    /** index of the longest variated parameter */
+    public longest: number;
+
     /**
      * tableau des ordonnées du graphe des résultats variés
      */
@@ -53,23 +59,26 @@ export class VarResults extends CalculatedParamResults implements PlottableData
 
     public reset() {
         super.reset();
-        this._variableParamHeader = undefined;
+        this._variableParamHeaders = [];
         this._extraResultHeaders = [];
         this.extraResultKeys = [];
         this._yValues = [];
+        this.longest = 0;
     }
 
-    public get variatedParameter(): NgParameter {
-        return this._variatedParam;
+    public get variatedParameters(): NgParameter[] {
+        return this._variatedParams;
     }
 
-    public set variatedParameter(p: NgParameter) {
-        this._variatedParam = p;
-        this._variableParamHeader = CalculatorResults.paramLabel(this._variatedParam, true);
+    public set variatedParameters(p: NgParameter[]) {
+        this._variatedParams = p;
+        this._variableParamHeaders = this._variatedParams.map((v) => {
+            return CalculatorResults.paramLabel(v, true);
+        });
     }
 
-    public get variableParamHeader() {
-        return this._variableParamHeader;
+    public get variableParamHeaders() {
+        return this._variableParamHeaders;
     }
 
     public get yValues() {
@@ -84,24 +93,34 @@ export class VarResults extends CalculatedParamResults implements PlottableData
         return this._extraResultHeaders;
     }
 
-    public getChartAxisLabel(symbol: string) {
+    public getChartAxisLabel(symbol: string): string {
         // 1. calculated param ?
         if (this.calculatedParameter && this.calculatedParameter.symbol === symbol) {
             return this.calculatedParameterHeader;
-        } else
+        }
         // 2. variated param ?
-        if (this.variatedParameter.symbol === symbol) {
-            return this.variableParamHeader;
-        } else {
-            // 3. Result element ?
-            // calculator type for translation
-            const sn = this.result.sourceNub;
-            let ct = sn.calcType;
-            if (sn.parent) {
-                ct = sn.parent.calcType;
+        for (let i = 0; i < this.variatedParameters.length; i++) {
+            if (this._variatedParams[i].symbol === symbol) {
+                return this.variableParamHeaders[i];
             }
-            return ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct, symbol);
         }
+        // 3. Result element
+        return this.expandLabelFromSymbol(symbol);
+
+    }
+
+    /**
+     * Returns the translated name of the given symbol (usually an extraResult) with
+     * its unit, but without the symbol itself
+     */
+    public expandLabelFromSymbol(symbol: string): string {
+        // calculator type for translation
+        const sn = this.result.sourceNub;
+        let ct = sn.calcType;
+        if (sn.parent) {
+            ct = sn.parent.calcType;
+        }
+        return ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct, symbol);
     }
 
     /**
@@ -117,19 +136,21 @@ export class VarResults extends CalculatedParamResults implements PlottableData
                     series.push(r.vCalc);
                 }
             }
-        } else
+        }
         // 2. variated param ?
-        if (this.variatedParameter.symbol === symbol) {
-            for (const v of this.variatedParameter.valuesIterator) {
-                series.push(v);
+        for (let i = 0; i < this.variatedParameters.length; i++) {
+            if (this._variatedParams[i].symbol === symbol) {
+                const iter = this.variatedParameters[i].getExtendedValuesIterator(this.size);
+                for (const v of iter) {
+                    series.push(v);
+                }
             }
-        } else {
-            // 3. Result element ?
-            for (const r of this.result.resultElements) { // re:ResultElement
-                for (const k in r.extraResults) {
-                    if (k === symbol) {
-                        series.push(r.extraResults[k]);
-                    }
+        }
+        // 3. Result element ?
+        for (const r of this.result.resultElements) { // re:ResultElement
+            for (const k in r.extraResults) {
+                if (k === symbol) {
+                    series.push(r.extraResults[k]);
                 }
             }
         }
@@ -146,16 +167,42 @@ export class VarResults extends CalculatedParamResults implements PlottableData
         if (this.calculatedParameter) {
             res.push(this.calculatedParameter.symbol);
         }
-        res.push(this.variatedParameter.symbol);
+        for (const v of this._variatedParams) {
+            res.push(v.symbol);
+        }
         for (const erk of this.extraResultKeys) {
             res.push(erk);
         }
         return res;
     }
 
+    /**
+     * Returns the list of variating parameters
+     * (used by tooltip functions)
+     */
+    public getVariatingParametersSymbols(): string[] {
+        return this._variatedParams.map((vp) => {
+            return vp.symbol;
+        });
+    }
+
     public update(displaySymbol: boolean) {
-        if (this._variableParamHeader === undefined) {
-            this._variableParamHeader = CalculatorResults.paramLabel(this.variatedParameter, displaySymbol);
+        if (this._variableParamHeaders.length === 0) {
+            this._variableParamHeaders = this._variatedParams.map((v) => {
+                return CalculatorResults.paramLabel(v, true);
+            });
+        }
+
+        // liste la plus longue
+        this.size = 0;
+        let i = 0;
+        for (const v of this._variatedParams) {
+            const s = v.valuesIterator.count();
+            if (s > this.size) {
+                this.size = s;
+                this.longest = i;
+            }
+            i++;
         }
 
         // valeurs du paramètre à calculer
@@ -181,7 +228,7 @@ export class VarResults extends CalculatedParamResults implements PlottableData
         } else if (this.extraResultKeys.length > 0) {
             defaultY = this.extraResultKeys[0];
         }
-        this.chartX = this.chartX || this.variatedParameter.symbol;
+        this.chartX = this.chartX || this.variatedParameters[this.longest].symbol;
         this.chartY = defaultY;
 
         // calculator type for translation
@@ -202,10 +249,10 @@ export class VarResults extends CalculatedParamResults implements PlottableData
         // (might be the previous variated parameter, that is not accessible anymore)
         const aca = this.getAvailableChartAxis();
         if (! aca.includes(this.chartX)) {
-            this.chartX = this.variatedParameter.symbol;
+            this.chartX = this.variatedParameters[0].symbol;
         }
         if (! aca.includes(this.chartY)) {
-            this.chartY = this.variatedParameter.symbol;
+            this.chartY = this.variatedParameters[0].symbol;
         }
     }
 }
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index b521d5451ff8f2ac832d7be94c448749a3e894ec..32364c09832fef08f3c9054093616ecdb6886227 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -212,6 +212,9 @@
     "INFO_PARAMFIELD_PARAMFIXE": "Fixed",
     "INFO_PARAMFIELD_PARAMLIE_LABEL": "Linked parameter",
     "INFO_PARAMFIELD_PARAMLIE": "Link",
+    "INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY": "Values list extension strategy",
+    "INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY_REPEAT_LAST": "Repeat last value",
+    "INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY_RECYCLE": "Recycle values",
     "INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER": "Import file",
     "INFO_PARAMFIELD_PARAMVARIER_MINMAXSTEP": "min: %s, max: %s, step: %s",
     "INFO_PARAMFIELD_PARAMVARIER_MODE": "Mode",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index efa2d9ba84232826e707875717056569989a9283..7228186b3420c17e0e4e7633247c1623fca744fb 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -212,6 +212,9 @@
     "INFO_PARAMFIELD_PARAMFIXE": "fixé",
     "INFO_PARAMFIELD_PARAMLIE_LABEL": "Paramètre lié",
     "INFO_PARAMFIELD_PARAMLIE": "lié",
+    "INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY": "Stratégie d'extension de la liste de valeurs",
+    "INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY_REPEAT_LAST": "Répéter la dernière valeur",
+    "INFO_PARAMFIELD_PARAMVARIER_EXT_STRATEGY_RECYCLE": "Réutiliser les valeurs",
     "INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER": "Importer un fichier",
     "INFO_PARAMFIELD_PARAMVARIER_MINMAXSTEP": "min : %s, max : %s, pas : %s",
     "INFO_PARAMFIELD_PARAMVARIER_MODE": "Mode",