diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 59f49747f69c369053e359601c66b2b424ab1d24..f1d0c02158a2d200aa58511119fd390dd95f0b8a 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -66,7 +66,6 @@ import { FixedVarResultsComponent } from "./components/fixedvar-results/fixedvar
 import { SectionResultsComponent } from "./components/section-results/section-results.component";
 import { GenericCalculatorComponent } from "./components/generic-calculator/calculator.component";
 import { CalculatorNameComponent } from "./components/generic-calculator/calc-name.component";
-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 { ResultsChartComponent } from "./components/results-chart/results-chart.component";
@@ -186,7 +185,6 @@ const appRoutes: Routes = [
         AppComponent,
         ApplicationSetupComponent,
         BaseParamInputComponent,
-        CalcCanvasComponent,
         CalculatorListComponent,
         CalculatorNameComponent,
         CalculatorResultsComponent,
diff --git a/src/app/components/calculator-results/calculator-results.component.html b/src/app/components/calculator-results/calculator-results.component.html
index 4befd3308c7879d86644375226764181d321f72f..61ddf062b3f7b144d0375276fc83fcd9963bc8ee 100644
--- a/src/app/components/calculator-results/calculator-results.component.html
+++ b/src/app/components/calculator-results/calculator-results.component.html
@@ -1,10 +1,10 @@
 <div>
-    <section-results [hidden]="! isSP"></section-results>
-    <remous-results [hidden]="! isRemous"></remous-results>
-    <pab-results [hidden]="! isPAB"></pab-results>
-    <pb-results [hidden]="! isPB"></pb-results>
-    <verificateur-results [hidden]="! isVerificateur"></verificateur-results>
-    <macrorugo-compound-results [hidden]="! isMRC"></macrorugo-compound-results>
-    <jet-results [hidden]="! isJet"></jet-results>
-    <fixedvar-results [hidden]="! showGenericResults"></fixedvar-results>
+    <section-results *ngIf="isSP" [results]=formResultsArray></section-results>
+    <remous-results *ngIf="isRemous" [results]=formResultsArray></remous-results>
+    <pab-results *ngIf="isPAB" [results]=formResultsArray></pab-results>
+    <pb-results *ngIf="isPB" [results]=formResultsArray></pb-results>
+    <verificateur-results *ngIf="isVerificateur" [results]=formResultsArray></verificateur-results>
+    <macrorugo-compound-results *ngIf="isMRC" [results]=formResultsArray></macrorugo-compound-results>
+    <jet-results *ngIf="isJet" [results]=formResultsArray></jet-results>
+    <fixedvar-results *ngIf="! isJet" [results]=formResultsArray></fixedvar-results>
 </div>
diff --git a/src/app/components/calculator-results/calculator-results.component.ts b/src/app/components/calculator-results/calculator-results.component.ts
index 8c36c651ca00a67e5b2601158575dfb5b86ce4d9..796d0e481ca79e3504b8ed9efdb98377b1f3a3cd 100644
--- a/src/app/components/calculator-results/calculator-results.component.ts
+++ b/src/app/components/calculator-results/calculator-results.component.ts
@@ -1,17 +1,8 @@
-import { Component, ViewChild, Output, EventEmitter, AfterViewChecked, Inject, forwardRef } from "@angular/core";
+import { Component, Output, EventEmitter, AfterViewChecked, Inject, forwardRef, Input } from "@angular/core";
 
-import { FixedVarResultsComponent } from "../../components/fixedvar-results/fixedvar-results.component";
-import { SectionResultsComponent } from "../../components/section-results/section-results.component";
-import { RemousResultsComponent } from "../../components/remous-results/remous-results.component";
-import { PabResultsComponent } from "../../components/pab-results/pab-results.component";
-import { MacrorugoCompoundResultsComponent } from "../macrorugo-compound-results/macrorugo-compound-results.component";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
-import { JetResultsComponent } from "../jet-results/jet-results.component";
+import { CalculatorResults } from "../../results/calculator-results";
 import { GenericCalculatorComponent } from "../generic-calculator/calculator.component";
-import { VerificateurResultsComponent } from "../verificateur-results/verificateur-results.component";
-
-import { CalculatorType } from "jalhyd";
-import { PbResultsComponent } from "../pb-results/pb-results.component";
 
 @Component({
     selector: "calc-results",
@@ -21,57 +12,7 @@ export class CalculatorResultsComponent implements AfterViewChecked {
 
     private _formulaire: FormulaireDefinition;
 
-    /**
-     * composant d'affichage des résultats de paramètres fixés/variables
-     */
-    @ViewChild(FixedVarResultsComponent, { static: true })
-    private fixedVarResultsComponent: FixedVarResultsComponent;
-
-    /**
-     * composant d'affichage des résultats des sections paramétrées
-     */
-    @ViewChild(SectionResultsComponent, { static: true })
-    private sectionResultsComponent: SectionResultsComponent;
-
-    /**
-     * composant d'affichage des résultats des courbes de remous
-     */
-    @ViewChild(RemousResultsComponent, { static: true })
-    private remousResultsComponent: RemousResultsComponent;
-
-    /**
-     * composant d'affichage des résultats des passes à bassins
-     */
-    @ViewChild(PabResultsComponent, { static: true })
-    private pabResultsComponent: PabResultsComponent;
-
-    /**
-     * composant d'affichage des résultats des vérificateurs de critères de franchissement
-     */
-    @ViewChild(VerificateurResultsComponent, { static: true })
-    private verificateurResultsComponent: VerificateurResultsComponent;
-
-    /*
-     * composant d'affichage des résultats des prébarrages
-     */
-    @ViewChild(PbResultsComponent, { static: true })
-    private pbResultsComponent: PbResultsComponent;
-
-    /**
-     * composant d'affichage des résultats des passes à macrorugosités complexes
-     */
-    @ViewChild(MacrorugoCompoundResultsComponent, { static: true })
-    private mrcResultsComponent: MacrorugoCompoundResultsComponent;
-
-    /**
-     * composant d'affichage des résultats des impacts de jet
-     */
-    @ViewChild(JetResultsComponent, { static: true })
-    private jetResultsComponent: JetResultsComponent;
-
-    /**
-     * événement émis à la fin du dessin de la vue
-     */
+    /** notify CalculatorComponent that it may scroll down to results panel */
     @Output()
     private afterViewChecked = new EventEmitter();
 
@@ -79,86 +20,49 @@ export class CalculatorResultsComponent implements AfterViewChecked {
         @Inject(forwardRef(() => GenericCalculatorComponent)) private calculatorComponent: GenericCalculatorComponent
     ) { }
 
-    // @TODO this system is sh*tty !
+    @Input()
     public set formulaire(f: FormulaireDefinition) {
         this._formulaire = f;
-        if (this._formulaire === undefined) {
-            this.fixedVarResultsComponent.results = undefined;
-            this.sectionResultsComponent.results = undefined;
-            this.pbResultsComponent.results = undefined;
-            this.jetResultsComponent.results = undefined;
-            this.mrcResultsComponent.results = undefined;
-            this.pabResultsComponent.results = undefined;
-            this.remousResultsComponent.results = undefined;
-            this.verificateurResultsComponent.results = undefined;
-        } else {
-            this.sectionResultsComponent.results = f.results;
-            this.remousResultsComponent.results = f.results;
-            this.pabResultsComponent.results = f.results;
-            this.pbResultsComponent.results = f.results;
-            this.mrcResultsComponent.results = f.results;
-            // FixedVar and Jet are mutually incompatible (the 2nd extend the 1st)
-            if (this.isJet) {
-                this.jetResultsComponent.results = f.results;
-                this.fixedVarResultsComponent.results = undefined;
-            } else {
-                this.fixedVarResultsComponent.results = f.results;
-                this.jetResultsComponent.results = undefined;
-            }
-        }
     }
 
-    public updateView() {
-        this.fixedVarResultsComponent.updateView();
-        this.sectionResultsComponent.updateView();
-        this.remousResultsComponent.updateView();
-        this.pabResultsComponent.updateView();
-        this.pbResultsComponent.updateView();
-        this.mrcResultsComponent.updateView();
-        this.jetResultsComponent.updateView();
+    public get formResultsArray(): CalculatorResults[] {
+        let r: CalculatorResults[] = [];
+        if (this._formulaire !== undefined) {
+            r = this._formulaire.results;
+        }
+        return r;
     }
 
     public ngAfterViewChecked() {
         this.afterViewChecked.emit();
     }
 
-    /** Should we show the default FixedVarResultsComponent ? */
-    public get showGenericResults(): boolean {
-        return (
-            ! this.isJet
-            && ! this.isMRC
-            && ! this.isPAB
-            && ! this.isRemous
-            && ! this.isSP
-            && ! this.isVerificateur
-        );
-    }
-
-    public get isJet(): boolean {
-        return this.calculatorComponent.isJet;
+    public get isSP() {
+        return this.calculatorComponent.isSP;
     }
 
-    public get isMRC(): boolean {
-        return this.calculatorComponent.isMRC;
+    public get isRemous() {
+        return this.calculatorComponent.isRemous;
     }
 
-    public get isPAB(): boolean {
+    public get isPAB() {
         return this.calculatorComponent.isPAB;
     }
 
-    public get isPB(): boolean {
-        return this.calculatorComponent.is(CalculatorType.PreBarrage);
+    public get isPB() {
+        return this.calculatorComponent.isPB;
     }
 
-    public get isRemous(): boolean {
-        return this.calculatorComponent.is(CalculatorType.CourbeRemous);
+    public get isMRC() {
+        return this.calculatorComponent.isMRC;
     }
 
-    public get isSP(): boolean {
-        return this.calculatorComponent.is(CalculatorType.SectionParametree);
+    public get isJet() {
+        return this.calculatorComponent.isJet;
     }
 
-    public get isVerificateur(): boolean {
-        return this.calculatorComponent.is(CalculatorType.Verificateur);
+    public get isVerificateur() {
+        return this.calculatorComponent.isVerificateur;
     }
+
 }
diff --git a/src/app/components/canvas/canvas.component.ts b/src/app/components/canvas/canvas.component.ts
deleted file mode 100644
index 2035e886e543b1b0846c3e043fd0464a1c902f01..0000000000000000000000000000000000000000
--- a/src/app/components/canvas/canvas.component.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { Component, Input, ViewChild, ElementRef, AfterViewInit } from "@angular/core";
-
-@Component({
-    selector: "calc-canvas",
-    template: `<canvas #canvas
-    [attr.width]="width"
-    [attr.height]="height">
-    </canvas>
-    `
-})
-export class CalcCanvasComponent implements AfterViewInit {
-
-    public get width(): number {
-        return this._calcCanvas.nativeElement.width;
-    }
-
-    @Input()
-    public set width(w: number) {
-        this._calcCanvas.nativeElement.width = w;
-    }
-
-    public get height(): number {
-        return this._calcCanvas.nativeElement.height;
-    }
-
-    @Input()
-    public set height(h: number) {
-        this._calcCanvas.nativeElement.height = h;
-    }
-
-    private _context2d: CanvasRenderingContext2D;
-
-    @ViewChild("canvas", { static: true })
-    private _calcCanvas: ElementRef;
-
-    ngAfterViewInit() { // wait for the view to init before using the element
-        this._context2d = this._calcCanvas.nativeElement.getContext("2d");
-    }
-
-    public clear() {
-        if (this._context2d) {
-            this._context2d.clearRect(0, 0, this.width, this.height);
-        }
-    }
-
-    public setStrokeColor(r: number, g: number, b: number) {
-        const col: string = "rgb(" + r + "," + g + "," + b + ")";
-        this._context2d.strokeStyle = col;
-    }
-
-    public setFillColor(r: number, g: number, b: number) {
-        const col: string = "rgb(" + r + "," + g + "," + b + ")";
-        this._context2d.fillStyle = col;
-    }
-
-    public setFont(f: string) {
-        this._context2d.font = f;
-    }
-
-    public fillText(s: string, x: number, y: number, align?: any) {
-        if (align) {
-            this._context2d.textAlign = align;
-        }
-        this._context2d.fillText(s, x, y);
-    }
-
-    public setLineWidth(w: number) {
-        this._context2d.lineWidth = w;
-    }
-
-    public setLineDash(d: number[]) {
-        this._context2d.setLineDash(d);
-    }
-
-    public resetLineDash() {
-        this._context2d.setLineDash([]);
-    }
-
-    public drawRect(x1: number, y1: number, w: number, h: number) {
-        this._context2d.strokeRect(x1, y1, w, h);
-    }
-
-    public drawLine(x1: number, y1: number, x2: number, y2: number) {
-        this._context2d.beginPath();
-        this._context2d.moveTo(x1, y1);
-        this._context2d.lineTo(x2, y2);
-        this._context2d.stroke();
-    }
-
-    /**
-     *
-     * @param x The x axis of the coordinate for the ellipse's center.
-     * @param y The y axis of the coordinate for the ellipse's center.
-     * @param radiusX The ellipse's major-axis radius.
-     * @param radiusY The ellipse's minor-axis radius.
-     * @param rotation The rotation for this ellipse, expressed in radians
-     * @param startAngle The starting point, measured from the x axis, from which it will be drawn, expressed in radians
-     * @param endAngle The end ellipse's angle to which it will be drawn, expressed in radians
-     */
-    public drawEllipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number) {
-        this._context2d.beginPath();
-        this._context2d.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
-        this._context2d.stroke();
-    }
-
-    public get context2d(): CanvasRenderingContext2D {
-        return this._context2d;
-    }
-}
diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts
index 8477e6cefc8f389dfa5df1027650a4f06ae428a4..090c1829dd5427bc02aa85c4551c4de3221844c0 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.ts
+++ b/src/app/components/fixedvar-results/fixed-results.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ElementRef } from "@angular/core";
+import { Component, ViewChild, ElementRef, Input } from "@angular/core";
 
 import { FixedResults } from "../../results/fixed-results";
 import { I18nService } from "../../services/internationalisation.service";
@@ -35,6 +35,7 @@ export class FixedResultsComponent extends ResultsComponentDirective {
         super();
     }
 
+    @Input()
     public set results(r: FixedResults) {
         this._fixedResults = r;
     }
diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.html b/src/app/components/fixedvar-results/fixedvar-results.component.html
index 7676b026859cc72cbef157cf5b94edaa9a57d1d4..271a255087c96d893af18ff4988ba741125d3e68 100644
--- a/src/app/components/fixedvar-results/fixedvar-results.component.html
+++ b/src/app/components/fixedvar-results/fixedvar-results.component.html
@@ -1,8 +1,8 @@
 <div class="container">
     <!-- journal -->
-    <log></log>
+    <log [log]=mergedGlobalLogs></log>
 
-    <results-chart [hidden]="! showVarResultsChart"></results-chart>
+    <results-chart [hidden]="! showVarResultsChart" [results]=varResults [resultData]=varResults?.result></results-chart>
 
     <div>
         <!-- table des résultats fixés -->
diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts
index 04136deb595d22df2e9952c7a456a34d5edb102c..d93bcc55c48d40acd98a23d556a7ce1b8a838c69 100644
--- a/src/app/components/fixedvar-results/fixedvar-results.component.ts
+++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts
@@ -1,14 +1,9 @@
-import { Component, ViewChild, DoCheck } from "@angular/core";
+import { Component, Input } from "@angular/core";
 
-import { LogComponent } from "../../components/log/log.component";
 import { FixedResults } from "../../results/fixed-results";
 import { VarResults } from "../../results/var-results";
-import { ResultsChartComponent } from "../results-chart/results-chart.component";
 import { CalculatorResults } from "../../results/calculator-results";
 import { Result, cLog } from "jalhyd";
-import { NgParameter } from "../../formulaire/elements/ngparam";
-import { FixedResultsComponent } from "./fixed-results.component";
-import { VarResultsComponent } from "./var-results.component";
 import { ResultsComponentDirective } from "./results.component";
 
 @Component({
@@ -18,36 +13,14 @@ import { ResultsComponentDirective } from "./results.component";
         "./fixedvar-results.component.scss"
     ]
 })
-export class FixedVarResultsComponent extends ResultsComponentDirective implements DoCheck {
+export class FixedVarResultsComponent extends ResultsComponentDirective {
     /**
      * résultats non mis en forme
      */
     protected _fixedResults: FixedResults;
     protected _varResults: VarResults;
 
-    /**
-     * true si les résultats doiventt être remis à jour
-     */
-    protected _doUpdate = false;
-
-    @ViewChild(FixedResultsComponent)
-    private fixedResultsComponent: FixedResultsComponent;
-
-    @ViewChild(VarResultsComponent)
-    private varResultsComponent: VarResultsComponent;
-
-    /**
-     * composant journal
-     */
-    @ViewChild(LogComponent)
-    private logComponent: LogComponent;
-
-    /**
-     * graphique dans le cas d'un paramètre à varier
-     */
-    @ViewChild(ResultsChartComponent)
-    private resultsChartComponent: ResultsChartComponent;
-
+    @Input()
     public set results(rs: CalculatorResults[]) {
         this._fixedResults = undefined;
         this._varResults = undefined;
@@ -60,40 +33,6 @@ export class FixedVarResultsComponent extends ResultsComponentDirective implemen
                 }
             }
         }
-        this.updateView();
-    }
-
-    public updateView() {
-        if (this.logComponent) {
-            this.logComponent.log = undefined;
-        }
-        if (this.fixedResultsComponent) {
-            this.fixedResultsComponent.results = undefined;
-        }
-        if (this.varResultsComponent) {
-            this.varResultsComponent.results = undefined;
-        }
-        if (this.resultsChartComponent) {
-            this.resultsChartComponent.results = undefined;
-        }
-
-        // set _doUpdate flag so that results are rebuilt on the next Angular display cycle
-        this._doUpdate = false;
-        if (this._fixedResults !== undefined) {
-            this._doUpdate = this._fixedResults.hasResults || this._fixedResults.hasLog;
-        }
-        if (this._varResults !== undefined) {
-            this._doUpdate = this._doUpdate || this._varResults.hasResults || this._varResults.hasLog;
-        }
-    }
-
-    public ngDoCheck() {
-        if (this._doUpdate) {
-            // clodo trick @see nghyd#308
-            setTimeout(() => {
-                this._doUpdate = !this.updateResults();
-            }, 10);
-        }
     }
 
     private mergeLog(result: Result, log: cLog) {
@@ -106,7 +45,7 @@ export class FixedVarResultsComponent extends ResultsComponentDirective implemen
         }
     }
 
-    private get mergedGlobalLogs(): cLog {
+    public get mergedGlobalLogs(): cLog {
         const res = new cLog();
         if (this._fixedResults) {
             this.mergeLog(this._fixedResults.result, res);
@@ -117,42 +56,6 @@ export class FixedVarResultsComponent extends ResultsComponentDirective implemen
         return res;
     }
 
-    /**
-     * met à jour l'affichage des résultats
-     * @returns true si les résultats ont pu être mis à jour
-     */
-    protected updateResults() {
-        const fixedUpdated = this._fixedResults !== undefined && this.fixedResultsComponent !== undefined;
-        if (fixedUpdated) {
-            this.fixedResultsComponent.results = this._fixedResults;
-        }
-
-        let graphUpdated: boolean;
-        let varUpdated: boolean;
-        if (this._varResults && this._varResults.hasResults) {
-            varUpdated = this.varResultsComponent !== undefined;
-            if (varUpdated) {
-                this.varResultsComponent.results = this._varResults;
-            }
-
-            graphUpdated = this.resultsChartComponent !== undefined;
-            if (graphUpdated) {
-                this.resultsChartComponent.results = this._varResults;
-                this.resultsChartComponent.updateView();
-            }
-        } else {
-            varUpdated = true;
-            graphUpdated = true;
-        }
-
-        const logUpdated = this.logComponent !== undefined;
-        if (logUpdated) {
-            this.logComponent.log = this.mergedGlobalLogs;
-        }
-
-        return fixedUpdated && varUpdated && logUpdated && graphUpdated;
-    }
-
     /**
      * affichage de la table des résultats fixés
      */
@@ -171,7 +74,7 @@ export class FixedVarResultsComponent extends ResultsComponentDirective implemen
      * affichage du graphique des résultats variés
      */
     public get showVarResultsChart(): boolean {
-        return this._varResults && this._varResults.hasPlottableResults;
+        return this._varResults && this._varResults.hasPlottableResults();
     }
 
     public getFixedResultClass(i: number) {
diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index d1ba56c328e9e7c5de41d359b89adbf7309aad14..7493401d2776c1760fbe9c616232aa62ceefecea 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ElementRef } from "@angular/core";
+import { Component, ViewChild, ElementRef, Input } from "@angular/core";
 
 import { MatDialog } from "@angular/material/dialog";
 
@@ -45,6 +45,7 @@ export class VarResultsComponent extends ResultsComponentDirective {
     }
 
     /** Refreshes results and builds the dataset */
+    @Input()
     public set results(r: VarResults) {
         this._varResults = r;
         this._results = [];
diff --git a/src/app/components/generic-calculator/calc-name.component.ts b/src/app/components/generic-calculator/calc-name.component.ts
index a07f51b0c4732537fd17ff912110d20a839f0baf..c1cc4bb7e40a29744a1726e52cc3cf2fd0dac374 100644
--- a/src/app/components/generic-calculator/calc-name.component.ts
+++ b/src/app/components/generic-calculator/calc-name.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, Input } from "@angular/core";
 import { GenericInputComponentDirective } from "../generic-input/generic-input.component";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
 import { I18nService } from "../../services/internationalisation.service";
@@ -20,6 +20,11 @@ export class CalculatorNameComponent extends GenericInputComponentDirective {
         super(null, intlService, appSetupService);
     }
 
+    @Input()
+    public set model(v: any) {
+        super.model = v;
+    }
+
     /**
      * formulaire géré
      */
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 906fc6a98db4ea4bc4e2811f41a90ec71a96cb08..7b085815a6bade8c59f4beff28627c292043d9fa 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -57,7 +57,7 @@
         <mat-card-content>
 
             <!-- nom du module de calcul -->
-            <calc-name id="calculator-name" [title]="uitextCalculatorName"></calc-name>
+            <calc-name id="calculator-name" [model]="formulaire" [title]="uitextCalculatorName"></calc-name>
 
             <button mat-raised-button type="button" color="accent" id="load-predefined-espece" *ngIf="isEspece"
                 (click)="loadPredefinedEspece()" [title]="uitextLoadPredefinedEspece">
@@ -192,7 +192,7 @@
                     </button>
 
                     <mat-card-content>
-                        <calc-results id="resultsComp" (afterViewChecked)="onCalcResultsViewChecked()"></calc-results>
+                        <calc-results id="resultsComp" [formulaire]="formulaire" (afterViewChecked)="onCalcResultsViewChecked()"></calc-results>
                     </mat-card-content>
                 </mat-card>
 
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 4951178b602694cc61ae2cb9e09ccba988f93b13..33efee5069f6ab5ecadf16ebb0c12d3fa3954de0 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -31,10 +31,8 @@ import { ApplicationSetupService } from "../../services/app-setup.service";
 import { I18nService } from "../../services/internationalisation.service";
 import { FieldSet } from "../../formulaire/elements/fieldset";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
-import { CalculatorResultsComponent } from "../../components/calculator-results/calculator-results.component";
 import { Subscription } from "rxjs";
 import { FieldSetComponent } from "../field-set/field-set.component";
-import { CalculatorNameComponent } from "./calc-name.component";
 import { FormulaireElement } from "../../formulaire/elements/formulaire-element";
 import { FieldsetContainer } from "../../formulaire/elements/fieldset-container";
 import { FieldsetContainerComponent } from "../fieldset-container/fieldset-container.component";
@@ -46,7 +44,6 @@ import { DialogGeneratePARSimulationComponent } from "../dialog-generate-par-sim
 import { DialogLoadPredefinedEspeceComponent } from "../dialog-load-predefined-espece/dialog-load-predefined-espece.component";
 import { PabTable } from "../../formulaire/elements/pab-table";
 import { MultiDimensionResults } from "../../results/multidimension-results";
-import { NgParameter } from "../../formulaire/elements/ngparam";
 import { FormulaireFixedVar } from "../../formulaire/definition/form-fixedvar";
 import { PbSchema } from "../../formulaire/elements/pb-schema";
 import { PbSchemaComponent } from "../pb-schema/pb-schema.component";
@@ -86,18 +83,6 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
     @ViewChild(PbSchemaComponent)
     private _pbSchemaComponent: PbSchemaComponent;
 
-    /**
-     * composant d'affichage des résultats
-     */
-    @ViewChild(CalculatorResultsComponent, { static: true })
-    private resultsComponent: CalculatorResultsComponent;
-
-    /**
-     * composant "nom du module de calcul"
-     */
-    @ViewChild(CalculatorNameComponent, { static: true })
-    private _calculatorNameComponent: CalculatorNameComponent;
-
     /**
      * formulaire affiché
      */
@@ -179,6 +164,10 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         }, this)));
     }
 
+    public get formulaire(): FormulaireDefinition {
+        return this._formulaire;
+    }
+
     public get formElements(): FormulaireElement[] {
         if (this._formulaire === undefined) {
             return [];
@@ -388,10 +377,6 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         this.appComponent.showProgressBar = true;
         this._computeClicked = true;
         this.showPBInputData = false;
-        // send resetForm to clear log
-        this._formulaire.notifyObservers({
-            "action": "resetForm",
-        }, this._formulaire);
         // calculate module
         setTimeout(() => {
             this._formulaire.doCompute();
@@ -443,22 +428,6 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         }
     }
 
-    private setForm(f: FormulaireDefinition) {
-        if (this._formulaire !== undefined) {
-            this._formulaire.removeObserver(this);
-        }
-        this._formulaire = f;
-        if (this._formulaire !== undefined) {
-            this._formulaire.addObserver(this);
-        }
-    }
-
-    private updateFormulaireResults(uid: string) {
-        if (this._formulaire.uid === uid) {
-            this.resultsComponent.updateView();
-        }
-    }
-
     // interface Observer
 
     update(sender: any, data: any): void {
@@ -466,22 +435,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
             switch (data["action"]) {
                 case "currentFormChanged":
                     const uid: string = data["formId"];
-                    this.setForm(this.formulaireService.getFormulaireFromId(uid));
-                    this.resultsComponent.formulaire = this._formulaire;
-                    this._calculatorNameComponent.model = this._formulaire;
+                    this._formulaire = (this.formulaireService.getFormulaireFromId(uid));
                     // reload localisation in all cases (it does not eat bread)
                     this.formulaireService.updateFormulaireLocalisation(this._formulaire);
                     break;
             }
-        } else if (sender instanceof FormulaireDefinition) {
-            let f: FormulaireDefinition;
-            switch (data["action"]) {
-                case "resetForm": // réinitialisation du formulaire
-                case "resultsUpdated":
-                    f = sender as FormulaireDefinition;
-                    this.updateFormulaireResults(f.uid);
-                    break;
-            }
         }
     }
 
@@ -557,8 +515,6 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
      */
     public onInputChange(event: any) {
         this._formulaire.resetResults([], (event ? event.symbol : undefined));
-        // to refresh log components, that are fed manually (!)
-        this.resultsComponent.updateView();
     }
 
     /**
@@ -604,8 +560,6 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         // show proper form (actually subform elements) or proper results,
         // depending on what was clicked
         (this._formulaire as FormulairePrebarrage).nodeSelected(event.node);
-        // refresh results component
-        this.resultsComponent.updateView();
     }
 
     public openHelp() {
@@ -678,11 +632,26 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         return this.is(CalculatorType.Par);
     }
 
+    // true if current Nub is Verificateur
+    public get isVerificateur() {
+        return this.is(CalculatorType.Verificateur);
+    }
+
     // true if current Nub is Espece
     public get isEspece() {
         return this.is(CalculatorType.Espece);
     }
 
+    // true if current Nub is PAR
+    public get isSP() {
+        return this.is(CalculatorType.SectionParametree);
+    }
+
+    // true if current Nub is PAR
+    public get isRemous() {
+        return this.is(CalculatorType.CourbeRemous);
+    }
+
     /**
      * Returns true if no parameter is varying; ignores parameters having
      * one of the given {except} symbols, if any
@@ -1060,7 +1029,6 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
                 const form = this._formulaire as FormulaireFixedVar;
                 const nub = (form.currentNub as Espece);
                 nub.loadPredefinedSpecies(result.selected);
-                console.log("================ espèce chargée, refresh tout");
                 form.refreshFieldsets();
             }
         });
diff --git a/src/app/components/jet-results/jet-results.component.html b/src/app/components/jet-results/jet-results.component.html
index ee434e04fa718f113acf60554f64e5db8156cb15..f3680821b57ef749b4521e1c6707b0dbd78bbdea 100644
--- a/src/app/components/jet-results/jet-results.component.html
+++ b/src/app/components/jet-results/jet-results.component.html
@@ -2,9 +2,9 @@
     <!-- journal -->
     <log></log>
 
-    <results-chart *ngIf="showVarResults" [hidden]="! showVarResultsChart"></results-chart>
+    <results-chart *ngIf="showVarResults" [hidden]="! showVarResultsChart" [results]=varResults [resultData]=varResults?.result></results-chart>
 
-    <jet-trajectory-chart [hidden]="! hasValidResults"></jet-trajectory-chart>
+    <jet-trajectory-chart [hidden]="! hasValidResults" [results]=trajectoryResults?.result></jet-trajectory-chart>
 
     <div>
         <!-- table des résultats fixés -->
diff --git a/src/app/components/jet-results/jet-results.component.ts b/src/app/components/jet-results/jet-results.component.ts
index 04e068fb078cb272d709c71ba9cf2abdaafeaca1..57258cd1ebe79fdf1e4fb871d07262fa2c8c6d5e 100644
--- a/src/app/components/jet-results/jet-results.component.ts
+++ b/src/app/components/jet-results/jet-results.component.ts
@@ -1,7 +1,8 @@
-import { Component, ViewChild } from "@angular/core";
+import { Component } from "@angular/core";
 
 import { FixedVarResultsComponent } from "../fixedvar-results/fixedvar-results.component";
-import { JetTrajectoryChartComponent } from "../jet-trajectory-chart/jet-trajectory-chart.component";
+import { FixedResults } from "../../results/fixed-results";
+import { VarResults } from "../../results/var-results";
 
 @Component({
     selector: "jet-results",
@@ -12,10 +13,6 @@ import { JetTrajectoryChartComponent } from "../jet-trajectory-chart/jet-traject
 })
 export class JetResultsComponent extends FixedVarResultsComponent {
 
-    /** graphique de trajectoire */
-    @ViewChild(JetTrajectoryChartComponent)
-    private jetTrajectoryChartComponent: JetTrajectoryChartComponent;
-
     public get hasResults(): boolean {
         return (
             (this._fixedResults?.hasResults)
@@ -32,33 +29,13 @@ export class JetResultsComponent extends FixedVarResultsComponent {
         );
     }
 
-    public updateView() {
-        if (this.jetTrajectoryChartComponent) {
-            this.jetTrajectoryChartComponent.results = undefined;
+    public get trajectoryResults(): FixedResults | VarResults {
+        // draw chart whether params are variating or not,
+        // hence different Results object for each case
+        if (this._varResults && this._varResults.hasResults) {
+            return this._varResults;
+        } else {
+            return this._fixedResults;
         }
-        super.updateView();
-    }
-
-    /**
-     * met à jour l'affichage des résultats
-     * @returns true si les résultats ont pu être mis à jour
-     */
-    protected updateResults() {
-        const superUpdated = super.updateResults();
-
-        const trajectoryChartUpdated = this.jetTrajectoryChartComponent !== undefined;
-
-        if (trajectoryChartUpdated) {
-            // draw chart whether params are variating or not,
-            // hence different Results object for each case
-            if (this._varResults && this._varResults.hasResults) {
-                this.jetTrajectoryChartComponent.results = this._varResults;
-            } else {
-                this.jetTrajectoryChartComponent.results = this._fixedResults;
-            }
-            this.jetTrajectoryChartComponent.updateView();
-        }
-
-        return superUpdated && trajectoryChartUpdated;
     }
 }
diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
index 1087a424a449b1eaa643bbbf4fbe0b961f547b0e..cedbcf29399b1b64c0fc89833f8b4cbee6e55830 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.html
@@ -17,7 +17,7 @@
         </div>
 
         <div *ngIf="! displayChart" class="fake-chart"></div><!-- trick to avoid blinking effect due to forceRebuild -->
-        <chart *ngIf="displayChart" type="scatter" [data]="graph_data" [options]="graph_options" #graphChart>
+        <chart *ngIf="displayChart" type="scatter" [data]="graph_data" [options]="graph_options">
         </chart>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
index 960cda6bde4a059274a8828a55150feea7b51ad1..2d726e9f975d19f3075bc924800f867df01a1134 100644
--- a/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
+++ b/src/app/components/jet-trajectory-chart/jet-trajectory-chart.component.ts
@@ -1,16 +1,14 @@
-import { Component, ViewChild, ChangeDetectorRef } from "@angular/core";
+import { Component, ViewChild, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
 import { ChartComponent } from "angular2-chartjs";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
 import { IYSeries } from "../../results/y-series";
-import { FixedResults } from "../../results/fixed-results";
-import { VarResults } from "../../results/var-results";
 import { fv } from "../../util";
 import { AppComponent } from "../../app.component";
 
-import { Jet } from "jalhyd";
+import { Jet, Result } from "jalhyd";
 
 @Component({
     selector: "jet-trajectory-chart",
@@ -19,12 +17,12 @@ import { Jet } from "jalhyd";
         "./jet-trajectory-chart.component.scss"
     ]
 })
-export class JetTrajectoryChartComponent extends ResultsComponentDirective {
+export class JetTrajectoryChartComponent extends ResultsComponentDirective implements OnChanges {
 
     @ViewChild(ChartComponent)
     private chartComponent;
 
-    private _results: FixedResults | VarResults;
+    private _results: Result;
 
     private _zoomWasChanged = false;
 
@@ -132,12 +130,16 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective {
         }, 10);
     }
 
-    public set results(r: FixedResults | VarResults) {
+    @Input()
+    public set results(r: Result) {
         this.forceRebuild(); // used for forcing redefinition of xAxes[0].ticks.min/max in generateScatterChart()
         this._results = r;
+    }
 
-        if (this._results && this._results.result) {
-            const nub = this._results.result.sourceNub as Jet;
+    // redessine le graphique dès qu'une entrée change
+    public ngOnChanges() {
+        if (this._results) {
+            const nub = this._results.sourceNub as Jet;
             const length = nub.variatingLength();
             // extract variable values list for legend
             if (nub.resultHasMultipleValues()) {
@@ -158,6 +160,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective {
                     }
                 }
             }
+            this.generateScatterChart();
         }
     }
 
@@ -170,16 +173,12 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective {
         return this._zoomWasChanged;
     }
 
-    public updateView() {
-        this.generateScatterChart();
-    }
-
     /**
      * génère les données d'un graphique de type "scatter"
      */
     private generateScatterChart() {
         const ySeries = this.getYSeries();
-        const nub = (this._results.result.sourceNub as Jet);
+        const nub = (this._results.sourceNub as Jet);
 
         this.graph_data = {
             datasets: []
@@ -260,7 +259,7 @@ export class JetTrajectoryChartComponent extends ResultsComponentDirective {
     private getYSeries(): IYSeries[] {
         const ret: IYSeries[] = [];
         const palette = ResultsComponentDirective.distinctColors;
-        const nub = (this._results.result.sourceNub as Jet);
+        const nub = (this._results.sourceNub as Jet);
         const trajectories = nub.generateTrajectories();
 
         for (let i = 0; i < trajectories.length; i++) {
diff --git a/src/app/components/log-drawer/log-drawer.component.html b/src/app/components/log-drawer/log-drawer.component.html
index f2139f7c2cac8da90895a812a9cf9de5c61b3e51..24c2ed3a863ba466f6951fd1be7e2cc2681f365c 100644
--- a/src/app/components/log-drawer/log-drawer.component.html
+++ b/src/app/components/log-drawer/log-drawer.component.html
@@ -3,18 +3,18 @@
         <!-- titre -->
         <div class="titre">{{ uitextTitreJournal }}</div>
         <!-- entrées du journal -->
-        <div class="log-entry" *ngFor="let entry of log">
+        <div class="log-entry" *ngFor="let entry of log; let i = index; trackBy: tbIndex">
             <log-entry [_message]="entry.message"></log-entry>
             <div *ngIf="entry.subLog.messages.length" class="drawer">
                 <div class="open-drawer">
-                    <span *ngIf="! entry.isOpen">
-                        <a (click)="entry.isOpen = true;">{{ uitextShowDetails }}</a>
+                    <span *ngIf="! entryIsOpen(i)">
+                        <a (click)="setEntryOpen(i, true);">{{ uitextShowDetails }}</a>
                     </span>
-                    <span *ngIf="entry.isOpen">
-                        <a (click)="entry.isOpen = false">{{ uitextHideDetails }}</a>
+                    <span *ngIf="entryIsOpen(i)">
+                        <a (click)="setEntryOpen(i, false);">{{ uitextHideDetails }}</a>
                     </span>
                 </div>
-                <div class="drawer-contents" [hidden]="! entry.isOpen">
+                <div class="drawer-contents" [hidden]="! entryIsOpen(i)">
                     <log-entry *ngFor="let m of entry.subLog.messages" [_message]="m"></log-entry>
                 </div>
             </div>
diff --git a/src/app/components/log-drawer/log-drawer.component.ts b/src/app/components/log-drawer/log-drawer.component.ts
index 2394e46b84dffcd3b8f7c3b1439ea967d5b3872f..bb4fcf4f39e1342f79b0dcff8e65ca4cb0734908 100644
--- a/src/app/components/log-drawer/log-drawer.component.ts
+++ b/src/app/components/log-drawer/log-drawer.component.ts
@@ -15,7 +15,9 @@ import { I18nService } from "../../services/internationalisation.service";
 export class LogDrawerComponent {
 
     /** A list of log messages accompanied by a sub-log (multiple messages) */
-    public log: Array<{ message: Message, subLog: cLog }>;
+    private _log: Array<{ message: Message, subLog: cLog }>;
+
+    private entriesStates: boolean[] = [];
 
     // title to display above the log
     @Input()
@@ -24,7 +26,16 @@ export class LogDrawerComponent {
     constructor(
         private intlService: I18nService,
     ) {
-        this.log = [];
+        this._log = [];
+    }
+
+    @Input()
+    public set log(log: Array<{ message: Message, subLog: cLog }>) {
+        this._log = log;
+    }
+
+    public get log(): Array<{ message: Message, subLog: cLog }> {
+        return this._log;
     }
 
     public get uitextTitreJournal(): string {
@@ -36,7 +47,7 @@ export class LogDrawerComponent {
     }
 
     public get hasEntries(): boolean {
-        return this.log !== undefined && this.log.length !== 0;
+        return this._log !== undefined && this._log.length !== 0;
     }
 
     public get uitextShowDetails(): string {
@@ -46,4 +57,20 @@ export class LogDrawerComponent {
     public get uitextHideDetails(): string {
         return this.intlService.localizeText("INFO_LOG_HIDE_DETAILS");
     }
+
+    public entryIsOpen(i: number): boolean {
+        if (this.entriesStates[i] !== undefined) {
+            return this.entriesStates[i];
+        }
+        return false;
+    }
+
+    public setEntryOpen(i: number, open: boolean) {
+        this.entriesStates[i] = open;
+    }
+
+    /** trackBy:index simulator @see nghyd#364 */
+    public tbIndex(index: number, item: any) {
+        return index;
+    }
 }
diff --git a/src/app/components/log/log.component.html b/src/app/components/log/log.component.html
index 4d3d0424a7c33bd9da1816c6f61e0c749bcacfef..5920817ec90af8c9dae78dbca027e29197cd7071 100644
--- a/src/app/components/log/log.component.html
+++ b/src/app/components/log/log.component.html
@@ -3,6 +3,6 @@
         <!-- titre -->
         <div class="titre">{{ uitextTitreJournal }}</div>
         <!-- entrées du journal -->
-        <log-entry *ngFor="let m of messages" [_message]="m"></log-entry>
+        <log-entry *ngFor="let m of _log?.messages" [_message]="m"></log-entry>
     </div>
 </div>
diff --git a/src/app/components/log/log.component.ts b/src/app/components/log/log.component.ts
index 350e544fe160b83a103414507c14678005bbb1f5..b3d9c2f7188e4227f5ec1559bfd488d24aa30e80 100644
--- a/src/app/components/log/log.component.ts
+++ b/src/app/components/log/log.component.ts
@@ -37,10 +37,7 @@ export class LogComponent {
         return this._log?.messages?.length > 0;
     }
 
-    public get messages(): Message[] {
-        return this._log?.messages;
-    }
-
+    @Input()
     public set log(log: cLog) {
         this._log = log;
     }
diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts
index abe858dcc5a426d6f7eb832759192c329a16ce3e..bf70492bf1b76785f94acbc9409326e0fada2b0e 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ElementRef } from "@angular/core";
+import { Component, ViewChild, ElementRef, Input, OnChanges } from "@angular/core";
 
 import { MacroRugo } from "jalhyd";
 
@@ -15,10 +15,15 @@ import { AppComponent } from "../../app.component";
         "./macrorugo-compound-results-table.component.scss"
     ]
 })
-export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDirective {
+export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDirective implements OnChanges {
 
     /** résultats non mis en forme */
-    private _mrcResults: MacrorugoCompoundResults;
+    @Input()
+    public results: MacrorugoCompoundResults;
+
+    /** index de l'élément de résultat à afficher (modifié par le sélecteur de conditions limites) */
+    @Input()
+    public variableIndex = 0;
 
     /** entêtes des colonnes */
     private _headers: string[];
@@ -36,21 +41,19 @@ export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDire
         super();
     }
 
-    public set results(r: MacrorugoCompoundResults) {
-        this._mrcResults = r;
-
+    public ngOnChanges() {
+        // rebuild dataset every time results or variableIndex change
         this._dataSet = [];
         if (
-            this._mrcResults
-            && this._mrcResults.childrenResults
-            && this._mrcResults.childrenResults.length > 0
-            && ! this._mrcResults.hasOnlyErrors()
+            this.results
+            && this.results.childrenResults
+            && this.results.childrenResults.length > 0
+            && ! this.results.hasOnlyErrors()
         ) {
-            const pr = this._mrcResults;
+            const pr = this.results;
             const nDigits = this.appSetupService.displayPrecision;
             // when a parameter is variating, index of the variating parameter
             // values to build the data from
-            const vi = pr.variableIndex;
 
             // refresh headers here if language changed
             this._headers = pr.headers;
@@ -58,13 +61,13 @@ export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDire
             // lines 1 - n-1 (aprons)
             for (let i = 0; i < pr.childrenResults.length; i++) {
                 // protect loop contents with if(vCalc) ? Will hide erroneous apron results..
-                const res = pr.childrenResults[i].resultElements[vi].values;
+                const res = pr.childrenResults[i].resultElements[this.variableIndex].values;
                 const nub = (pr.childrenResults[i].sourceNub as MacroRugo);
                 // does ZF1 or B vary ?
                 let zf1: number;
                 try {
                     if (nub.prms.ZF1.hasMultipleValues) {
-                        zf1 = nub.prms.ZF1.getInferredValuesList()[vi];
+                        zf1 = nub.prms.ZF1.getInferredValuesList()[this.variableIndex];
                     } else {
                         zf1 = nub.prms.ZF1.singleValue;
                     }
@@ -74,7 +77,7 @@ export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDire
                 let b: number;
                 try {
                     if (nub.prms.B.hasMultipleValues) {
-                        b = nub.prms.B.getInferredValuesList()[vi];
+                        b = nub.prms.B.getInferredValuesList()[this.variableIndex];
                     } else {
                         b = nub.prms.B.singleValue;
                     }
@@ -84,7 +87,7 @@ export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDire
                 let Y: number;
                 try {
                     if (nub.prms.Y.hasMultipleValues) {
-                        Y = nub.prms.Y.getInferredValuesList()[vi];
+                        Y = nub.prms.Y.getInferredValuesList()[this.variableIndex];
                     } else {
                         Y = nub.prms.Y.singleValue;
                     }
@@ -111,7 +114,7 @@ export class MacrorugoCompoundResultsTableComponent extends ResultsComponentDire
             this._dataSet.push([
                 this.intlService.localizeText("INFO_LIB_TOTAL"),
                 "", "", "",
-                pr.result.resultElements[vi].vCalc.toFixed(nDigits),
+                pr.result.resultElements[this.variableIndex].vCalc.toFixed(nDigits),
                 "", "", "", "", "", ""
             ]);
         }
diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html
index 85b150db8a3bbdc7f23bbd2aa6a88f0f7915fb46..593252b2cd8f4cae825bf03b5dee17eb64545eec 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.html
@@ -1,15 +1,16 @@
 <div class="container">
 
-    <log #generalLog [logTitle]="uitextGeneralLogTitle">log général</log>
+    <log [logTitle]="uitextGeneralLogTitle" [log]=globalLog>log général</log>
 
-    <variable-results-selector [results]="mrcResults" (indexChange)="variableIndexChanged()">
+    <variable-results-selector [results]=mrcResults [variatedParameters]=mrcResults?.variatedParameters>
     </variable-results-selector>
 
-    <log #iterationLog></log>
+    <log [log]=iterationLog></log>
 
     <div>
         <!-- tableau de résultats -->
-        <macrorugo-compound-results-table *ngIf="hasDisplayableResults" [results]="mrcResults">
+        <macrorugo-compound-results-table *ngIf="hasDisplayableResults"
+          [results]=mrcResults [variableIndex]=mrcResults?.variableIndex>
         </macrorugo-compound-results-table>
     </div>
 
@@ -20,11 +21,9 @@
     <quicknav *ngIf="hasDisplayableResults" [items]="[ 'input', 'results', 'charts' ]" [currentItem]="'charts'"
         [align]="'left'"></quicknav>
 
-    <div id="macrorugo-compound-graphs-container" class="container" fxLayout="row wrap"
-        fxLayoutAlign="space-around start">
-        <!-- <pab-profile-chart *ngIf="hasDisplayableResults" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
-        </pab-profile-chart> -->
-        <results-chart *ngIf="hasDisplayableResults" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
+    <div id="macrorugo-compound-graphs-container" class="container" fxLayout="row wrap" fxLayoutAlign="space-around start">
+        <results-chart *ngIf="hasDisplayableResults" [results]=mrcResults [resultData]=mrcResults?.result
+          [variableIndex]=mrcResults?.variableIndex fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
         </results-chart>
     </div>
 
diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
index d2d9328382d10d1f7327c8d70811185deb649960..232f0c436caa9e177defbe862dbdb940a4f7fd39 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
@@ -1,20 +1,14 @@
-import { Component, ViewChild, DoCheck } from "@angular/core";
+import { Component, Input } from "@angular/core";
 
 import { Result, cLog, Message, MessageCode, MessageSeverity, MRCInclination } from "jalhyd";
 
 import { fv } from "../../../app/util";
 
-import { LogComponent } from "../../components/log/log.component";
 import { CalculatorResults } from "../../results/calculator-results";
 import { NgParameter } from "../../formulaire/elements/ngparam";
 import { ApplicationSetupService } from "../../services/app-setup.service";
-import { PlottableData } from "../../results/plottable-data";
-import { ResultsChartComponent } from "../results-chart/results-chart.component";
 import { I18nService } from "../../services/internationalisation.service";
-import { VariableResultsSelectorComponent } from "../variable-results-selector/variable-results-selector.component";
-import { MacrorugoCompoundResultsTableComponent } from "./macrorugo-compound-results-table.component";
 import { MacrorugoCompoundResults } from "../../results/macrorugo-compound-results";
-import { PlottableMacrorugoCompoundResults } from "../../results/plottable-macrorugo-compound-results";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
 
 @Component({
@@ -24,84 +18,24 @@ import { ResultsComponentDirective } from "../fixedvar-results/results.component
         "./macrorugo-compound-results.component.scss"
     ]
 })
-export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective implements DoCheck {
+export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective {
 
     /** résultats non mis en forme */
     private _mrcResults: MacrorugoCompoundResults;
 
-    /** résultats mis en forme pour le graphique de données (classique) */
-    private _plottableResults: PlottableMacrorugoCompoundResults;
-
-    /** true si les résultats doiventt être remis à jour */
-    private _doUpdate = false;
-
-    @ViewChild(MacrorugoCompoundResultsTableComponent)
-    private mrcResultsTableComponent: MacrorugoCompoundResultsTableComponent;
-
-    @ViewChild(VariableResultsSelectorComponent)
-    private variableResultsSelectorComponent: VariableResultsSelectorComponent;
-
-    @ViewChild("generalLog")
-    private generalLogComponent: LogComponent;
-
-    @ViewChild("iterationLog")
-    private iterationLogComponent: LogComponent;
-
-    @ViewChild(ResultsChartComponent)
-    private resultsChartComponent: ResultsChartComponent;
-
     constructor(
         private appSetupService: ApplicationSetupService,
         private i18nService: I18nService,
     ) {
         super();
-        this._plottableResults = new PlottableMacrorugoCompoundResults();
     }
 
+    @Input()
     public set results(rs: CalculatorResults[]) {
         this._mrcResults = undefined;
         if (rs.length > 0 && rs[0] instanceof MacrorugoCompoundResults) {
             this._mrcResults = rs[0] as MacrorugoCompoundResults;
         }
-        this.updateView();
-    }
-
-    /**
-     * update results table and chart when the variable index changed (event sent by
-     * VariableResultsSelectorComponent); variable index is already set in
-     * mrcResults at this time
-     */
-    public variableIndexChanged() {
-        this.updateView();
-    }
-
-    public updateView() {
-        if (this.iterationLogComponent) {
-            this.iterationLogComponent.log = undefined;
-        }
-        if (this.generalLogComponent) {
-            this.generalLogComponent.log = undefined;
-        }
-        if (this.mrcResultsTableComponent) {
-            this.mrcResultsTableComponent.results = undefined;
-        }
-        if (this.variableResultsSelectorComponent) {
-            this.variableResultsSelectorComponent.results = undefined;
-        }
-        if (this.resultsChartComponent) {
-            this.resultsChartComponent.results = undefined;
-        }
-        // set _doUpdate flag so that results are rebuilt on the next Angular display cycle
-        this._doUpdate = false;
-        if (this._mrcResults !== undefined) {
-            this._doUpdate = this._doUpdate || this._mrcResults.hasResults || this._mrcResults.hasLog;
-        }
-    }
-
-    public ngDoCheck() {
-        if (this._doUpdate) {
-            this._doUpdate = !this.updateResults();
-        }
     }
 
     private mergeGlobalLog(result: Result, log: cLog) {
@@ -177,7 +111,7 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
      * du sélecteur d'itération : messages globaux et / ou résumé des messages
      * spécifiques à chaque ResultElement
      */
-    private get globalLog(): cLog {
+    public get globalLog(): cLog {
         const l = new cLog();
         if (this._mrcResults && this.mrcResults.variatedParameters.length > 0) {
             this.mergeGlobalLog(this._mrcResults.result, l);
@@ -199,11 +133,11 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
     }
 
     /**
-     * Retourne les logs à afficher dans le composant de log global, au dessus
-     * du sélecteur d'itération : messages globaux et / ou résumé des messages
-     * spécifiques à chaque ResultElement
+     * Retourne les logs à afficher dans le composant de log local, en dessous
+     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
+     * en cours
      */
-    private get iterationLog(): cLog {
+    public get iterationLog(): cLog {
         const l = new cLog();
         if (this._mrcResults) {
             if (this.mrcResults.variatedParameters.length > 0) {
@@ -238,46 +172,6 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
         return l;
     }
 
-    /**
-     * met à jour l'affichage des résultats
-     * @returns true si les résultats ont pu être mis à jour
-     */
-    private updateResults() {
-        let mrcUpdated: boolean;
-        let resultsChartUpdated: boolean;
-        let selectorUpdated: boolean;
-
-        // results or not, there might be a log
-        const logUpdated = (this.iterationLogComponent !== undefined || this.generalLogComponent !== undefined); // gne ?
-        if (logUpdated) {
-            // order of logs is important !
-            this.iterationLogComponent.log = this.iterationLog;
-            this.generalLogComponent.log = this.globalLog;
-        }
-
-        if (this.hasResults) {
-            mrcUpdated = this.mrcResultsTableComponent !== undefined;
-            if (mrcUpdated) {
-                this.mrcResultsTableComponent.results = this._mrcResults;
-            }
-            selectorUpdated = this.variableResultsSelectorComponent !== undefined;
-            if (selectorUpdated) {
-                this.variableResultsSelectorComponent.results = this._mrcResults;
-            }
-            resultsChartUpdated = this.resultsChartComponent !== undefined;
-            if (resultsChartUpdated) {
-                this.resultsChartComponent.results = this.plottableResults;
-                this.resultsChartComponent.updateView();
-            }
-        } else {
-            mrcUpdated = true;
-            resultsChartUpdated = true;
-            selectorUpdated = true;
-        }
-
-        return mrcUpdated && logUpdated && resultsChartUpdated && selectorUpdated;
-    }
-
     public get mrcResults() {
         return this._mrcResults;
     }
@@ -328,10 +222,4 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
         return fv(lincl);
     }
 
-    /** builds a set of PlottableData from MacrorugoCompoundResults, to feed the chart */
-    protected get plottableResults(): PlottableData {
-        this._plottableResults.setMrcResults(this.mrcResults);
-        return this._plottableResults;
-    }
-
 }
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.html b/src/app/components/pab-profile-chart/pab-profile-chart.component.html
index 35c9c9aecdd6b751495e275b5a1e916150faeb31..f7c4d9079569cf669e92ffecf1e18d01684b654b 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.html
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.html
@@ -16,7 +16,7 @@
             </button>
         </div>
 
-        <chart type="scatter" [data]="graph_data" [options]="graph_options" #graphChart>
+        <chart type="scatter" [data]="graph_data" [options]="graph_options">
         </chart>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index ce34f4dae6c9cf8adbdce67f03466dcfc950c71e..5d9220b27bded151a062f9bdd91f1a6bfb813e72 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ChangeDetectorRef } from "@angular/core";
+import { Component, ViewChild, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
 import { ChartComponent } from "angular2-chartjs";
 
@@ -20,7 +20,7 @@ import { sprintf } from "sprintf-js";
         "./pab-profile-chart.component.scss"
     ]
 })
-export class PabProfileChartComponent extends ResultsComponentDirective {
+export class PabProfileChartComponent extends ResultsComponentDirective implements OnChanges {
 
     @ViewChild(ChartComponent)
     private chartComponent;
@@ -125,9 +125,13 @@ export class PabProfileChartComponent extends ResultsComponentDirective {
         };
     }
 
+    @Input()
     public set results(r: PabResults) {
         this._results = r;
+    }
 
+    // redessine le graphique dès qu'une entrée change
+    public ngOnChanges() {
         // pre-extract variable parameters values
         if (this._results) {
             this.varValues = [];
@@ -144,6 +148,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective {
                 }
                 this.varValues.push(vv);
             }
+            this.generateScatterChart();
         }
     }
 
@@ -156,10 +161,6 @@ export class PabProfileChartComponent extends ResultsComponentDirective {
         return this._zoomWasChanged;
     }
 
-    public updateView() {
-        this.generateScatterChart();
-    }
-
     /**
      * génère les données d'un graphique de type "scatter"
      */
diff --git a/src/app/components/pab-results/pab-results-table.component.ts b/src/app/components/pab-results/pab-results-table.component.ts
index 45418cf16c9bc1d546e5c2b2f9e17d10efac8fa0..3591658a7cbf742531918f8509acfa69245600cb 100644
--- a/src/app/components/pab-results/pab-results-table.component.ts
+++ b/src/app/components/pab-results/pab-results-table.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ElementRef } from "@angular/core";
+import { Component, ViewChild, ElementRef, Input, OnChanges } from "@angular/core";
 
 import { CloisonAval, Result, capitalize } from "jalhyd";
 
@@ -15,10 +15,15 @@ import { fv } from "../../util";
         "./pab-results-table.component.scss"
     ]
 })
-export class PabResultsTableComponent extends ResultsComponentDirective {
+export class PabResultsTableComponent extends ResultsComponentDirective implements OnChanges {
 
     /** résultats non mis en forme */
-    private _pabResults: PabResults;
+    @Input()
+    public results: PabResults;
+
+    /** index de l'élément de résultat à afficher (modifié par le sélecteur de conditions limites) */
+    @Input()
+    public variableIndex = 0;
 
     /** entêtes des colonnes */
     private _headers: string[];
@@ -35,33 +40,15 @@ export class PabResultsTableComponent extends ResultsComponentDirective {
         super();
     }
 
-    private getJetTypes(re: Result, vi: number): string {
-        // jet type for each device
-        const devices = re.sourceNub.getChildren();
-        const jetTypes: string[] = devices.map((device) => {
-            const jt = device.result.resultElements[vi].getValue("ENUM_StructureJetType");
-            let jetType = capitalize(this.intlService.localizeText("INFO_ENUM_STRUCTUREJETTYPE_" + jt));
-            if (devices.length > 1) {
-                // evil HTML injection in table cell (simpler)
-                jetType = this.intlService.localizeText("INFO_LIB_FS_OUVRAGE") + " n°"
-                    + (device.findPositionInParent() + 1) + ": " + jetType;
-            }
-            return jetType;
-        });
-        return `<div class="inner-cell-line">` + jetTypes.join(`, </div><div class="inner-cell-line">`) + `</div>`;
-    }
-
-    public set results(r: PabResults) {
-        this._pabResults = r;
-
+    public ngOnChanges() {
         this._dataSet = [];
         if (
-            this._pabResults
-            && this._pabResults.cloisonsResults
-            && this._pabResults.cloisonsResults.length > 0
-            && ! this._pabResults.hasOnlyErrors()
+            this.results
+            && this.results.cloisonsResults
+            && this.results.cloisonsResults.length > 0
+            && ! this.results.hasOnlyErrors()
         ) {
-            const pr = this._pabResults;
+            const pr = this.results;
             // when a parameter is variating, index of the variating parameter
             // values to build the data from
             const vi = pr.variableIndex;
@@ -134,6 +121,22 @@ export class PabResultsTableComponent extends ResultsComponentDirective {
         }
     }
 
+    private getJetTypes(re: Result, vi: number): string {
+        // jet type for each device
+        const devices = re.sourceNub.getChildren();
+        const jetTypes: string[] = devices.map((device) => {
+            const jt = device.result.resultElements[vi].getValue("ENUM_StructureJetType");
+            let jetType = this.intlService.localizeText("INFO_ENUM_STRUCTUREJETTYPE_" + jt);
+            if (devices.length > 1) {
+                // evil HTML injection in table cell (simpler)
+                jetType = this.intlService.localizeText("INFO_LIB_FS_OUVRAGE") + " n°"
+                    + (device.findPositionInParent() + 1) + ": " + jetType;
+            }
+            return jetType;
+        });
+        return `<div class="inner-cell-line">` + jetTypes.join(`, </div><div class="inner-cell-line">`) + `</div>`;
+    }
+
     public get headers() {
         return this._headers;
     }
diff --git a/src/app/components/pab-results/pab-results.component.html b/src/app/components/pab-results/pab-results.component.html
index 9bb311053cb44654634a6785c8f59407d48e36b8..a85d72bd6eccbb2ebbdc0e907be64613e3f58820 100644
--- a/src/app/components/pab-results/pab-results.component.html
+++ b/src/app/components/pab-results/pab-results.component.html
@@ -1,24 +1,27 @@
 <div class="container">
 
-    <log #generalLog [logTitle]="uitextGeneralLogTitle">log général</log>
+    <log [logTitle]="uitextGeneralLogTitle" [log]=globalLog>log général</log>
 
-    <variable-results-selector [results]="pabResults" (indexChange)="variableIndexChanged()">
+    <variable-results-selector [results]="pabResults" [variatedParameters]=pabResults?.variatedParameters>
     </variable-results-selector>
 
-    <log #iterationLog></log>
+    <log [log]=iterationLog></log>
 
     <div>
         <!-- tableau de résultats -->
-        <pab-results-table *ngIf="hasDisplayableResults" [results]="pabResults"></pab-results-table>
+        <pab-results-table *ngIf="hasDisplayableResults"
+          [results]=pabResults [variableIndex]=pabResults?.variableIndex>
+        </pab-results-table>
     </div>
 
     <quicknav *ngIf="hasDisplayableResults" [items]="[ 'input', 'results', 'charts' ]" [currentItem]="'charts'"
         [align]="'left'"></quicknav>
 
     <div id="pab-graphs-container" class="container" fxLayout="row wrap" fxLayoutAlign="space-around start">
-        <pab-profile-chart *ngIf="hasDisplayableResults" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
+        <pab-profile-chart *ngIf="hasDisplayableResults" [results]=pabResults fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
         </pab-profile-chart>
-        <results-chart *ngIf="hasDisplayableResults" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
+        <results-chart *ngIf="hasDisplayableResults" [results]=pabResults [resultData]=pabResults?.result
+          [variableIndex]=pabResults?.variableIndex fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
         </results-chart>
     </div>
 
diff --git a/src/app/components/pab-results/pab-results.component.ts b/src/app/components/pab-results/pab-results.component.ts
index 309a6647a8afa4889e3364466783c976fef070aa..bb190be6a1e861fcf81ffa3a2079ef2efd85ad72 100644
--- a/src/app/components/pab-results/pab-results.component.ts
+++ b/src/app/components/pab-results/pab-results.component.ts
@@ -1,17 +1,10 @@
-import { Component, ViewChild, DoCheck } from "@angular/core";
+import { Component, Input } from "@angular/core";
 
 import { Result, cLog, Message, MessageCode, MessageSeverity } from "jalhyd";
 
-import { LogComponent } from "../../components/log/log.component";
 import { CalculatorResults } from "../../results/calculator-results";
-import { PabResultsTableComponent } from "./pab-results-table.component";
 import { PabResults } from "../../results/pab-results";
-import { VariableResultsSelectorComponent } from "../variable-results-selector/variable-results-selector.component";
-import { PlottableData } from "../../results/plottable-data";
-import { PlottablePabResults } from "../../results/plottable-pab-results";
-import { ResultsChartComponent } from "../results-chart/results-chart.component";
 import { I18nService } from "../../services/internationalisation.service";
-import { PabProfileChartComponent } from "../pab-profile-chart/pab-profile-chart.component";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
 
 @Component({
@@ -21,89 +14,23 @@ import { ResultsComponentDirective } from "../fixedvar-results/results.component
         "./pab-results.component.scss"
     ]
 })
-export class PabResultsComponent extends ResultsComponentDirective implements DoCheck {
+export class PabResultsComponent extends ResultsComponentDirective {
 
     /** résultats non mis en forme */
     private _pabResults: PabResults;
 
-    /** résultats mis en forme pour le graphique de données (classique) */
-    private _plottableResults: PlottablePabResults;
-
-    /** true si les résultats doiventt être remis à jour */
-    private _doUpdate = false;
-
-    @ViewChild(PabResultsTableComponent)
-    private pabResultsTableComponent: PabResultsTableComponent;
-
-    @ViewChild(VariableResultsSelectorComponent)
-    private variableResultsSelectorComponent: VariableResultsSelectorComponent;
-
-    @ViewChild("generalLog")
-    private generalLogComponent: LogComponent;
-
-    @ViewChild("iterationLog")
-    private iterationLogComponent: LogComponent;
-
-    @ViewChild(ResultsChartComponent)
-    private resultsChartComponent: ResultsChartComponent;
-
-    @ViewChild(PabProfileChartComponent)
-    private profileChartComponent: PabProfileChartComponent;
-
     constructor(
         private i18nService: I18nService,
     ) {
         super();
-        this._plottableResults = new PlottablePabResults();
     }
 
+    @Input()
     public set results(rs: CalculatorResults[]) {
         this._pabResults = undefined;
         if (rs.length > 0 && rs[0] instanceof PabResults) {
             this._pabResults = rs[0] as PabResults;
         }
-        this.updateView();
-    }
-
-    /**
-     * update results table and chart when the variable index changed (event sent by
-     * VariableResultsSelectorComponent); variable index is already set in
-     * pabResults at this time
-     */
-    public variableIndexChanged() {
-        this.updateView();
-    }
-
-    public updateView() {
-        if (this.iterationLogComponent) {
-            this.iterationLogComponent.log = undefined;
-        }
-        if (this.generalLogComponent) {
-            this.generalLogComponent.log = undefined;
-        }
-        if (this.pabResultsTableComponent) {
-            this.pabResultsTableComponent.results = undefined;
-        }
-        if (this.variableResultsSelectorComponent) {
-            this.variableResultsSelectorComponent.results = undefined;
-        }
-        if (this.resultsChartComponent) {
-            this.resultsChartComponent.results = undefined;
-        }
-        if (this.profileChartComponent) {
-            this.profileChartComponent.results = undefined;
-        }
-        // set _doUpdate flag so that results are rebuilt on the next Angular display cycle
-        this._doUpdate = false;
-        if (this._pabResults !== undefined) {
-            this._doUpdate = this._doUpdate || this._pabResults.hasResults || this._pabResults.hasLog;
-        }
-    }
-
-    public ngDoCheck() {
-        if (this._doUpdate) {
-            this._doUpdate = !this.updateResults();
-        }
     }
 
     private mergeGlobalLog(result: Result, log: cLog) {
@@ -199,7 +126,7 @@ export class PabResultsComponent extends ResultsComponentDirective implements Do
      * du sélecteur d'itération : messages globaux et / ou résumé des messages
      * spécifiques à chaque ResultElement
      */
-    private get globalLog(): cLog {
+    public get globalLog(): cLog {
         const l = new cLog();
         if (this._pabResults && this.pabResults.variatedParameters.length > 0) {
             this.mergeGlobalLog(this._pabResults.result, l);
@@ -221,11 +148,11 @@ export class PabResultsComponent extends ResultsComponentDirective implements Do
     }
 
     /**
-     * Retourne les logs à afficher dans le composant de log global, au dessus
-     * du sélecteur d'itération : messages globaux et / ou résumé des messages
-     * spécifiques à chaque ResultElement
+     * Retourne les logs à afficher dans le composant de log local, en dessous
+     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
+     * en cours
      */
-    private get iterationLog(): cLog {
+    public get iterationLog(): cLog {
         const l = new cLog();
         if (this._pabResults) {
             if (this.pabResults.variatedParameters.length > 0) {
@@ -266,53 +193,6 @@ export class PabResultsComponent extends ResultsComponentDirective implements Do
         return l;
     }
 
-    /**
-     * met à jour l'affichage des résultats
-     * @returns true si les résultats ont pu être mis à jour
-     */
-    private updateResults() {
-        let pabUpdated: boolean;
-        let resultsChartUpdated: boolean;
-        let profileChartUpdated: boolean;
-        let selectorUpdated: boolean;
-
-        // results or not, there might be a log
-        const logUpdated = (this.iterationLogComponent !== undefined || this.generalLogComponent !== undefined); // gne ?
-        if (logUpdated) {
-            // order of logs is important !
-            this.iterationLogComponent.log = this.iterationLog;
-            this.generalLogComponent.log = this.globalLog;
-        }
-
-        if (this.hasResults) {
-            pabUpdated = this.pabResultsTableComponent !== undefined;
-            if (pabUpdated) {
-                this.pabResultsTableComponent.results = this._pabResults;
-            }
-            selectorUpdated = this.variableResultsSelectorComponent !== undefined;
-            if (selectorUpdated) {
-                this.variableResultsSelectorComponent.results = this._pabResults;
-            }
-            resultsChartUpdated = this.resultsChartComponent !== undefined;
-            if (resultsChartUpdated) {
-                this.resultsChartComponent.results = this.plottableResults;
-                this.resultsChartComponent.updateView();
-            }
-            profileChartUpdated = this.profileChartComponent !== undefined;
-            if (profileChartUpdated) {
-                this.profileChartComponent.results = this._pabResults;
-                this.profileChartComponent.updateView();
-            }
-        } else {
-            pabUpdated = true;
-            resultsChartUpdated = true;
-            profileChartUpdated = true;
-            selectorUpdated = true;
-        }
-
-        return pabUpdated && logUpdated && resultsChartUpdated && profileChartUpdated && selectorUpdated;
-    }
-
     public get pabResults() {
         return this._pabResults;
     }
@@ -340,10 +220,4 @@ export class PabResultsComponent extends ResultsComponentDirective implements Do
         return this.i18nService.localizeText("INFO_TITREJOURNAL_GLOBAL");
     }
 
-    /** builds a set of PlottableData from PabResults, to feed the chart */
-    protected get plottableResults(): PlottableData {
-        this._plottableResults.setPabResults(this.pabResults);
-        return this._plottableResults;
-    }
-
 }
diff --git a/src/app/components/pb-results/pb-cloison-results.component.ts b/src/app/components/pb-results/pb-cloison-results.component.ts
index 0d2fe30ccdcec69911373b90fce555d92c52862f..0a59b6a8b1f0581e7ff07e706f24459e6e7df5ce 100644
--- a/src/app/components/pb-results/pb-cloison-results.component.ts
+++ b/src/app/components/pb-results/pb-cloison-results.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, Input } from "@angular/core";
 
 import { FixedResultsComponent } from "../fixedvar-results/fixed-results.component";
 import { NgParameter } from "../../formulaire/elements/ngparam";
@@ -16,6 +16,7 @@ import { Result, ResultElement } from "jalhyd";
 })
 export class PbCloisonResultsComponent extends FixedResultsComponent {
 
+    @Input()
     public set results(r: PbCloisonResults) {
         this._fixedResults = r;
     }
diff --git a/src/app/components/pb-results/pb-results-table.component.ts b/src/app/components/pb-results/pb-results-table.component.ts
index 925eab960e5ad0300ed425bbfc206a6a7d59f747..c5d8dff4d32791788ce5c62a4e40b1a6acce13da 100644
--- a/src/app/components/pb-results/pb-results-table.component.ts
+++ b/src/app/components/pb-results/pb-results-table.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ElementRef } from "@angular/core";
+import { Component, ViewChild, ElementRef, Input } from "@angular/core";
 
 import { PreBarrage, PbBassin } from "jalhyd";
 
@@ -35,6 +35,7 @@ export class PbResultsTableComponent extends ResultsComponentDirective {
         super();
     }
 
+    @Input()
     public set results(r: PrebarrageResults) {
         this._pbResults = r;
 
diff --git a/src/app/components/pb-results/pb-results.component.html b/src/app/components/pb-results/pb-results.component.html
index 80a7d4501fb231e707cb36374fa54595a2bfecb9..ae300910591b90d0c0ca1b78533013200d91d379 100644
--- a/src/app/components/pb-results/pb-results.component.html
+++ b/src/app/components/pb-results/pb-results.component.html
@@ -1,16 +1,16 @@
 <div class="container">
-    <log #generalLog [logTitle]="uitextGeneralLogTitle">log général</log>
+    <log [logTitle]="uitextGeneralLogTitle" [log]=globalLog>log général</log>
 
-    <variable-results-selector [results]="pbResults" (indexChange)="variableIndexChanged()">
+    <variable-results-selector [results]=pbResults>
     </variable-results-selector>
 
-    <log #iterationLog></log>
+    <log [log]=iterationLog></log>
 
     <!-- tableau de résultats des bassins -->
-    <pb-results-table *ngIf="hasBasinResults" [results]="pbResults"></pb-results-table>
+    <pb-results-table *ngIf="hasBasinResults" [results]=pbResults></pb-results-table>
 
     <!-- table des résultats fixés -->
-    <pb-cloison-results *ngIf="hasWallResults" [results]="pbResults.cloisonResults"></pb-cloison-results>
+    <pb-cloison-results *ngIf="hasWallResults" [results]=pbResults.cloisonResults></pb-cloison-results>
 
     <!-- <quicknav *ngIf="hasDisplayableResults" [items]="[ 'input', 'results', 'charts' ]"
         [currentItem]="'charts'" [align]="'left'"></quicknav> -->
diff --git a/src/app/components/pb-results/pb-results.component.ts b/src/app/components/pb-results/pb-results.component.ts
index 0362c6b8bb1ce91982fb31c636f35333b252dbbc..b502c4e40fe2335c1688ddc7028aa7112bc105c6 100644
--- a/src/app/components/pb-results/pb-results.component.ts
+++ b/src/app/components/pb-results/pb-results.component.ts
@@ -1,15 +1,10 @@
-import { Component, ViewChild, DoCheck } from "@angular/core";
+import { Component, Input } from "@angular/core";
 
-import { LogComponent } from "../log/log.component";
 import { CalculatorResults } from "../../results/calculator-results";
-import { PbResultsTableComponent } from "./pb-results-table.component";
 import { PrebarrageResults } from "../../results/prebarrage-results";
-import { VariableResultsSelectorComponent } from "../variable-results-selector/variable-results-selector.component";
 import { I18nService } from "../../services/internationalisation.service";
-import { PbCloisonResultsComponent } from "./pb-cloison-results.component";
-import { FixedResults } from "../../results/fixed-results";
 
-import { Result } from "jalhyd";
+import { cLog } from "jalhyd";
 
 @Component({
     selector: "pb-results",
@@ -18,36 +13,16 @@ import { Result } from "jalhyd";
         "./pb-results.component.scss"
     ]
 })
-export class PbResultsComponent implements DoCheck {
+export class PbResultsComponent {
 
     /** résultats des bassins, non mis en forme */
     private _pbResults: PrebarrageResults;
 
-    /** true si les résultats doiventt être remis à jour */
-    private _doUpdate = false;
-
-    @ViewChild(PbResultsTableComponent)
-    private pbResultsTableComponent: PbResultsTableComponent;
-
-    @ViewChild(VariableResultsSelectorComponent)
-    private variableResultsSelectorComponent: VariableResultsSelectorComponent;
-
-    @ViewChild(PbCloisonResultsComponent)
-    private pbCloisonResultsComponent: PbCloisonResultsComponent;
-
-    @ViewChild("generalLog")
-    private generalLogComponent: LogComponent;
-
-    @ViewChild("iterationLog")
-    private iterationLogComponent: LogComponent;
-
-    /* @ViewChild(PabProfileChartComponent)
-    private profileChartComponent: PabProfileChartComponent; */
-
     constructor(
         private i18nService: I18nService,
     ) { }
 
+    @Input()
     public set results(rs: CalculatorResults[]) {
         this._pbResults = undefined;
         for (const r of rs) {
@@ -55,7 +30,6 @@ export class PbResultsComponent implements DoCheck {
                 this._pbResults = r as PrebarrageResults;
             }
         }
-        this.updateView();
     }
 
     public get pbResults() {
@@ -77,47 +51,6 @@ export class PbResultsComponent implements DoCheck {
         return this._pbResults && this._pbResults.hasWallResults;
     }
 
-    /**
-     * update results table and chart when the variable index changed (event sent by
-     * VariableResultsSelectorComponent); variable index is already set in
-     * pbResults at this time
-     */
-    public variableIndexChanged() {
-        this.updateView();
-    }
-
-    public updateView() {
-        if (this.iterationLogComponent) {
-            this.iterationLogComponent.log = undefined;
-        }
-        if (this.generalLogComponent) {
-            this.generalLogComponent.log = undefined;
-        }
-        if (this.pbResultsTableComponent) {
-            this.pbResultsTableComponent.results = undefined;
-        }
-        if (this.variableResultsSelectorComponent) {
-            this.variableResultsSelectorComponent.results = undefined;
-        }
-        if (this.pbCloisonResultsComponent) {
-            this.pbCloisonResultsComponent.results = undefined;
-        }
-        /* if (this.profileChartComponent) {
-            this.profileChartComponent.results = undefined;
-        } */
-        // set _doUpdate flag so that results are rebuilt on the next Angular display cycle
-        this._doUpdate = false;
-        if (this._pbResults !== undefined) {
-            this._doUpdate = this._doUpdate || this._pbResults.hasResults || this._pbResults.hasLog;
-        }
-    }
-
-    public ngDoCheck() {
-        if (this._doUpdate) {
-            this._doUpdate = !this.updateResults();
-        }
-    }
-
     /* private mergeGlobalLog(result: Result, log: cLog) {
         if (result) {
             if (result.hasGlobalLog()) {
@@ -211,9 +144,9 @@ export class PbResultsComponent implements DoCheck {
      * du sélecteur d'itération : messages globaux et / ou résumé des messages
      * spécifiques à chaque ResultElement
      */
-    /* private get globalLog(): cLog {
+    public get globalLog(): cLog {
         const l = new cLog();
-        if (this._pbResults && this.pbResults.variatedParameters.length > 0) {
+        /* if (this._pbResults && this.pbResults.variatedParameters.length > 0) {
             this.mergeGlobalLog(this._pbResults.result, l);
             // un problème avec la PAB en général / les cloisons, à une étape quelconque ?
             if (
@@ -228,107 +161,54 @@ export class PbResultsComponent implements DoCheck {
                 l.add(m);
                 // l.add(new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED));
             }
-        } // sinon pas de log global (aucun paramètre ne varie)
+        } // sinon pas de log global (aucun paramètre ne varie) */
         return l;
-    } */
+    }
 
     /**
-     * Retourne les logs à afficher dans le composant de log global, au dessus
-     * du sélecteur d'itération : messages globaux et / ou résumé des messages
-     * spécifiques à chaque ResultElement
+     * Retourne les logs à afficher dans le composant de log local, en dessous
+     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
+     * en cours
      */
-    /* private get iterationLog(): cLog {
+    public get iterationLog(): cLog {
         const l = new cLog();
-        if (this._pbResults) {
-            if (this.pbResults.variatedParameters.length > 0) {
+        /* if (this._pabResults) {
+            if (this.pabResults.variatedParameters.length > 0) {
                 // A. si un paramètre varie
-                const vi = this._pbResults.variableIndex;
+                const vi = this._pabResults.variableIndex;
                 // log de la PAB pour l'itération en cours
                 if (
-                    this._pbResults.result
-                    && this._pbResults.result.hasResultElements()
-                    && this._pbResults.result.resultElements[vi]
-                    && this._pbResults.result.resultElements[vi].hasLog()
+                    this._pabResults.result
+                    && this._pabResults.result.hasResultElements()
+                    && this._pabResults.result.resultElements[vi]
+                    && this._pabResults.result.resultElements[vi].hasLog()
                 ) {
-                    l.addLog(this._pbResults.result.resultElements[vi].log);
+                    l.addLog(this._pabResults.result.resultElements[vi].log);
                 }
                 // logs des enfants pour l'itération en cours
-                for (const cr of this._pbResults.cloisonsResults) {
+                for (const cr of this._pabResults.cloisonsResults) {
                     if (cr && cr.hasResultElements() && cr.resultElements[vi].hasLog()) {
                         l.addLog(cr.resultElements[vi].log);
                     }
                 }
-                if (this._pbResults.cloisonAvalResults && this._pbResults.cloisonAvalResults.resultElements[vi].hasLog()) {
-                    l.addLog(this._pbResults.cloisonAvalResults.resultElements[vi].log);
+                if (this._pabResults.cloisonAvalResults && this._pabResults.cloisonAvalResults.resultElements[vi].hasLog()) {
+                    l.addLog(this._pabResults.cloisonAvalResults.resultElements[vi].log);
                 }
             } else {
                 // B. si aucun paramètre ne varie
-                this.mergeGlobalLog(this._pbResults.result, l); // faut bien mettre le log global quelque part
+                this.mergeGlobalLog(this._pabResults.result, l); // faut bien mettre le log global quelque part
                 // logs des enfants
-                for (const cr of this._pbResults.cloisonsResults) {
+                for (const cr of this._pabResults.cloisonsResults) {
                     if (cr && cr.hasResultElements() && cr.resultElement.hasLog()) {
                         l.addLog(cr.resultElement.log);
                     }
                 }
-                if (this._pbResults.cloisonAvalResults && this._pbResults.cloisonAvalResults.resultElement.hasLog()) {
-                    l.addLog(this._pbResults.cloisonAvalResults.resultElement.log);
+                if (this._pabResults.cloisonAvalResults && this._pabResults.cloisonAvalResults.resultElement.hasLog()) {
+                    l.addLog(this._pabResults.cloisonAvalResults.resultElement.log);
                 }
             }
-        }
+        } */
         return l;
-    } */
-
-    /**
-     * met à jour l'affichage des résultats
-     * @returns true si les résultats ont pu être mis à jour
-     */
-    private updateResults() {
-        let pbTableUpdated: boolean;
-        let profileChartUpdated: boolean;
-        let selectorUpdated: boolean;
-        let cloisonResultsUpdated: boolean;
-
-        // results or not, there might be a log
-        const logUpdated = (this.iterationLogComponent !== undefined || this.generalLogComponent !== undefined); // gne ?
-        if (logUpdated) {
-            // order of logs is important !
-            /* this.iterationLogComponent.log = this.iterationLog;
-            this.generalLogComponent.log = this.globalLog; */
-        }
-
-        // show selector as long as any result is present
-        if (this.hasResults) {
-            selectorUpdated = this.variableResultsSelectorComponent !== undefined;
-            if (selectorUpdated) {
-                this.variableResultsSelectorComponent.results = this._pbResults;
-            }
-        } else {
-            selectorUpdated = true;
-        }
-        if (this.hasBasinResults) {
-            pbTableUpdated = this.pbResultsTableComponent !== undefined;
-            if (pbTableUpdated) {
-                this.pbResultsTableComponent.results = this._pbResults;
-            }
-            /* profileChartUpdated = this.profileChartComponent !== undefined;
-            if (profileChartUpdated) {
-                this.profileChartComponent.results = this._pbResults;
-                this.profileChartComponent.updateView();
-            } */
-        } else {
-            pbTableUpdated = true;
-            profileChartUpdated = true;
-        }
-        if (this.hasWallResults) {
-            cloisonResultsUpdated = this.pbCloisonResultsComponent !== undefined;
-            if (cloisonResultsUpdated) {
-                this.pbCloisonResultsComponent.results = this._pbResults.cloisonResults;
-            }
-        } else {
-            cloisonResultsUpdated = true;
-        }
-
-        return pbTableUpdated && logUpdated && profileChartUpdated && selectorUpdated && cloisonResultsUpdated;
     }
 
     public get uitextGeneralLogTitle(): string {
diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html
index ed96cbf12dfdbf619938d462cba2959f7f1b2a83..7f9efd5fd03a4a8827d85473bc660943f101a7c4 100644
--- a/src/app/components/remous-results/remous-results.component.html
+++ b/src/app/components/remous-results/remous-results.component.html
@@ -42,10 +42,9 @@
 
 
 <!-- journal -->
-<log></log>
+<log [log]=log></log>
 
-<div [hidden]="! hasData">
-    <!-- *ngIf breaks @ViewChild availability-->
+<div *ngIf="hasData">
     <!-- résultats numériques -->
-    <var-results></var-results>
-</div>
\ No newline at end of file
+    <var-results [results]=varResults></var-results>
+</div>
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index ecf98435acc8ee520cfc22476a2dada00e93198b..b39505299078fd465949b1f8c178625e459fc299 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -1,17 +1,16 @@
-import { Component, ViewChild, DoCheck } from "@angular/core";
+import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";
 
-import { INumberIterator, CourbeRemousParams, CourbeRemous, ParamDefinition, ParamDomain, ParamDomainValue } from "jalhyd";
+import { INumberIterator, CourbeRemousParams, CourbeRemous, ParamDefinition, ParamDomainValue, cLog } from "jalhyd";
 
 import { I18nService } from "../../services/internationalisation.service";
-import { LogComponent } from "../../components/log/log.component";
 import { RemousResults } from "../../results/remous-results";
 import { CalculatorResults } from "../../results/calculator-results";
-import { VarResultsComponent } from "../fixedvar-results/var-results.component";
 import { FormulaireService } from "../../services/formulaire.service";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
 import { AppComponent } from "../../app.component";
 import { LineData, ChartData } from "./line-and-chart-data";
 import { fv } from "../../util";
+import { VarResults } from "../../results/var-results";
 
 @Component({
     selector: "remous-results",
@@ -20,7 +19,7 @@ import { fv } from "../../util";
         "./remous-results.component.scss"
     ]
 })
-export class RemousResultsComponent extends ResultsComponentDirective implements DoCheck {
+export class RemousResultsComponent extends ResultsComponentDirective implements OnChanges {
 
     private _remousResults: RemousResults;
 
@@ -43,23 +42,6 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
      */
     private _tableHeaders: string[];
 
-    /**
-     * true si les résultats doivent être mis à jour
-     */
-    private _doUpdate = false;
-
-    /**
-     * composant des résultats variables
-     */
-    @ViewChild(VarResultsComponent)
-    private varResultsComponent: VarResultsComponent;
-
-    /**
-     * composant journal
-     */
-    @ViewChild(LogComponent)
-    private logComponent: LogComponent;
-
     constructor(
         private intlService: I18nService,
         private formService: FormulaireService
@@ -67,7 +49,11 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         super();
     }
 
-    private get uitextLigneFluviale() {
+    public get remousResults() {
+        return this._remousResults;
+    }
+
+    public get uitextLigneFluviale() {
         // calculator type for translation
         const sn = this._remousResults.result.sourceNub;
         let ct = sn.calcType;
@@ -77,7 +63,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         return this.formService.expandVariableNameAndUnit(ct, "FLU");
     }
 
-    private get uitextLigneTorrentielle() {
+    public get uitextLigneTorrentielle() {
         // calculator type for translation
         const sn = this._remousResults.result.sourceNub;
         let ct = sn.calcType;
@@ -87,23 +73,23 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         return this.formService.expandVariableNameAndUnit(ct, "TOR");
     }
 
-    private get uitextAbscisse() {
+    public get uitextAbscisse() {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_ABSCISSE");
     }
 
-    private get uitextFond() {
+    public get uitextFond() {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_FOND");
     }
 
-    private get uitextBerge() {
+    public get uitextBerge() {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_BERGE");
     }
 
-    private get uitextTirantNormal() {
+    public get uitextTirantNormal() {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_TIRANTNORMAL");
     }
 
-    private get uitextTirantCritique() {
+    public get uitextTirantCritique() {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_TIRANTCRITIQUE");
     }
 
@@ -149,6 +135,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
         return this._remousResults && this._remousResults.result && this._remousResults.result.ok;
     }
 
+    @Input()
     public set results(rs: CalculatorResults[]) {
         this._remousResults = undefined;
         if (rs !== undefined) {
@@ -159,43 +146,25 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
                 }
             }
         }
-        this.updateView();
     }
 
-    public updateView() {
-        this.graph1_data = {};
-        this.graph1_options = {};
-        this.graph2_data = {};
-        this.graph2_options = {};
-        if (this.varResultsComponent !== undefined) {
-            this.varResultsComponent.results = undefined;
-        }
-        if (this.logComponent !== undefined) {
-            this.logComponent.log = undefined;
-        }
-        this._tableHeaders = [];
-
-        if (this._remousResults !== undefined) {
-            this._doUpdate = this._remousResults.hasResults;
+    public ngOnChanges(s: SimpleChanges) {
+        // console.log("_________> RRC onChanges", s);
+        if (this._remousResults && this._remousResults.result) {
+            this.generateChart();
         }
     }
 
-    /**
-     * appelé pour gérer les changements non détectés par Angular
-     */
-    public ngDoCheck() {
-        if (this._doUpdate) {
-            this._doUpdate = !this.updateResults();
+    public get log(): cLog {
+        if (this._remousResults !== undefined) {
+            return this._remousResults.log;
         }
     }
 
-    private updateResults() {
-        if (this.logComponent !== undefined && this._remousResults !== undefined) {
-            this.logComponent.log = this._remousResults.log;
-            this.generateChart();
-            return true;
+    public get varResults(): VarResults {
+        if (this._remousResults !== undefined) {
+            return this._remousResults.varResults;
         }
-        return false;
     }
 
     /**
@@ -268,11 +237,7 @@ export class RemousResultsComponent extends ResultsComponentDirective implements
     private generateChart() {
         // http://www.chartjs.org/docs/latest/charts/line.html
         // le dernier dataset de la liste datasets est dessiné en 1er
-
         this._remousResults.update();
-        if (this.varResultsComponent) {
-            this.varResultsComponent.results = this._remousResults.varResults;
-        }
 
         const nub = this._remousResults.result.sourceNub as CourbeRemous;
         const params = nub.prms as CourbeRemousParams;
diff --git a/src/app/components/results-chart/results-chart.component.html b/src/app/components/results-chart/results-chart.component.html
index 1cf1336d5b43c0c98f79f967a421166a720e799e..be55ade023ec1c2b38630011af12ef652a515152 100644
--- a/src/app/components/results-chart/results-chart.component.html
+++ b/src/app/components/results-chart/results-chart.component.html
@@ -17,7 +17,7 @@
         </div>
 
         <div *ngIf="! displayChart" class="fake-chart"></div><!-- trick to avoid blinking effect due to forceRebuild -->
-        <chart *ngIf="displayChart" [type]="graph_type" [data]="graph_data" [options]="graph_options" #graphChart>
+        <chart *ngIf="displayChart" [type]="graph_type" [data]="graph_data" [options]="graph_options">
         </chart>
     </div>
 </div>
diff --git a/src/app/components/results-chart/results-chart.component.ts b/src/app/components/results-chart/results-chart.component.ts
index 05247e41c836467b53cd4e53a4d66aa24000f8e0..d41858fe728c13c5f9a40072b9d8ee5f8aa621e3 100644
--- a/src/app/components/results-chart/results-chart.component.ts
+++ b/src/app/components/results-chart/results-chart.component.ts
@@ -1,8 +1,8 @@
-import { Component, ViewChild, AfterContentInit, ChangeDetectorRef } from "@angular/core";
+import { Component, ViewChild, AfterContentInit, ChangeDetectorRef, Input, OnChanges } from "@angular/core";
 
 import { ChartComponent } from "angular2-chartjs";
 
-import { Observer, ParamFamily } from "jalhyd";
+import { Observer, ParamFamily, Result } from "jalhyd";
 
 import { ChartTypeSelectComponent } from "./chart-type.component";
 import { I18nService } from "../../services/internationalisation.service";
@@ -21,7 +21,7 @@ import { AppComponent } from "../../app.component";
         "./results-chart.component.scss"
     ]
 })
-export class ResultsChartComponent extends ResultsComponentDirective implements AfterContentInit, Observer {
+export class ResultsChartComponent extends ResultsComponentDirective implements AfterContentInit, Observer, OnChanges {
 
     @ViewChild(ChartComponent)
     private chartComponent;
@@ -90,23 +90,33 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         };
     }
 
+    @Input()
     public set results(r: PlottableData) {
-        this.forceRebuild();
         this._results = r;
         if (this._results && this._graphTypeComponent) {
-            this._graphTypeComponent.selectedValue = r.graphType;
+            this._graphTypeComponent.selectedValue = r.chartType;
         }
     }
 
-    public get availableXAxis() {
+    @Input()
+    public set resultData(r: Result) {
+        // trick to trigger onChanges when results data changes
+    }
+
+    @Input()
+    public set variableIndex(v: number) {
+        // trick to trigger onChanges when variable index changes
+    }
+
+    public get availableXAxis(): string[] {
         if (this._results) {
             return this._results.getAvailableXAxis();
         }
     }
 
-    public get availableYAxis() {
+    public get availableYAxis(): string[] {
         if (this._results) {
-            if (this._results.graphType !== ChartType.Scatter) {
+            if (this._results.chartType !== ChartType.Scatter) {
                 // do not use real Y axis (that include families), if chart cannot display multiple series
                 return this._results.getAvailableXAxis();
             } else {
@@ -124,9 +134,8 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
     public set chartX(X) {
         if (X !== this.chartX) {
             this._results.chartX = X;
-            this.forceRebuild();
             // refresh chart
-            this.updateView();
+            this.drawChart();
         }
     }
 
@@ -139,9 +148,8 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
     public set chartY(Y) {
         if (Y !== this.chartY) {
             this._results.chartY = Y;
-            this.forceRebuild();
             // refresh chart
-            this.updateView();
+            this.drawChart();
         }
     }
 
@@ -169,23 +177,29 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         return this._zoomWasChanged;
     }
 
-    public updateView() {
-        // (re)generate chart
-        switch (this._graphTypeComponent.selectedValue) {
-            case ChartType.Histogram:
-                this.graph_type = "bar";
-                this.generateBarChart();
-                break;
-
-            case ChartType.Dots:
-                this.graph_type = "line";
-                this.generateLineChart();
-                break;
-
-            default:
-                this.graph_type = "scatter";
-                this.generateScatterChart();
-                break;
+    public ngOnChanges() {
+        // redessiner le graphique chaque fois qu'une entrée change
+        this.drawChart();
+    }
+
+    public drawChart() {
+        if (this._results && this._results.hasPlottableResults()) {
+            switch (this._graphTypeComponent.selectedValue) {
+                case ChartType.Histogram:
+                    this.graph_type = "bar";
+                    this.generateBarChart();
+                    break;
+
+                case ChartType.Dots:
+                    this.graph_type = "line";
+                    this.generateLineChart();
+                    break;
+
+                default:
+                    this.graph_type = "scatter";
+                    this.generateScatterChart();
+                    break;
+            }
         }
     }
 
@@ -212,15 +226,6 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
         return l;
     }
 
-    /** forces Angular to rebuild the chart @see bug #137 */
-    private forceRebuild() {
-        this.displayChart = false;
-        const that = this;
-        setTimeout(() => { // trick
-            that.displayChart = true;
-        }, 10);
-    }
-
     /**
      * génère les données d'un graphique de type "bar"
      */
@@ -479,9 +484,9 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
     update(sender: any, data: any) {
         if (sender instanceof ChartTypeSelectComponent) {
             if (data.action === "graphTypeChanged") {
-                this._results.graphType = data.value;
+                this._results.chartType = data.value;
             }
         }
-        this.updateView();
+        this.drawChart();
     }
 }
diff --git a/src/app/components/section-canvas/section-canvas.component.html b/src/app/components/section-canvas/section-canvas.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..da242b966d3d4eb18ed9873ad32e8779fec1ce6b
--- /dev/null
+++ b/src/app/components/section-canvas/section-canvas.component.html
@@ -0,0 +1,2 @@
+<canvas #canvas [attr.width]="width" [attr.height]="height">
+</canvas>
diff --git a/src/app/components/section-canvas/section-canvas.component.scss b/src/app/components/section-canvas/section-canvas.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..7f26ddcb550343c65fbc953a2c7b73b6440c0eae
--- /dev/null
+++ b/src/app/components/section-canvas/section-canvas.component.scss
@@ -0,0 +1,3 @@
+:host {
+    display: block;
+}
diff --git a/src/app/components/section-canvas/section-canvas.component.ts b/src/app/components/section-canvas/section-canvas.component.ts
index 3475f8842d495cac9f058e195fb93a101d4081f2..81b4c45dde483584e6234ca028bf5cef1ae2d5cf 100644
--- a/src/app/components/section-canvas/section-canvas.component.ts
+++ b/src/app/components/section-canvas/section-canvas.component.ts
@@ -1,27 +1,30 @@
-import { Component, ViewChild } from "@angular/core";
+import { Component, ViewChild, Input, OnChanges, AfterViewInit, ElementRef } from "@angular/core";
 
 import {
     acSection, cSnTrapez, ParamsSectionTrapez, cSnRectang, ParamsSectionRectang, cSnCirc,
     ParamsSectionCirc, cSnPuiss, ParamsSectionPuiss, Result
 } from "jalhyd";
 
-import { CalcCanvasComponent } from "../canvas/canvas.component";
+import { ResultsComponentDirective } from "../fixedvar-results/results.component";
 
 @Component({
     selector: "section-canvas",
-    template: `<calc-canvas #calcCanvas
-    [width]="size"
-    [height]="size">
-    </calc-canvas>
-    `
+    templateUrl: "./section-canvas.component.html",
+    styleUrls: [
+        "./section-canvas.component.scss"
+    ]
 })
-export class SectionCanvasComponent {
-
-    /** default square size, supposed to match device size (computed at contruct time) */
-    public originalSize: number;
-
-    /** taille (pixels) du canvas (c'est un carré) */
-    public size = 400;
+export class SectionCanvasComponent extends ResultsComponentDirective implements AfterViewInit, OnChanges {
+
+    private static labelColors: { [key: string]: any; } = {
+        "Hs": { r: 255, g: 0, b: 0 },
+        "Hsc": { r: 0, g: 0, b: 255 },
+        "Yn": { r: 16, g: 128, b: 16 },
+        "Ycor": { r: 128, g: 128, b: 128 },
+        "Yc": { r: 255, g: 128, b: 0 },
+        "Ycon": { r: 255, g: 0, b: 255 },
+        "Y": { r: 50, g: 50, b: 50 }
+    };
 
     /** marges gauche/droite pour le texte (pixels) */
     private _textMargin = 90;
@@ -35,42 +38,59 @@ export class SectionCanvasComponent {
 
     private _section: acSection;
 
+    private _result: Result;
+
+    private _size: number;
+
     // tirants
     private _levels: Object[] = [];
 
-    @ViewChild("calcCanvas")
-    private _calcCanvas: CalcCanvasComponent;
+    public get width(): number {
+        // return this._calcCanvas.nativeElement.width;
+        return this._size;
+    }
 
+    public get height(): number {
+        // return this._calcCanvas.nativeElement.height;
+        return this._size;
+    }
+
+    private _context2d: CanvasRenderingContext2D;
+
+    @ViewChild("canvas", { static: true })
+    private _calcCanvas: ElementRef;
+
+    @Input()
     public set section(s: acSection) {
         this._section = s;
-        if (this._section) {
-            this.draw();
-        }
     }
 
-    public reset() {
-        this._section = undefined;
-        this._levels = [];
-        this._calcCanvas.clear();
+    @Input()
+    public set result(r: Result) {
+        this._result = r;
     }
 
-    private computeScale(maxWidth: number, maxHeight: number) {
-        this._scaleX = (this.size - 2 * this._textMargin) / maxWidth;
-        this._scaleY = (this.size - this._bottomMargin) / maxHeight;
+    @Input()
+    public set size(s: number) {
+        this._size = s;
+        console.log("(i) size set to", this._size);
     }
 
-    /**
-     * convertit une abscisse en m en pixels
-     */
-    private Xm2pix(x: number) {
-        return this._textMargin + x * this._scaleX;
+    // redessine le canvas chaque fois qu'une entrée change
+    public ngOnChanges() {
+        console.log("XXX section canvas on changes");
+        this.draw();
     }
 
-    /**
-     * convertit une ordonnée en m en pixels
-     */
-    private Ym2pix(y: number) {
-        return this.size - this._bottomMargin - y * this._scaleY;
+    public ngAfterViewInit() { // wait for the view to init before using the element
+        this._context2d = this._calcCanvas.nativeElement.getContext("2d");
+        console.log("<<<< after view init >>>");
+        this.draw();
+    }
+
+    public reset() {
+        this._levels = [];
+        this.clear();
     }
 
     public addLevel(val: number, label: string, rgb: {}) {
@@ -83,6 +103,45 @@ export class SectionCanvasComponent {
         return Math.max(this._section.prms.YB.v, this._levels[this._levels.length - 1]["val"]);
     }
 
+    private isSectionLevel(s: string) {
+        for (const k in SectionCanvasComponent.labelColors) {
+            if (k === s) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public draw() {
+        console.log(">> redrawing at size", this._size);
+        if (this._context2d && this._section) {
+            this.reset();
+
+            // traduction des symboles des variables calculées
+            const re = this._result.resultElement;
+            for (const k in re.values) {
+                if (k !== re.vCalcSymbol) {
+                    const lbl = k.toUpperCase();
+                    const er = re.getValue(k);
+                    // this._resultElement.addExtraResult(lbl, er);
+
+                    if (this.isSectionLevel(k)) {
+                        this.addLevel(er, k + " = " + this.formattedValue(er), SectionCanvasComponent.labelColors[k]);
+                    }
+                }
+            }
+
+            // ajout du tirant d'eau saisi
+            const valY = this._result.sourceNub.getParameter("Y").singleValue;
+            this.addLevel(valY, "Y = " + this.formattedValue(valY), SectionCanvasComponent.labelColors["Y"]);
+
+            this.sortLevels();
+            this.drawFrame();
+            const maxWidth = this.drawSection();
+            this.drawLevels(maxWidth);
+        }
+    }
+
     /**
      * dessin des pointillés au dessus de la berge
      * xmin,xmax : position gauche/droite
@@ -90,9 +149,9 @@ export class SectionCanvasComponent {
      * maxHeight : valeur maxi des cotes
      */
     private drawTopDashLines(xmin: number, xmax: number, yb: number, maxHeight: number) {
-        this._calcCanvas.setLineWidth(2);
-        this._calcCanvas.setLineDash([5]);
-        this._calcCanvas.setStrokeColor(128, 128, 128);
+        this.setLineWidth(2);
+        this.setLineDash([5]);
+        this.setStrokeColor(128, 128, 128);
         this.drawSectionLine(xmin, yb, xmin, maxHeight);
         this.drawSectionLine(xmax, yb, xmax, maxHeight);
     }
@@ -118,8 +177,8 @@ export class SectionCanvasComponent {
 
         // dessin de la section
 
-        this._calcCanvas.setStrokeColor(0, 0, 0);
-        this._calcCanvas.setLineWidth(5);
+        this.setStrokeColor(0, 0, 0);
+        this.setLineWidth(5);
         this.drawSectionLine(0, yb, lp, 0);
         this.drawSectionLine(lp, 0, lp + prms.LargeurFond.v, 0);
         this.drawSectionLine(lp + prms.LargeurFond.v, 0, maxWidth, yb);
@@ -149,8 +208,8 @@ export class SectionCanvasComponent {
 
         // dessin de la section
 
-        this._calcCanvas.setStrokeColor(0, 0, 0);
-        this._calcCanvas.setLineWidth(5);
+        this.setStrokeColor(0, 0, 0);
+        this.setLineWidth(5);
         this.drawSectionLine(0, yb, 0, 0);
         this.drawSectionLine(0, 0, prms.LargeurBerge.v, 0);
         this.drawSectionLine(prms.LargeurBerge.v, 0, maxWidth, yb);
@@ -191,8 +250,8 @@ export class SectionCanvasComponent {
 
             // dessin de la section
 
-            this._calcCanvas.setStrokeColor(0, 0, 0);
-            this._calcCanvas.setLineWidth(5);
+            this.setStrokeColor(0, 0, 0);
+            this.setLineWidth(5);
 
             const wx: number = maxWidth / 2;
             const alpha: Result = sect.CalcSection("Alpha", yb);
@@ -237,19 +296,19 @@ export class SectionCanvasComponent {
 
         // contour de la section
 
-        this._calcCanvas.setStrokeColor(0, 0, 0);
-        this._calcCanvas.setLineWidth(5);
+        this.setStrokeColor(0, 0, 0);
+        this.setLineWidth(5);
         const k: number = prms.k.v;
         const lambda: number = B / Math.pow(yb, k);
         const inv_k: number = 1 / k;
 
         const n = 20;
-        this.beginPath();
+        this._context2d.beginPath();
         for (let x: number = -B / 2; x <= B / 2; x += B / n) {
             const y: number = Math.pow(Math.abs(x) * 2 / lambda, inv_k);
-            this.lineTo(x + B / 2, y);
+            this._context2d.lineTo(this.Xm2pix(x + B / 2), this.Ym2pix(y));
         }
-        this.closePath();
+        this._context2d.stroke();
 
         // pointillés du haut
         this.drawTopDashLines(0, maxWidth, yb, maxHeight);
@@ -257,28 +316,16 @@ export class SectionCanvasComponent {
         return maxWidth;
     }
 
-    private beginPath() {
-        this._calcCanvas.context2d.beginPath();
-    }
-
-    private lineTo(x: number, y: number) {
-        this._calcCanvas.context2d.lineTo(this.Xm2pix(x), this.Ym2pix(y));
-    }
-
-    private closePath() {
-        this._calcCanvas.context2d.stroke();
-    }
-
     private drawSectionEllipse(x: number, y: number, rX: number, rY: number, rot: number, start: number, end: number) {
-        this._calcCanvas.drawEllipse(this.Xm2pix(x), this.Ym2pix(y), rX * this._scaleX, rY * this._scaleY, rot, start, end);
+        this.drawEllipse(this.Xm2pix(x), this.Ym2pix(y), rX * this._scaleX, rY * this._scaleY, rot, start, end);
     }
 
     private drawText(s: string, x: number, y: number, align?: string) {
-        this._calcCanvas.fillText(s, this.Xm2pix(x), this.Ym2pix(y), align);
+        this.fillText(s, this.Xm2pix(x), this.Ym2pix(y), align);
     }
 
     private drawSectionLine(x1: number, y1: number, x2: number, y2: number) {
-        this._calcCanvas.drawLine(this.Xm2pix(x1), this.Ym2pix(y1), this.Xm2pix(x2), this.Ym2pix(y2));
+        this.drawLine(this.Xm2pix(x1), this.Ym2pix(y1), this.Xm2pix(x2), this.Ym2pix(y2));
     }
 
     /**
@@ -301,6 +348,25 @@ export class SectionCanvasComponent {
         throw new Error("SectionCanvasComponent.drawSection() : type de section non pris en charge");
     }
 
+    private computeScale(maxWidth: number, maxHeight: number) {
+        this._scaleX = (this._size - 2 * this._textMargin) / maxWidth;
+        this._scaleY = (this._size - this._bottomMargin) / maxHeight;
+    }
+
+    /**
+     * convertit une abscisse en m en pixels
+     */
+    private Xm2pix(x: number) {
+        return this._textMargin + x * this._scaleX;
+    }
+
+    /**
+     * convertit une ordonnée en m en pixels
+     */
+    private Ym2pix(y: number) {
+        return this._size - this._bottomMargin - y * this._scaleY;
+    }
+
     private sortLevels() {
         this._levels.sort((a, b) => {
             if (a["val"] < b["val"]) {
@@ -316,16 +382,16 @@ export class SectionCanvasComponent {
     private drawLevels(maxWidth: number) {
         let left = true;
 
-        this._calcCanvas.resetLineDash();
-        this._calcCanvas.setLineWidth(1);
-        this._calcCanvas.setFont("12px sans- serif");
+        this.resetLineDash();
+        this.setLineWidth(1);
+        this.setFont("12px sans- serif");
         for (const l of this._levels) {
             const y = l["val"];
             const col = l["rgb"];
-            this._calcCanvas.setStrokeColor(col["r"], col["g"], col["b"]);
+            this.setStrokeColor(col["r"], col["g"], col["b"]);
             this.drawSectionLine(0, y, maxWidth, y);
 
-            this._calcCanvas.setFillColor(col["r"], col["g"], col["b"]);
+            this.setFillColor(col["r"], col["g"], col["b"]);
             if (left) {
                 this.drawText(l["label"], -0.1, y, "right");
             } else {
@@ -337,17 +403,75 @@ export class SectionCanvasComponent {
 
     // contour du canvas
     private drawFrame() {
-        this._calcCanvas.clear();
-        this._calcCanvas.resetLineDash();
-        this._calcCanvas.setStrokeColor(128, 128, 128);
-        this._calcCanvas.drawRect(0, 0, this._calcCanvas.width, this._calcCanvas.height);
+        this.clear();
+        this.resetLineDash();
+        this.setStrokeColor(128, 128, 128);
+        this.drawRect(0, 0, this.width, this.height);
     }
 
-    public draw() {
-        // console.log(">> redrawing at size", this.size);
-        this.sortLevels();
-        this.drawFrame();
-        const maxWidth = this.drawSection();
-        this.drawLevels(maxWidth);
+    public clear() {
+        if (this._context2d) {
+            this._context2d.clearRect(0, 0, this.width, this.height);
+        }
+    }
+
+    public setStrokeColor(r: number, g: number, b: number) {
+        const col: string = "rgb(" + r + "," + g + "," + b + ")";
+        this._context2d.strokeStyle = col;
+    }
+
+    public setFillColor(r: number, g: number, b: number) {
+        const col: string = "rgb(" + r + "," + g + "," + b + ")";
+        this._context2d.fillStyle = col;
+    }
+
+    public setFont(f: string) {
+        this._context2d.font = f;
+    }
+
+    public fillText(s: string, x: number, y: number, align?: any) {
+        if (align) {
+            this._context2d.textAlign = align;
+        }
+        this._context2d.fillText(s, x, y);
+    }
+
+    public setLineWidth(w: number) {
+        this._context2d.lineWidth = w;
+    }
+
+    public setLineDash(d: number[]) {
+        this._context2d.setLineDash(d);
+    }
+
+    public resetLineDash() {
+        this._context2d.setLineDash([]);
+    }
+
+    public drawRect(x1: number, y1: number, w: number, h: number) {
+        this._context2d.strokeRect(x1, y1, w, h);
+    }
+
+    public drawLine(x1: number, y1: number, x2: number, y2: number) {
+        this._context2d.beginPath();
+        this._context2d.moveTo(x1, y1);
+        this._context2d.lineTo(x2, y2);
+        this._context2d.stroke();
+    }
+
+    /**
+     *
+     * @param x The x axis of the coordinate for the ellipse's center.
+     * @param y The y axis of the coordinate for the ellipse's center.
+     * @param radiusX The ellipse's major-axis radius.
+     * @param radiusY The ellipse's minor-axis radius.
+     * @param rotation The rotation for this ellipse, expressed in radians
+     * @param startAngle The starting point, measured from the x axis, from which it will be drawn, expressed in radians
+     * @param endAngle The end ellipse's angle to which it will be drawn, expressed in radians
+     */
+    public drawEllipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number) {
+        this._context2d.beginPath();
+        this._context2d.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
+        this._context2d.stroke();
     }
 }
diff --git a/src/app/components/section-results/section-results.component.html b/src/app/components/section-results/section-results.component.html
index ff26a315cad7f386d37b69661a6be7d76becdf7c..ac4e78fa01c00b3a81ff4c428e830416831d0142 100644
--- a/src/app/components/section-results/section-results.component.html
+++ b/src/app/components/section-results/section-results.component.html
@@ -1,6 +1,5 @@
 <div class="section-results-container" #sectionResults *ngIf="hasResults" fxLayout="row wrap"
     fxLayoutAlign="center center">
-
     <div fxFlex="1 1 100%">
         <div class="section-results-buttons">
             <button mat-icon-button (click)="exportAsImage(sectionResults)" [title]="uitextExportImageTitle">
@@ -17,25 +16,7 @@
 
         <!-- graphique -->
         <div class="canvas-container">
-            <section-canvas></section-canvas>
+            <section-canvas [result]=result [section]=section [size]=size></section-canvas>
         </div>
     </div>
 </div>
-
-<div class="container">
-    <!-- journal -->
-    <log></log>
-
-    <results-chart *ngIf="showVarResults"></results-chart>
-    <!--<results-chart [hidden]="! showVarResultsChart"></results-chart>-->
-
-    <div>
-        <!-- table des résultats fixés -->
-        <fixed-results [results]=fixedResults></fixed-results>
-
-        <!-- table des résultats variés -->
-        <div *ngIf="showVarResults">
-            <var-results [results]=varResults></var-results>
-        </div>
-    </div>
-</div>
\ No newline at end of file
diff --git a/src/app/components/section-results/section-results.component.ts b/src/app/components/section-results/section-results.component.ts
index 99df6bb4a1346c5376f452cd64c29d79738aa7d3..0893a387f0132b851ff7d7390a1ed8732a51ba63 100644
--- a/src/app/components/section-results/section-results.component.ts
+++ b/src/app/components/section-results/section-results.component.ts
@@ -1,13 +1,10 @@
-import { Component, ViewChild, DoCheck, ElementRef } from "@angular/core";
+import { Component, ElementRef, Input } from "@angular/core";
 
-import { ResultElement } from "jalhyd";
-
-import { SectionCanvasComponent } from "../section-canvas/section-canvas.component";
 import { SectionResults } from "../../results/section-results";
 import { CalculatorResults } from "../../results/calculator-results";
 import { I18nService } from "../../services/internationalisation.service";
 import { AppComponent } from "../../app.component";
-import { FixedVarResultsComponent } from "../fixedvar-results/fixedvar-results.component";
+import { ResultsComponentDirective } from "../fixedvar-results/results.component";
 
 @Component({
     selector: "section-results",
@@ -16,18 +13,32 @@ import { FixedVarResultsComponent } from "../fixedvar-results/fixedvar-results.c
         "./section-results.component.scss"
     ]
 })
-export class SectionResultsComponent extends FixedVarResultsComponent implements DoCheck {
+export class SectionResultsComponent extends ResultsComponentDirective {
+
+    /** taille (pixels) du canvas (c'est un carré) */
+    public _size: number;
+
+    /** hardcoded bullet-proof default canvas size **/
+    private previousContainerSize: number;
+
+    private defaultSize = 400;
+
+    private minimalSize = 300;
+
+    /**  résultats non mis en forme */
+    private _results: SectionResults;
 
     constructor(
         private intlService: I18nService,
         private element: ElementRef,
     ) {
         super();
+        this.previousContainerSize = this.defaultSize;
+        this._size = this.previousContainerSize;
     }
 
+    @Input()
     public set results(rs: CalculatorResults[]) {
-        super.results = rs;
-        this._resultElement = undefined;
         this._results = undefined;
         if (rs) {
             for (const r of rs) {
@@ -36,105 +47,22 @@ export class SectionResultsComponent extends FixedVarResultsComponent implements
                 }
             }
         }
-        this.updateView();
     }
 
-    /** détermine s'il y a des résultats de section "fixes" (pas de paramètre varié, graphique de la section) */
     public get hasResults(): boolean {
         return this._results && this._results.hasResults;
     }
 
-    public get resultElement() {
-        return this._resultElement;
-    }
-
-    private static labelColors: { [key: string]: any; } = {
-        "Hs": { r: 255, g: 0, b: 0 },
-        "Hsc": { r: 0, g: 0, b: 255 },
-        "Yn": { r: 16, g: 128, b: 16 },
-        "Ycor": { r: 128, g: 128, b: 128 },
-        "Yc": { r: 255, g: 128, b: 0 },
-        "Ycon": { r: 255, g: 0, b: 255 },
-        "Y": { r: 50, g: 50, b: 50 }
-    };
-
-    /** hardcoded bullet-proof default canvas size **/
-    private previousContainerSize = 400;
-
-    /**  résultats non mis en forme */
-    private _results: SectionResults;
-
-    /**
-     * ResultElement mis en forme (symboles des variables traduits)
-     */
-    private _resultElement: ResultElement;
-
-    @ViewChild(SectionCanvasComponent)
-    private _sectionCanvasComponent: SectionCanvasComponent;
-
-    public updateView() {
-        if (this._sectionCanvasComponent) {
-            this._sectionCanvasComponent.reset();
-        }
-        if (this._results) {
-            this._doUpdate = this._results.hasResults;
-        }
-        super.updateView();
+    public get section() {
+        return this._results.section;
     }
 
-    private isSectionLevel(s: string) {
-        for (const k in SectionResultsComponent.labelColors) {
-            if (k === s) {
-                return true;
-            }
-        }
-        return false;
+    public get result() {
+        return this._results.result;
     }
 
-    protected updateResults() {
-        const superUpdated = super.updateResults();
-
-        if (this._results && this._sectionCanvasComponent !== undefined) {
-            this._resultElement = new ResultElement();
-
-            // compute canvas optimal size the first time
-            if (this._sectionCanvasComponent.originalSize === undefined) {
-                const container = this.element.nativeElement.querySelector(".section-results-container");
-                const size = Math.min(container.offsetWidth, container.offsetHeight);
-                this._sectionCanvasComponent.originalSize = size - 17; // 417 - 17 = 400
-                this._sectionCanvasComponent.size = this._sectionCanvasComponent.originalSize;
-            }
-
-            // traduction des symboles des variables calculées
-            const re = this._results.result.resultElement;
-            for (const k in re.values) {
-                if (k !== re.vCalcSymbol) {
-                    const lbl = k.toUpperCase();
-                    const er = re.getValue(k);
-                    this._resultElement.addExtraResult(lbl, er);
-
-                    if (this.isSectionLevel(k)) {
-                        this._sectionCanvasComponent.addLevel(
-                            er, k + " = " + this.formattedValue(er), SectionResultsComponent.labelColors[k]
-                        );
-                    }
-                }
-            }
-
-            // ajout du tirant d'eau saisi
-            const valY = this._results.result.sourceNub.getParameter("Y").singleValue;
-            this._sectionCanvasComponent.addLevel(valY, "Y = " + this.formattedValue(valY), SectionResultsComponent.labelColors["Y"]);
-
-            // wait just a little to draw, in case this._sectionCanvas.size was changed above (1st run)
-            setTimeout(() => {
-                if (this._results && this._results.section) {
-                    this._sectionCanvasComponent.section = this._results.section;
-                }
-            }, 100);
-        }
-
-        const canvasUpdated = (! this.hasResults || this._sectionCanvasComponent !== undefined);
-        return superUpdated && canvasUpdated;
+    public get size() {
+        return this._size;
     }
 
     public exportAsImage(element: HTMLDivElement) {
@@ -143,26 +71,34 @@ export class SectionResultsComponent extends FixedVarResultsComponent implements
 
     /** redraw canvas on fullscreen state change (scale drawing) */
     public fullscreenChange(isFullscreen: boolean) {
-        this._sectionCanvasComponent.size = this.getContainerSize(! isFullscreen);
-        this.previousContainerSize = this._sectionCanvasComponent.size;
-        setTimeout(() => {
-            this._sectionCanvasComponent.draw();
-        }, 100);
+        this._size = this.getContainerSize(! isFullscreen, isFullscreen);
+        this.previousContainerSize = this._size;
     }
 
-    private getContainerSize(useOriginalSize: boolean = false): number {
+    private getContainerSize(useDefaultSize: boolean = false, useMinOfWidthAndHeight: boolean = false): number {
         const container = this.element.nativeElement.querySelector(".section-results-container");
+        console.log("[container size in getContainerSize]", container.offsetWidth, container.offsetHeight);
         let size: number;
         if (container) {
-            size = Math.min(container.offsetWidth, container.offsetHeight);
+            if (useMinOfWidthAndHeight) {
+                // when going to fullscreen mode, ensure the drawing
+                // is not larger or higher than the screen
+                size = Math.min(container.offsetWidth, container.offsetHeight);
+            } else {
+                size = container.offsetWidth;
+            }
         } else {
             size = this.previousContainerSize;
         }
         // when going back from fullscreen mode, container size tends to be
-        // too high for whatever reason; use originalSize on this purpose
-        if (useOriginalSize) {
-            size = Math.min(size, this._sectionCanvasComponent.originalSize);
+        // too high for whatever reason; use defaultSize on this purpose
+        if (useDefaultSize) {
+            console.log("~~ use default ~~", size, this.defaultSize);
+            size = this.defaultSize;
         }
+        // lower boundary
+        size = Math.max(size, this.minimalSize);
+
         return size;
     }
 
diff --git a/src/app/components/variable-results-selector/variable-results-selector.component.ts b/src/app/components/variable-results-selector/variable-results-selector.component.ts
index ff36f82b1e52e5cfed2b1a27fa3df682d987f85f..68491335a515f172f709427ac6ebcd02762e6218 100644
--- a/src/app/components/variable-results-selector/variable-results-selector.component.ts
+++ b/src/app/components/variable-results-selector/variable-results-selector.component.ts
@@ -1,11 +1,11 @@
-import { Component, Output, EventEmitter } from "@angular/core";
+import { Component, Output, EventEmitter, Input, OnChanges } from "@angular/core";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { fv, longestVarParam } from "../../util";
 import { MultiDimensionResults } from "../../results/multidimension-results";
 import { PrebarrageResults } from "../../results/prebarrage-results";
 
-import { CalculatorType, PbCloison, Structure } from "jalhyd";
+import { CalculatorType, PbCloison, Structure, VariatedDetails } from "jalhyd";
 
 @Component({
     selector: "variable-results-selector",
@@ -14,12 +14,18 @@ import { CalculatorType, PbCloison, Structure } from "jalhyd";
         "./variable-results-selector.component.scss"
     ]
 })
-export class VariableResultsSelectorComponent {
+export class VariableResultsSelectorComponent implements OnChanges {
 
     /** résultats non mis en forme */
-    private _results: MultiDimensionResults;
+    @Input()
+    private results: MultiDimensionResults;
 
-    private _selectedValue: number;
+    /** détails des paramètres qui varient dans le Nub associé au formulaire */
+    @Input()
+    private variatedParameters: VariatedDetails[];
+
+    /** valeur en cours */
+    private _selectedValue = 0;
 
     /** size of the longest variable value */
     private size = 0;
@@ -27,26 +33,22 @@ export class VariableResultsSelectorComponent {
     /** inferred extended values list for each variating parameter */
     private varValues = [];
 
-    @Output()
-    protected indexChange = new EventEmitter();
+    /* @Output()
+    protected indexChange = new EventEmitter(); */
 
     constructor(
         protected intlService: I18nService,
-    ) {
-        this._selectedValue = 0;
-    }
+    ) { }
 
-    public set results(r: MultiDimensionResults) {
-        this._results = r;
-
-        if (this._results) {
-            // pre-extract variable parameters values
+    public ngOnChanges() {
+        // rebuild variable parameters values everytime somthing changes
+        if (this.variatedParameters) {
             this.varValues = [];
             // find longest list
-            const lvp = longestVarParam(this._results.variatedParameters);
+            const lvp = longestVarParam(this.variatedParameters);
             this.size = lvp.size;
             // get extended values lists for each variable parameter
-            for (const v of this._results.variatedParameters) {
+            for (const v of this.variatedParameters) {
                 const vv = [];
                 const iter = v.param.getExtendedValuesIterator(this.size);
                 while (iter.hasNext) {
@@ -56,13 +58,17 @@ export class VariableResultsSelectorComponent {
                 this.varValues.push(vv);
             }
         }
+        // get current variatedIndex even if component was rebuilt
+        if (this.results) {
+            this._selectedValue = this.results.variableIndex;
+        }
     }
 
     public get hasVariableResults(): boolean {
         return (
-            this._results
-            && this._results.hasResults
-            && this._results.variatedParameters.length > 0
+            this.results
+            && this.results.hasResults
+            && this.results.variatedParameters.length > 0
         );
     }
 
@@ -78,7 +84,7 @@ export class VariableResultsSelectorComponent {
         const kv = [];
         for (let i = 0; i < this.varValues.length; i++) {
             const vv = this.varValues[i];
-            const vp = this._results.variatedParameters[i];
+            const vp = this.results.variatedParameters[i];
             let symbol = vp.param.symbol;
             // is vp a parameter of a child Nub ?
             if (
@@ -90,7 +96,7 @@ export class VariableResultsSelectorComponent {
                 switch (vp.param.originNub.calcType) {
                     case CalculatorType.PreBarrage:
                         const struct = vp.param.parentNub as Structure;
-                        const pbRes = this._results as PrebarrageResults;
+                        const pbRes = this.results as PrebarrageResults;
                         const wall = struct.parent as PbCloison;
                         const posS = struct.findPositionInParent() + 1;
                         childPrefix = this.intlService.localizeMessage(wall.description);
@@ -117,8 +123,8 @@ export class VariableResultsSelectorComponent {
     }
 
     public set selectedValue(v: number) {
-        this._results.variableIndex = v;
-        this.indexChange.emit();
+        this.results.variableIndex = v;
+        // this.indexChange.emit();
     }
 
     public get label() {
diff --git a/src/app/components/verificateur-results/verificateur-results.component.html b/src/app/components/verificateur-results/verificateur-results.component.html
index 1d0f784795249b95dd9efe67895a5ee24087c843..b343b924ea0c74c9157d7436bc7af35246160d2c 100644
--- a/src/app/components/verificateur-results/verificateur-results.component.html
+++ b/src/app/components/verificateur-results/verificateur-results.component.html
@@ -1,8 +1,8 @@
 <div class="container">
-    <log #generalLog [logTitle]="uitextGeneralLogTitle">log général</log>
+    <log [log]="globalLog" [logTitle]="uitextGeneralLogTitle">log général</log>
 
-    <variable-results-selector [results]="verificateurResults" (indexChange)="variableIndexChanged()">
+    <variable-results-selector [results]="verificateurResults" [variatedParameters]=verificateurResults?.variatedParameters>
     </variable-results-selector>
 
-    <log-drawer #iterationLog></log-drawer>
+    <log-drawer [log]="iterationLog"></log-drawer>
 </div>
diff --git a/src/app/components/verificateur-results/verificateur-results.component.ts b/src/app/components/verificateur-results/verificateur-results.component.ts
index 1d76c0420f3a10d49246900585a910fa85c3240a..6770b31acf910cab7a26cd0aef0f9200f5c74528 100644
--- a/src/app/components/verificateur-results/verificateur-results.component.ts
+++ b/src/app/components/verificateur-results/verificateur-results.component.ts
@@ -1,14 +1,11 @@
-import { Component, ViewChild, DoCheck } from "@angular/core";
+import { Component, Input } from "@angular/core";
 
 import { cLog, Message } from "jalhyd";
 
-import { LogComponent } from "../log/log.component";
 import { CalculatorResults } from "../../results/calculator-results";
-import { VariableResultsSelectorComponent } from "../variable-results-selector/variable-results-selector.component";
 import { I18nService } from "../../services/internationalisation.service";
 import { VerificateurResults } from "../../results/verificateur-results";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
-import { LogDrawerComponent } from "../log-drawer/log-drawer.component";
 
 @Component({
     selector: "verificateur-results",
@@ -17,74 +14,30 @@ import { LogDrawerComponent } from "../log-drawer/log-drawer.component";
         "./verificateur-results.component.scss"
     ]
 })
-export class VerificateurResultsComponent extends ResultsComponentDirective implements DoCheck {
+export class VerificateurResultsComponent extends ResultsComponentDirective {
 
     /** résultats non mis en forme */
     private _verificateurResults: VerificateurResults;
 
-    /** true si les résultats doiventt être remis à jour */
-    private _doUpdate = false;
-
-    @ViewChild(VariableResultsSelectorComponent)
-    private variableResultsSelectorComponent: VariableResultsSelectorComponent;
-
-    @ViewChild("generalLog")
-    private generalLogComponent: LogComponent;
-
-    @ViewChild("iterationLog")
-    private iterationLogComponent: LogDrawerComponent;
-
     constructor(
         private i18nService: I18nService,
     ) {
         super();
     }
 
+    @Input()
     public set results(rs: CalculatorResults[]) {
         this._verificateurResults = undefined;
         if (rs.length > 0 && rs[0] instanceof VerificateurResults) {
             this._verificateurResults = rs[0] as VerificateurResults;
         }
-        this.updateView();
-    }
-
-    /**
-     * update iteration log when the variable index changed (event sent by
-     * VariableResultsSelectorComponent); variable index is already set in
-     * verificateurResults at this time
-     */
-    public variableIndexChanged() {
-        this.updateView();
-    }
-
-    public updateView() {
-        if (this.iterationLogComponent) {
-            this.iterationLogComponent.log = undefined;
-        }
-        if (this.generalLogComponent) {
-            this.generalLogComponent.log = undefined;
-        }
-        if (this.variableResultsSelectorComponent) {
-            this.variableResultsSelectorComponent.results = undefined;
-        }
-        // set _doUpdate flag so that results are rebuilt on the next Angular display cycle
-        this._doUpdate = false;
-        if (this._verificateurResults !== undefined) {
-            this._doUpdate = this._doUpdate || this._verificateurResults.hasResults || this._verificateurResults.hasLog;
-        }
-    }
-
-    public ngDoCheck() {
-        if (this._doUpdate) {
-            this._doUpdate = !this.updateResults();
-        }
     }
 
     /*
      * Retourne les messages à afficher dans le composant de log global, au dessus
      * du sélecteur d'itération : messages globaux du Verificateur
      */
-    private get globalLog(): cLog {
+    public get globalLog(): cLog {
         const l = new cLog();
         if (this._verificateurResults && this._verificateurResults.result && this._verificateurResults.result.hasGlobalLog()) {
             l.addLog(this._verificateurResults.result.globalLog);
@@ -96,7 +49,7 @@ export class VerificateurResultsComponent extends ResultsComponentDirective impl
      * Retourne les messages à afficher dans le composant de log "du bas" : logs de l'itération
      * en cours (messages non-globaux du Vérificateur et eds Espèce), que le résultat varie ou non
      */
-    private get iterationLog(): Array<{ message: Message, subLog: cLog }> {
+    public get iterationLog(): Array<{ message: Message, subLog: cLog }> {
         const l: Array<{ message: Message, subLog: cLog }> = [];
         if (this._verificateurResults) {
             // = 0 lorsque rien ne varie
@@ -136,33 +89,6 @@ export class VerificateurResultsComponent extends ResultsComponentDirective impl
         return l;
     }
 
-    /**
-     * met à jour l'affichage des résultats
-     * @returns true si les résultats ont pu être mis à jour
-     */
-    private updateResults() {
-        let selectorUpdated: boolean;
-
-        // results or not, there might be a log
-        const logUpdated = (this.iterationLogComponent !== undefined || this.generalLogComponent !== undefined); // gne ?
-        if (logUpdated) {
-            // order of logs is important !
-            this.iterationLogComponent.log = this.iterationLog;
-            this.generalLogComponent.log = this.globalLog;
-        }
-
-        if (this.hasResults) {
-            selectorUpdated = this.variableResultsSelectorComponent !== undefined;
-            if (selectorUpdated) {
-                this.variableResultsSelectorComponent.results = this._verificateurResults;
-            }
-        } else {
-            selectorUpdated = true;
-        }
-
-        return logUpdated && selectorUpdated;
-    }
-
     public get verificateurResults() {
         return this._verificateurResults;
     }
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index eb1dc8ad519424fda4068d05b1c7d66908e9eea0..9ebc4348b874fd2cee9ba78a8747893747c17c64 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -317,12 +317,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
         }
     }
 
-    protected notifyReset() {
-        this.notifyObservers({
-            "action": "resetForm"
-        }, this);
-    }
-
     /**
      * Forwards Nub's progress updated notification.
      * Used by CalculatorComponent to update progress bar
@@ -337,8 +331,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
      */
     public reset() {
         this.resetResults([], undefined, true);
-        // prévenir les composants qu'il faut détecter les changements
-        this.notifyReset();
     }
 
     /**
@@ -499,10 +491,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     public doCompute() {
         // calculate module
         this.compute();
-        // refresh results
-        this.notifyObservers({
-            "action": "resultsUpdated",
-        }, this);
     }
 
     public resetFormResults() {}
diff --git a/src/app/formulaire/definition/form-fixedvar.ts b/src/app/formulaire/definition/form-fixedvar.ts
index acd265fa2e04ccbb1eae71e0ce86877fc3bfe099..7509e9bd57934d51b9c51418f1989c80bf3fc489 100644
--- a/src/app/formulaire/definition/form-fixedvar.ts
+++ b/src/app/formulaire/definition/form-fixedvar.ts
@@ -50,8 +50,8 @@ export class FormulaireFixedVar extends FormulaireDefinition {
         }
     }
 
-    public set graphType(t: ChartType) {
-        this._varResults.graphType = t;
+    public set chartType(t: ChartType) {
+        this._varResults.chartType = t;
     }
 
     public get hasResults(): boolean {
diff --git a/src/app/formulaire/definition/form-pb-cloison.ts b/src/app/formulaire/definition/form-pb-cloison.ts
index b1599380cc529ecbfc3cf3c327f6b9e1a7757550..311f8f9181f571974212586af1eb9108a12c2a3c 100644
--- a/src/app/formulaire/definition/form-pb-cloison.ts
+++ b/src/app/formulaire/definition/form-pb-cloison.ts
@@ -122,8 +122,6 @@ export class FormulairePbCloison extends FormulaireParallelStructure {
     public reset() {
         // also reset parent results (that will reset all its children results)
         (this.parent as FormulairePrebarrage).reset();
-        // prévenir les composants qu'il faut détecter les changements
-        this.notifyReset();
     }
 
     // ensure all PBresults are reset
diff --git a/src/app/results/macrorugo-compound-results.ts b/src/app/results/macrorugo-compound-results.ts
index 8aba75366df359fc005419da671cd87be46008d2..74e776f72846483d97857ed9f123cb6714dbb5eb 100644
--- a/src/app/results/macrorugo-compound-results.ts
+++ b/src/app/results/macrorugo-compound-results.ts
@@ -1,9 +1,11 @@
-import { Result } from "jalhyd";
+import { Result, ParamDefinition } from "jalhyd";
 
 import { ServiceFactory } from "../services/service-factory";
 import { MultiDimensionResults } from "./multidimension-results";
+import { PlottableData } from "./plottable-data";
+import { ChartType } from "./chart-type";
 
-export class MacrorugoCompoundResults extends MultiDimensionResults {
+export class MacrorugoCompoundResults extends MultiDimensionResults implements PlottableData {
 
     /** résultats des modules MacroRugo enfants */
     public childrenResults: Result[];
@@ -11,6 +13,10 @@ export class MacrorugoCompoundResults extends MultiDimensionResults {
     /** symboles des colonnes de résultat */
     protected _columns: string[];
 
+    public chartType: ChartType = ChartType.Scatter;
+    public chartX: string;
+    public chartY: string;
+
     public constructor() {
         super();
         this.reset();
@@ -28,6 +34,9 @@ export class MacrorugoCompoundResults extends MultiDimensionResults {
             "ENUM_MacroRugoFlowType",
             "xCenter"
         ];
+        // axes par défaut
+        this.chartX = this.chartX || "xCenter";
+        this.chartY = this.chartY || "Q";
     }
 
     /** headers symbols */
@@ -119,4 +128,99 @@ export class MacrorugoCompoundResults extends MultiDimensionResults {
 
         return err;
     }
+    public hasPlottableResults(): boolean {
+        return this.hasResults;
+    }
+
+    /**
+     * Returns the label to display, for an element of getAvailableChartAxis()
+     * @param symbol parameter / result symbol (ex: "Q")
+     */
+    public getChartAxisLabel(symbol: string): string {
+        return this.headers[this.columns.indexOf(symbol)];
+    }
+
+    public expandLabelFromSymbol(p: ParamDefinition): string {
+        return p.symbol;
+    }
+
+    /**
+     * Returns a list of plottable parameters / result elements, that can be defined
+     * as X or Y chart axis
+     */
+    public getAvailableChartAxis(): string[] {
+        const axis = [];
+        for (const c of this.columns) {
+            if (c.indexOf("ENUM_") === -1) { // ENUM variables are not plottable
+                axis.push(c);
+            }
+        }
+        return axis;
+    }
+
+    public getAvailableXAxis(): string[] {
+        return this.getAvailableChartAxis();
+    }
+
+    public getAvailableYAxis(): string[] {
+        return this.getAvailableChartAxis();
+    }
+
+    // just to implement interface
+    public getVariatingParametersSymbols(): string[] {
+        return [];
+    }
+
+    /**
+     * Returns the series of values for the required symbol
+     * @param symbol parameter / result symbol (ex: "Q")
+     */
+    public getValuesSeries(symbol: string): number[] {
+        const data: number[] = [];
+        const l = this.childrenResults.length;
+        // when a parameter is variating, index of the variating parameter
+        // values to build the data from
+        const vi = this.variableIndex;
+
+        if (this.iterationHasError(vi)) {
+            return [];
+        }
+
+        for (let i = 0; i < l; i++) {
+            switch (symbol) {
+                case "RADIER_N":
+                    data.push(i + 1);
+                    break;
+
+                case "ZF1":
+                case "Y":
+                case "B":
+                    let v: number;
+                    const nub = this.childrenResults[i].sourceNub;
+                    const param = nub.getParameter(symbol);
+                    try {
+                        if (param.hasMultipleValues) {
+                            v = param.getInferredValuesList()[vi];
+                        } else {
+                            v = param.singleValue;
+                        }
+                    } catch (e) {
+                        // silent fail
+                    }
+                    data.push(v);
+                    break;
+
+                case "Q":
+                case "Vdeb":
+                case "Fr":
+                case "Vmax":
+                case "PV":
+                case "xCenter":
+                    data.push(this.childrenResults[i].resultElements[vi].getValue(symbol));
+                    break;
+            }
+        }
+
+        return data;
+    }
 }
diff --git a/src/app/results/multidimension-results.ts b/src/app/results/multidimension-results.ts
index 44967427cccf1a0a1899462b5ff5244efc25f626..c7af4cc990ab030b530ce740f5147cb22fa436d2 100644
--- a/src/app/results/multidimension-results.ts
+++ b/src/app/results/multidimension-results.ts
@@ -6,7 +6,7 @@ import { VariatedDetails } from "jalhyd";
 export class MultiDimensionResults extends CalculatedParamResults {
 
     /** paramètres variés */
-    public variatedParameters: VariatedDetails[];
+    public variatedParameters: VariatedDetails[] = [];
 
     /** index de la valeur du paramètre varié à afficher dans les résultats */
     protected _variableIndex = 0;
diff --git a/src/app/results/pab-results.ts b/src/app/results/pab-results.ts
index d08b381f1137262d70d32b21f8ae4950f08ed423..d282524efac3c6e3f05d8e0936f4d15134f74f58 100644
--- a/src/app/results/pab-results.ts
+++ b/src/app/results/pab-results.ts
@@ -1,9 +1,11 @@
-import { Result } from "jalhyd";
+import { Result, ParamDefinition } from "jalhyd";
 
 import { ServiceFactory } from "../services/service-factory";
 import { MultiDimensionResults } from "./multidimension-results";
+import { PlottableData } from "./plottable-data";
+import { ChartType } from "./chart-type";
 
-export class PabResults extends MultiDimensionResults {
+export class PabResults extends MultiDimensionResults implements PlottableData {
 
     /** résultats des modules Cloisons avant chaque bassin */
     public cloisonsResults: Result[];
@@ -20,6 +22,10 @@ export class PabResults extends MultiDimensionResults {
     /** symboles des colonnes de résultat */
     protected _columns: string[];
 
+    public chartType: ChartType = ChartType.Scatter;
+    public chartX: string;
+    public chartY: string;
+
     public constructor() {
         super();
         this.reset();
@@ -36,6 +42,9 @@ export class PabResults extends MultiDimensionResults {
             "QA",
             "ENUM_StructureJetType"
         ];
+        // axes par défaut
+        this.chartX = this.chartX || "CLOISON";
+        this.chartY = this.chartY || "YMOY";
     }
 
     /** headers symbols */
@@ -130,4 +139,121 @@ export class PabResults extends MultiDimensionResults {
 
         return err;
     }
+
+    public hasPlottableResults(): boolean {
+        return this.hasResults;
+    }
+
+    /**
+     * Returns the label to display, for an element of getAvailableChartAxis()
+     * @param symbol parameter / result symbol (ex: "Q")
+     */
+    public getChartAxisLabel(symbol: string): string {
+        if (symbol === "x") { // specific case for wall abscissa
+            return ServiceFactory.i18nService.localizeText("INFO_LIB_ABSCISSE_CLOISON");
+        } else {
+            return this.headers[this.columns.indexOf(symbol)];
+        }
+    }
+
+    public expandLabelFromSymbol(p: ParamDefinition): string {
+        return p.symbol;
+    }
+
+    /**
+     * Returns a list of plottable parameters / result elements, that can be defined
+     * as X or Y chart axis
+     */
+    public getAvailableChartAxis(): string[] {
+        const axis = [];
+        axis.push("x"); // wall abscissa
+        for (const c of this.columns) {
+            if (c.indexOf("ENUM_") === -1) { // ENUM variables are not plottable
+                axis.push(c);
+            }
+        }
+        return axis;
+    }
+
+    public getAvailableXAxis(): string[] {
+        return this.getAvailableChartAxis();
+    }
+
+    public getAvailableYAxis(): string[] {
+        return this.getAvailableChartAxis();
+    }
+
+    // just to implement interface
+    public getVariatingParametersSymbols(): string[] {
+        return [];
+    }
+
+    /**
+     * Returns the series of values for the required symbol
+     * @param symbol parameter / result symbol (ex: "Q")
+     */
+    public getValuesSeries(symbol: string): number[] {
+        const data: number[] = [];
+        const l = this.cloisonsResults.length;
+        // when a parameter is variating, index of the variating parameter
+        // values to build the data from
+        const vi = this.variableIndex;
+
+        if (this.iterationHasError(vi)) {
+            return [];
+        }
+
+        switch (symbol) {
+            case "CLOISON":
+                data.push(undefined);
+                for (let i = 0; i <= l; i++) { // <= for one extra step (downwall)
+                    data.push(i + 1);
+                }
+                break;
+
+            case "DH":
+            case "ZRAM":
+            case "Q":
+                data.push(undefined);
+                for (let i = 0; i < l; i++) {
+                    const er = this.cloisonsResults[i].resultElements[vi].getValue(symbol);
+                    data.push(er);
+                }
+                const zrAval = this.cloisonAvalResults.resultElements[vi].getValue(symbol);
+                data.push(zrAval);
+                break;
+
+            case "Z":
+                for (let i = 0; i < l; i++) {
+                    data.push(this.cloisonsResults[i].resultElements[vi].vCalc);
+                }
+                data.push(this.cloisonAvalResults.resultElements[vi].vCalc);
+                data.push(this.Z2[vi]);
+                break;
+
+            case "PV":
+            case "YMOY":
+            case "ZRMB":
+            case "QA":
+                data.push(undefined);
+                for (let i = 0; i < l; i++) {
+                    const er = this.cloisonsResults[i].resultElements[vi].getValue(symbol);
+                    data.push(er);
+                }
+                data.push(undefined);
+                break;
+
+            case "x": // wall abscissa
+                data.push(undefined);
+                for (let i = 0; i < l; i++) {
+                    const er = this.cloisonsResults[i].resultElements[vi].getValue(symbol);
+                    data.push(er);
+                }
+                const erXdw = this.cloisonAvalResults.resultElements[vi].getValue(symbol);
+                data.push(erXdw);
+                break;
+        }
+
+        return data;
+    }
 }
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index 6a24188484a22305e7e9ba15c2be440f351d13a0..eaca087d32dee78357630328c0c72508f7b00e44 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -40,15 +40,6 @@ export abstract class CalculatedParamResults extends CalculatorResults {
             return false;
         }
         return true;
-        // return ! this.result.hasOnlyErrors;
-    }
-
-    /** return true if there is something to display on the variable results chart */
-    public get hasPlottableResults(): boolean {
-        if (this.result === undefined) {
-            return false;
-        }
-        return ! this.result.hasOnlyErrors;
     }
 
     public get hasLog(): boolean {
diff --git a/src/app/results/plottable-data.ts b/src/app/results/plottable-data.ts
index bae4f7709eef67cf54befaa9cb34af4011c9a949..a2bd574d285f9062b359deedd1f1010cd38994f9 100644
--- a/src/app/results/plottable-data.ts
+++ b/src/app/results/plottable-data.ts
@@ -7,7 +7,7 @@ import { ParamDefinition } from "jalhyd";
  */
 export interface PlottableData {
 
-    graphType: ChartType;
+    chartType: ChartType;
     chartX: string;
     chartY: string;
 
@@ -47,4 +47,9 @@ export interface PlottableData {
      * (used by tooltip functions)
      */
     getVariatingParametersSymbols(): string[];
+
+    /**
+     * Returns true if results contain data
+     */
+    hasPlottableResults(): boolean;
 }
diff --git a/src/app/results/plottable-macrorugo-compound-results.ts b/src/app/results/plottable-macrorugo-compound-results.ts
deleted file mode 100644
index caf34a11989af147825f46ebdacfaf9cd76a42dc..0000000000000000000000000000000000000000
--- a/src/app/results/plottable-macrorugo-compound-results.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import { PlottableData } from "./plottable-data";
-import { ChartType } from "./chart-type";
-import { MacrorugoCompoundResults } from "./macrorugo-compound-results";
-
-import { ParamDefinition } from "jalhyd";
-
-export class PlottableMacrorugoCompoundResults implements PlottableData {
-
-    public graphType: ChartType = ChartType.Scatter;
-    public chartX: string;
-    public chartY: string;
-
-    protected mrcResults: MacrorugoCompoundResults;
-
-    public constructor(mrcResults?: MacrorugoCompoundResults) {
-        if (mrcResults) {
-            this.setMrcResults(mrcResults);
-        }
-        // axes par défaut
-        this.chartX = this.chartX || "xCenter";
-        this.chartY = this.chartY || "Q";
-    }
-
-    /** reaffect mrcResults, for ex. when objet was contructed with empty mrcResults */
-    public setMrcResults(mrcResults: MacrorugoCompoundResults) {
-        this.mrcResults = mrcResults;
-    }
-
-    /**
-     * Returns the label to display, for an element of getAvailableChartAxis()
-     * @param symbol parameter / result symbol (ex: "Q")
-     */
-    public getChartAxisLabel(symbol: string): string {
-        return this.mrcResults.headers[this.mrcResults.columns.indexOf(symbol)];
-    }
-
-    public expandLabelFromSymbol(p: ParamDefinition): string {
-        return p.symbol;
-    }
-
-    /**
-     * Returns a list of plottable parameters / result elements, that can be defined
-     * as X or Y chart axis
-     */
-    public getAvailableChartAxis(): string[] {
-        const axis = [];
-        for (const c of this.mrcResults.columns) {
-            if (c.indexOf("ENUM_") === -1) { // ENUM variables are not plottable
-                axis.push(c);
-            }
-        }
-        return axis;
-    }
-
-    public getAvailableXAxis(): string[] {
-        return this.getAvailableChartAxis();
-    }
-
-    public getAvailableYAxis(): string[] {
-        return this.getAvailableChartAxis();
-    }
-
-    // just to implement interface
-    public getVariatingParametersSymbols(): string[] {
-        return [];
-    }
-
-    /**
-     * Returns the series of values for the required symbol
-     * @param symbol parameter / result symbol (ex: "Q")
-     */
-    public getValuesSeries(symbol: string): number[] {
-        const data: number[] = [];
-        const l = this.mrcResults.childrenResults.length;
-        // when a parameter is variating, index of the variating parameter
-        // values to build the data from
-        const vi = this.mrcResults.variableIndex;
-
-        if (this.mrcResults.iterationHasError(vi)) {
-            return [];
-        }
-
-        for (let i = 0; i < l; i++) {
-            switch (symbol) {
-                case "RADIER_N":
-                    data.push(i + 1);
-                    break;
-
-                case "ZF1":
-                case "Y":
-                case "B":
-                    let v: number;
-                    const nub = this.mrcResults.childrenResults[i].sourceNub;
-                    const param = nub.getParameter(symbol);
-                    try {
-                        if (param.hasMultipleValues) {
-                            v = param.getInferredValuesList()[vi];
-                        } else {
-                            v = param.singleValue;
-                        }
-                    } catch (e) {
-                        // silent fail
-                    }
-                    data.push(v);
-                    break;
-
-                case "Q":
-                case "Vdeb":
-                case "Fr":
-                case "Vmax":
-                case "PV":
-                case "xCenter":
-                    data.push(this.mrcResults.childrenResults[i].resultElements[vi].getValue(symbol));
-                    break;
-            }
-        }
-
-        return data;
-    }
-}
diff --git a/src/app/results/plottable-pab-results.ts b/src/app/results/plottable-pab-results.ts
deleted file mode 100644
index 56ee016711ae367ffd20ce2abc8f25c46bcfc843..0000000000000000000000000000000000000000
--- a/src/app/results/plottable-pab-results.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import { PlottableData } from "./plottable-data";
-import { PabResults } from "./pab-results";
-import { ChartType } from "./chart-type";
-import { ServiceFactory } from "../services/service-factory";
-
-import { ParamDefinition } from "jalhyd";
-
-export class PlottablePabResults implements PlottableData {
-
-    public graphType: ChartType = ChartType.Scatter;
-    public chartX: string;
-    public chartY: string;
-
-    protected pabResults: PabResults;
-
-    public constructor(pabResults?: PabResults) {
-        if (pabResults) {
-            this.setPabResults(pabResults);
-        }
-        // axes par défaut
-        this.chartX = this.chartX || "CLOISON";
-        this.chartY = this.chartY || "YMOY";
-    }
-
-    /** reaffect pabResults, for ex. when objet was contructed with empty pabResults */
-    public setPabResults(pabResults: PabResults) {
-        this.pabResults = pabResults;
-    }
-
-    /**
-     * Returns the label to display, for an element of getAvailableChartAxis()
-     * @param symbol parameter / result symbol (ex: "Q")
-     */
-    public getChartAxisLabel(symbol: string): string {
-        if (symbol === "x") { // specific case for wall abscissa
-            return ServiceFactory.i18nService.localizeText("INFO_LIB_ABSCISSE_CLOISON");
-        } else {
-            return this.pabResults.headers[this.pabResults.columns.indexOf(symbol)];
-        }
-    }
-
-    public expandLabelFromSymbol(p: ParamDefinition): string {
-        return p.symbol;
-    }
-
-    /**
-     * Returns a list of plottable parameters / result elements, that can be defined
-     * as X or Y chart axis
-     */
-    public getAvailableChartAxis(): string[] {
-        const axis = [];
-        axis.push("x"); // wall abscissa
-        for (const c of this.pabResults.columns) {
-            if (c.indexOf("ENUM_") === -1) { // ENUM variables are not plottable
-                axis.push(c);
-            }
-        }
-        return axis;
-    }
-
-    public getAvailableXAxis(): string[] {
-        return this.getAvailableChartAxis();
-    }
-
-    public getAvailableYAxis(): string[] {
-        return this.getAvailableChartAxis();
-    }
-
-    // just to implement interface
-    public getVariatingParametersSymbols(): string[] {
-        return [];
-    }
-
-    /**
-     * Returns the series of values for the required symbol
-     * @param symbol parameter / result symbol (ex: "Q")
-     */
-    public getValuesSeries(symbol: string): number[] {
-        const data: number[] = [];
-        const pr = this.pabResults;
-        const l = this.pabResults.cloisonsResults.length;
-        // when a parameter is variating, index of the variating parameter
-        // values to build the data from
-        const vi = this.pabResults.variableIndex;
-
-        if (this.pabResults.iterationHasError(vi)) {
-            return [];
-        }
-
-        switch (symbol) {
-            case "CLOISON":
-                data.push(undefined);
-                for (let i = 0; i <= l; i++) { // <= for one extra step (downwall)
-                    data.push(i + 1);
-                }
-                break;
-
-            case "DH":
-            case "ZRAM":
-            case "Q":
-                data.push(undefined);
-                for (let i = 0; i < l; i++) {
-                    const er = pr.cloisonsResults[i].resultElements[vi].getValue(symbol);
-                    data.push(er);
-                }
-                const zrAval = pr.cloisonAvalResults.resultElements[vi].getValue(symbol);
-                data.push(zrAval);
-                break;
-
-            case "Z":
-                for (let i = 0; i < l; i++) {
-                    data.push(pr.cloisonsResults[i].resultElements[vi].vCalc);
-                }
-                data.push(pr.cloisonAvalResults.resultElements[vi].vCalc);
-                data.push(pr.Z2[vi]);
-                break;
-
-            case "PV":
-            case "YMOY":
-            case "ZRMB":
-            case "QA":
-                data.push(undefined);
-                for (let i = 0; i < l; i++) {
-                    const er = pr.cloisonsResults[i].resultElements[vi].getValue(symbol);
-                    data.push(er);
-                }
-                data.push(undefined);
-                break;
-
-            case "x": // wall abscissa
-                data.push(undefined);
-                for (let i = 0; i < l; i++) {
-                    const er = pr.cloisonsResults[i].resultElements[vi].getValue(symbol);
-                    data.push(er);
-                }
-                const erXdw = pr.cloisonAvalResults.resultElements[vi].getValue(symbol);
-                data.push(erXdw);
-                break;
-        }
-
-        return data;
-    }
-}
diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts
index 918d7084561d7b575e9f0d540a482db461d99936..7b85bfb0dc7efa90f0444dbb42c8d7c460682b25 100644
--- a/src/app/results/var-results.ts
+++ b/src/app/results/var-results.ts
@@ -13,7 +13,7 @@ export class VarResults extends CalculatedParamResults implements PlottableData
     /**
      * paramètres variés
      */
-    private _variatedParams: VariatedDetails[];
+    private _variatedParams: VariatedDetails[] = [];
 
     /**
      * titre des colonnes des résultats variés
@@ -97,28 +97,37 @@ export class VarResults extends CalculatedParamResults implements PlottableData
         return this._resultHeaders;
     }
 
-    public get graphType(): ChartType {
+    public get chartType(): ChartType {
         return this._graphType;
     }
 
-    public set graphType(gt: ChartType) {
+    public set chartType(gt: ChartType) {
         this._graphType = gt;
         this.resetDefaultAxisIfNeeded();
     }
 
-    public getChartAxisLabel(symbol: string): string {
-        // 1. calculated param ?
-        if (this.calculatedParameter && this.calculatedParameter.symbol === symbol) {
-            return this.calculatedParameterHeader;
+    public hasPlottableResults(): boolean {
+        if (this.result === undefined) {
+            return false;
         }
-        // 2. variated param ?
-        for (let i = 0; i < this.variatedParameters.length; i++) {
-            if (this._variatedParams[i].param.symbol === symbol) {
-                return this.variableParamHeaders[i];
+        return ! this.result.hasOnlyErrors;
+    }
+
+    public getChartAxisLabel(symbol: string): string {
+        if (this.result) {
+            // 1. calculated param ?
+            if (this.calculatedParameter && this.calculatedParameter.symbol === symbol) {
+                return this.calculatedParameterHeader;
+            }
+            // 2. variated param ?
+            for (let i = 0; i < this.variatedParameters.length; i++) {
+                if (this._variatedParams[i].param.symbol === symbol) {
+                    return this.variableParamHeaders[i];
+                }
             }
+            // 3. Result element / child result
+            return this.expandLabelFromSymbol(new ParamDefinition(undefined, symbol, ParamDomainValue.ANY));
         }
-        // 3. Result element / child result
-        return this.expandLabelFromSymbol(new ParamDefinition(undefined, symbol, ParamDomainValue.ANY));
     }
 
     /**
@@ -408,10 +417,10 @@ export class VarResults extends CalculatedParamResults implements PlottableData
      * When variable parameter or chart type changes, ensure the X / Y current values are still available
      */
     public resetDefaultAxisIfNeeded() {
-        if (! this.getAvailableXAxis().includes(this.chartX)) {
+        if (this.variatedParameters.length > 0 && ! this.getAvailableXAxis().includes(this.chartX)) {
             this.chartX = this.variatedParameters[0].param.symbol;
         }
-        if (! this.getAvailableYAxis().includes(this.chartY)) {
+        if (this.variatedParameters.length > 0 && ! this.getAvailableYAxis().includes(this.chartY)) {
             this.chartY = this.variatedParameters[0].param.symbol;
         }
     }