From 87e00cfca74d99831753c2cbd5024f1e47f2d5eb Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Fri, 6 Sep 2019 12:13:36 +0200
Subject: [PATCH] Fix #281 use formattedValue (fv) instead of toFixed

---
 .../dialog-edit-param-values.component.ts     |  3 +-
 .../fixedvar-results/results.component.ts     |  3 +-
 .../pab-profile-graph.component.ts            | 35 ++++++++++---------
 .../pab-results-table.component.ts            | 29 +++++++--------
 .../pab-results/pab-results.component.ts      |  5 ---
 ...pab-variable-results-selector.component.ts |  3 +-
 .../remous-results.component.ts               |  9 ++---
 .../results-graph/results-graph.component.ts  | 17 ++++-----
 src/app/formulaire/ngparam.ts                 | 25 ++++++-------
 .../internationalisation.service.ts           |  5 +--
 src/app/util.ts                               | 34 ++++++++++++++++++
 11 files changed, 103 insertions(+), 65 deletions(-)

diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
index 9c5947efc..070a5422d 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
@@ -6,6 +6,7 @@ import { NgParameter } from "../../formulaire/ngparam";
 import { ParamValueMode, ExtensionStrategy } from "jalhyd";
 import { sprintf } from "sprintf-js";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
+import { fv } from "../../util";
 
 @Component({
     selector: "dialog-edit-param-values",
@@ -125,7 +126,7 @@ export class DialogEditParamValuesComponent implements OnInit {
             tooltips: {
                 callbacks: {
                     label: function(tooltipItem) {
-                        return  Number(tooltipItem.yLabel).toFixed(nDigits);
+                        return  fv(Number(tooltipItem.yLabel));
                     }
                 }
             }
diff --git a/src/app/components/fixedvar-results/results.component.ts b/src/app/components/fixedvar-results/results.component.ts
index 4f45d632e..db20c2ec5 100644
--- a/src/app/components/fixedvar-results/results.component.ts
+++ b/src/app/components/fixedvar-results/results.component.ts
@@ -3,6 +3,7 @@ import { Screenfull } from "screenfull"; // @see https://github.com/sindresorhus
 
 import { NgParameter } from "../../formulaire/ngparam";
 import { ServiceFactory } from "../../services/service-factory";
+import { fv } from "../../util";
 
 /**
  * Base class for results components, including common features
@@ -82,7 +83,7 @@ export class ResultsComponent {
         if (originalValue < minRenderableNumber) {
             return String(Number(originalValue.toPrecision(nDigits))); // double casting avoids trailing zeroes
         } else {
-            return originalValue.toFixed(nDigits);
+            return fv(originalValue);
         }
     }
 }
diff --git a/src/app/components/pab-profile-graph/pab-profile-graph.component.ts b/src/app/components/pab-profile-graph/pab-profile-graph.component.ts
index 1fcbeb2d5..92a5b9979 100644
--- a/src/app/components/pab-profile-graph/pab-profile-graph.component.ts
+++ b/src/app/components/pab-profile-graph/pab-profile-graph.component.ts
@@ -9,6 +9,7 @@ import { PabResults } from "../../results/pab-results";
 import { IYSeries } from "../../results/y-series";
 
 import { CloisonAval, Cloisons } from "jalhyd";
+import { fv } from "../../util";
 
 @Component({
     selector: "pab-profile-graph",
@@ -136,7 +137,7 @@ export class PabProfileGraphComponent extends ResultsComponent {
                 const iter = v.getExtendedValuesIterator(this.size);
                 while (iter.hasNext) {
                     const nv = iter.next();
-                    vv.push(nv.value.toFixed(nDigits));
+                    vv.push(fv(nv.value));
                 }
                 this.varValues.push(vv);
             }
@@ -213,10 +214,10 @@ export class PabProfileGraphComponent extends ResultsComponent {
         // X is always wall abscissa
         for (const cr of this._results.cloisonsResults) {
             const x = cr.resultElement.getValue("x"); // any resultElement will do
-            data.push(x.toFixed(nDigits));
+            data.push(fv(x));
         }
         const xdw = this._results.cloisonAvalResults.resultElement.getValue("x");
-        data.push(xdw.toFixed(nDigits));
+        data.push(fv(xdw));
         return data;
     }
 
@@ -231,8 +232,8 @@ export class PabProfileGraphComponent extends ResultsComponent {
         const nDigits = this.appSetupService.displayDigits;
         // extend upstream
         dataF.push({
-            x: (Number(xs[0]) - pabLength5Pct).toFixed(nDigits),
-            y: this._results.cloisonsResults[0].resultElement.getValue("ZRAM").toFixed(nDigits)
+            x: fv(Number(xs[0]) - pabLength5Pct),
+            y: fv(this._results.cloisonsResults[0].resultElement.getValue("ZRAM"))
         });
         // regular walls
         for (let i = 0; i < this._results.cloisonsResults.length; i++) {
@@ -243,11 +244,11 @@ export class PabProfileGraphComponent extends ResultsComponent {
             const halfLB = c.prms.LB.singleValue / 2;
             dataF.push({
                 x: xs[i],
-                y: ZRAM.toFixed(nDigits)
+                y: fv(ZRAM)
             });
             dataF.push({
-                x: (Number(xs[i]) + halfLB).toFixed(nDigits),
-                y: ZRMB.toFixed(nDigits)
+                x: fv(Number(xs[i]) + halfLB),
+                y: fv(ZRMB)
             });
         }
         // downwall
@@ -255,12 +256,12 @@ export class PabProfileGraphComponent extends ResultsComponent {
         const ZRAMdw = dw.prms.ZRAM.singleValue;
         dataF.push({
             x: xs[ xs.length - 1 ],
-            y: ZRAMdw.toFixed(nDigits)
+            y: fv(ZRAMdw)
         });
         // extend downstream
         dataF.push({
-            x: (Number(xs[xs.length - 1]) + pabLength5Pct).toFixed(nDigits),
-            y: ZRAMdw.toFixed(nDigits)
+            x: fv(Number(xs[xs.length - 1]) + pabLength5Pct),
+            y: fv(ZRAMdw)
         });
         // add series
         ret.push({
@@ -286,8 +287,8 @@ export class PabProfileGraphComponent extends ResultsComponent {
 
             // extend upstream
             dataN.push({
-                x: (Number(xs[0]) - pabLength5Pct).toFixed(nDigits),
-                y: this._results.cloisonsResults[0].resultElements[n].vCalc.toFixed(nDigits)
+                x: fv(Number(xs[0]) - pabLength5Pct),
+                y: fv(this._results.cloisonsResults[0].resultElements[n].vCalc)
             });
 
             // walls
@@ -311,11 +312,11 @@ export class PabProfileGraphComponent extends ResultsComponent {
                 // 2 points for each abscissa
                 dataN.push({
                     x: x,
-                    y: Z1.toFixed(nDigits)
+                    y: fv(Z1)
                 });
                 dataN.push({
                     x: x,
-                    y: (nextZ1 !== undefined ? nextZ1.toFixed(nDigits) : "")
+                    y: (nextZ1 !== undefined ? fv(nextZ1) : "")
                 });
 
                 i++;
@@ -323,8 +324,8 @@ export class PabProfileGraphComponent extends ResultsComponent {
 
             // extend downstream
             dataN.push({
-                x: (Number(xs[xs.length - 1]) + pabLength5Pct).toFixed(nDigits),
-                y: (this._results.Z2[n] ? this._results.Z2[n].toFixed(nDigits) : "")
+                x: fv(Number(xs[xs.length - 1]) + pabLength5Pct),
+                y: (this._results.Z2[n] ? fv(this._results.Z2[n]) : "")
             });
 
             ret.push({
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 d685f4500..d17b83a56 100644
--- a/src/app/components/pab-results/pab-results-table.component.ts
+++ b/src/app/components/pab-results/pab-results-table.component.ts
@@ -8,6 +8,7 @@ import { PabResults } from "../../results/pab-results";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
 import { ResultsComponent } from "../fixedvar-results/results.component";
+import { fv } from "../../util";
 
 @Component({
     selector: "pab-results-table",
@@ -76,7 +77,7 @@ export class PabResultsTableComponent extends ResultsComponent {
             if (pr.cloisonsResults[0].resultElements[vi].vCalc) { // parfois le calcul des cloisons échoue
                 this._dataSet.push([
                     this.intlService.localizeText("INFO_LIB_AMONT"),
-                    pr.cloisonsResults[0].resultElements[vi] ? pr.cloisonsResults[0].resultElements[vi].vCalc.toFixed(nDigits) : "",
+                    pr.cloisonsResults[0].resultElements[vi] ? fv(pr.cloisonsResults[0].resultElements[vi].vCalc) : "",
                     "", "", "", "", "", "", ""
                 ]);
             }
@@ -96,14 +97,14 @@ export class PabResultsTableComponent extends ResultsComponent {
 
                     this._dataSet.push([
                         i + 1, // n° cloison
-                        Z1.toFixed(nDigits), // Z
-                        r2n.ZRAM.toFixed(nDigits),
-                        r2n.DH.toFixed(nDigits),
-                        r2n.Q.toFixed(nDigits),
-                        r2n.PV.toFixed(nDigits),
-                        r2n.YMOY.toFixed(nDigits),
-                        r2n.ZRMB.toFixed(nDigits),
-                        r2n.QA,
+                        fv(Z1), // Z
+                        fv(r2n.ZRAM),
+                        fv(r2n.DH),
+                        fv(r2n.Q),
+                        fv(r2n.PV),
+                        fv(r2n.YMOY),
+                        fv(r2n.ZRMB),
+                        fv(r2n.QA),
                         this.getJetTypes(pr.cloisonsResults[i], vi)
                     ]);
                 }
@@ -115,10 +116,10 @@ export class PabResultsTableComponent extends ResultsComponent {
                 const rln = pr.cloisonAvalResults.resultElements[vi].values;
                 this._dataSet.push([
                     this.intlService.localizeText("INFO_LIB_AVAL"),
-                    (pr.Z2[vi] !== undefined ? pr.Z2[vi].toFixed(nDigits) : ""),
-                    cloisonAval.prms.ZRAM.singleValue.toFixed(nDigits),
-                    rln.DH.toFixed(nDigits),
-                    rln.Q.toFixed(nDigits),
+                    (pr.Z2[vi] !== undefined ? fv(pr.Z2[vi]) : ""),
+                    fv(cloisonAval.prms.ZRAM.singleValue),
+                    fv(rln.DH),
+                    fv(rln.Q),
                     "", "", "", "",
                     this.getJetTypes(pr.cloisonAvalResults, vi)
                 ]);
@@ -128,7 +129,7 @@ export class PabResultsTableComponent extends ResultsComponent {
                     if (vanneZDV) {
                         this._dataSet.push([
                             this.intlService.localizeText("INFO_LIB_COTE_VANNE_LEVANTE"),
-                            vanneZDV.toFixed(nDigits),
+                            fv(vanneZDV),
                             "", "", "", "", "", "", ""
                         ]);
                     }
diff --git a/src/app/components/pab-results/pab-results.component.ts b/src/app/components/pab-results/pab-results.component.ts
index 510867ca6..4cd9b0dab 100644
--- a/src/app/components/pab-results/pab-results.component.ts
+++ b/src/app/components/pab-results/pab-results.component.ts
@@ -322,11 +322,6 @@ export class PabResultsComponent implements DoCheck {
         return CalculatorResults.paramLabel(p, false);
     }
 
-    public formattedValue(p: NgParameter): string {
-        const nDigits = this.appSetupService.displayDigits;
-        return p.getValue().toFixed(nDigits);
-    }
-
     public get hasResults(): boolean {
         return this._pabResults && this._pabResults.hasResults;
     }
diff --git a/src/app/components/pab-results/pab-variable-results-selector.component.ts b/src/app/components/pab-results/pab-variable-results-selector.component.ts
index 4986bfbf8..799cc5267 100644
--- a/src/app/components/pab-results/pab-variable-results-selector.component.ts
+++ b/src/app/components/pab-results/pab-variable-results-selector.component.ts
@@ -3,6 +3,7 @@ import { Component, Output, EventEmitter } from "@angular/core";
 import { PabResults } from "../../results/pab-results";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
+import { fv } from "../../util";
 
 @Component({
     selector: "pab-variable-results-selector",
@@ -55,7 +56,7 @@ export class PabVariableResultsSelectorComponent {
                 const iter = v.getExtendedValuesIterator(this.size);
                 while (iter.hasNext) {
                     const nv = iter.next();
-                    vv.push(nv.value.toFixed(nDigits));
+                    vv.push(fv(nv.value));
                 }
                 this.varValues.push(vv);
             }
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index da77b6c0d..df5678887 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -10,6 +10,7 @@ import { VarResultsComponent } from "../fixedvar-results/var-results.component";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { FormulaireService } from "../../services/formulaire/formulaire.service";
 import { ResultsComponent } from "../fixedvar-results/results.component";
+import { fv } from "../../util";
 
 /**
  * données pour une ligne dans le graphe
@@ -605,7 +606,7 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
                     ticks: {
                         precision: nDigits,
                         callback: function(value, index, values) {
-                            return Number(value).toFixed(nDigits);
+                            return fv(Number(value));
                         }
                     },
                     scaleLabel: {
@@ -617,7 +618,7 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
             tooltips: {
                 callbacks: {
                     label: function(tooltipItem, data) {
-                        return Number(tooltipItem.yLabel).toFixed(nDigits);
+                        return fv(Number(tooltipItem.yLabel));
                     }
                 }
             }
@@ -645,7 +646,7 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
                         ticks: {
                             precision: nDigits,
                             callback: function(value, index, values) {
-                                return Number(value).toFixed(nDigits);
+                                return fv(Number(value));
                             }
                         },
                     }]
@@ -653,7 +654,7 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
                 tooltips: {
                     callbacks: {
                         label: function(tooltipItem, data) {
-                            return Number(tooltipItem.yLabel).toFixed(nDigits);
+                            return fv(Number(tooltipItem.yLabel));
                         }
                     }
                 }
diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts
index 7c1ae074f..96c35127a 100644
--- a/src/app/components/results-graph/results-graph.component.ts
+++ b/src/app/components/results-graph/results-graph.component.ts
@@ -12,6 +12,7 @@ import { GraphType } from "../../results/graph-type";
 import { ResultsComponent } from "../fixedvar-results/results.component";
 import { IYSeries } from "../../results/y-series";
 import { VarResults } from "../../results/var-results";
+import { fv } from "../../util";
 
 @Component({
     selector: "results-graph",
@@ -240,7 +241,7 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
                 ticks: {
                     precision: nDigits,
                     callback: function(value, index, values) {
-                        return Number(value).toFixed(nDigits);
+                        return fv(Number(value));
                     }
                 },
                 scaleLabel: {
@@ -261,14 +262,14 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
             displayColors: false,
             callbacks: {
                 title: (tooltipItems, data) => {
-                    return this.chartY + " = " + Number(tooltipItems[0].yLabel).toFixed(nDigits);
+                    return this.chartY + " = " + fv(Number(tooltipItems[0].yLabel));
                 },
                 label: (tooltipItem, data) => {
                     const lines: string[] = [];
                     const nbLines = that._results.getVariatingParametersSymbols().length;
                     for (const v of that._results.getVariatingParametersSymbols()) {
                         const series = that._results.getValuesSeries[0](v);
-                        const line = v + " = " + series[tooltipItem.index].toFixed(nDigits);
+                        const line = v + " = " + fv(series[tooltipItem.index]);
                         if (v === this.chartX) {
                             if (nbLines > 1) {
                                 lines.unshift("");
@@ -357,14 +358,14 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
                 displayColors: false,
                 callbacks: {
                     title: (tooltipItems, data) => {
-                        return this.chartY + " = " + Number(tooltipItems[0].yLabel).toFixed(nDigits);
+                        return this.chartY + " = " + fv(Number(tooltipItems[0].yLabel));
                     },
                     label: (tooltipItem, data) => {
                         let lines: string[] = [];
                         // 1. X if different from Y
                         if (this.chartX !== this.chartY) {
                             const xseries = that._results.getValuesSeries(this.chartX);
-                            const xline = this.chartX + " = " + xseries[tooltipItem.index].toFixed(nDigits);
+                            const xline = this.chartX + " = " + fv(xseries[tooltipItem.index]);
                             lines.push(xline);
                         }
                         // 2. variated parameters other than X or Y
@@ -372,7 +373,7 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
                         for (const v of that._results.getVariatingParametersSymbols()) {
                             if (v !== this.chartX && v !== this.chartY) {
                                 const series = that._results.getValuesSeries(v);
-                                const line = v + " = " + series[tooltipItem.index].toFixed(nDigits);
+                                const line = v + " = " + fv(series[tooltipItem.index]);
                                 varLines.push(line);
                             }
                         }
@@ -417,8 +418,8 @@ export class ResultsGraphComponent extends ResultsComponent implements AfterCont
             // build fixed precision x/y coordinate pairs
             for (let j = 0; j < xSeries.length; j++) {
                 dat.push({
-                    x: (xSeries[j] !== undefined) ? xSeries[j].toFixed(nDigits) : "",
-                    y: (ySeries[j] !== undefined) ? ySeries[j].toFixed(nDigits) : ""
+                    x: (xSeries[j] !== undefined) ? fv(xSeries[j]) : "",
+                    y: (ySeries[j] !== undefined) ? fv(ySeries[j]) : ""
                 });
             }
             // add series
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index a76a934ff..a58d5ff42 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -6,6 +6,7 @@ import { sprintf } from "sprintf-js";
 import { InputField } from "./input-field";
 import { ServiceFactory } from "../services/service-factory";
 import { FormulaireNode } from "./formulaire-node";
+import { fv } from "../util";
 
 export enum ParamRadioConfig {
     /** pas de radio, paramètre modifiable à la main uniquement */
@@ -45,20 +46,20 @@ export class NgParameter extends InputField implements Observer {
 
         switch (p.valueMode) {
             case ParamValueMode.SINGLE:
-                valuePreview = String(p.getValue().toFixed(nDigits));
+                valuePreview = fv(p.getValue());
                 break;
             case ParamValueMode.MINMAX:
                 let min: any = p.min;
                 let max: any = p.max;
                 let step: any = p.step;
                 if (min) {
-                    min = min.toFixed(nDigits);
+                    min = fv(min);
                 }
                 if (max) {
-                    max = max.toFixed(nDigits);
+                    max = fv(max);
                 }
                 if (step) {
-                    step = step.toFixed(nDigits);
+                    step = fv(step);
                 }
                 if (compact) {
                     valuePreview = min + " … " + max;
@@ -70,11 +71,11 @@ export class NgParameter extends InputField implements Observer {
             case ParamValueMode.LISTE:
                 const vals = p.valueList || [];
                 if (compact) {
-                    valuePreview = vals[0].toFixed(nDigits) + " … " + vals[vals.length - 1].toFixed(nDigits);
+                    valuePreview = fv(vals[0]) + " … " + fv(vals[vals.length - 1]);
                 } else {
                     valuePreview = i18n.localizeText("INFO_PARAMFIELD_PARAMVARIER_VALUES");
                     valuePreview += " " + vals.slice(0, 5).map((v) => {
-                        return v.toFixed(nDigits);
+                        return fv(v);
                     }).join("; ") + "…";
                 }
                 break;
@@ -82,7 +83,7 @@ export class NgParameter extends InputField implements Observer {
                 valuePreview = i18n.localizeText("INFO_PARAMFIELD_IN_CALCULATION");
                 if (p.calculability === ParamCalculability.DICHO) {
                     valuePreview += " (" + i18n.localizeText("INFO_PARAMFIELD_IN_CALCULATION_INITIAL_VALUE")
-                        + ": " + p.getValue().toFixed(nDigits) + ")";
+                        + ": " + fv(p.getValue()) + ")";
                 }
                 break;
             case ParamValueMode.LINK:
@@ -112,11 +113,11 @@ export class NgParameter extends InputField implements Observer {
                     if (ref.hasMultipleValues()) {
                         // compact representation
                         const cVal = ref.nub.result.getCalculatedValues();
-                        valuePreview = cVal[0].toFixed(nDigits) + " … " + cVal[cVal.length - 1].toFixed(nDigits);
+                        valuePreview = fv(cVal[0]) + " … " + fv(cVal[cVal.length - 1]);
                     } else {
                         const vCalc = ref.nub.result.vCalc;
                         if (vCalc) {
-                            valuePreview = String(vCalc.toFixed(nDigits));
+                            valuePreview = fv(vCalc);
                         } else {
                             // computation has been run but has failed
                             valuePreview = i18n.localizeText("INFO_PARAMFIELD_CALCULATION_FAILED");
@@ -136,10 +137,10 @@ export class NgParameter extends InputField implements Observer {
                 if (ref.hasMultipleValues()) {
                     // compact representation
                     const cVal = remoteValues.valueList;
-                    valuePreview = cVal[0].toFixed(nDigits) + " … " + cVal[cVal.length - 1].toFixed(nDigits);
+                    valuePreview = fv(cVal[0]) + " … " + fv(cVal[cVal.length - 1]);
                 } else {
                     // like SINGLE mode
-                    valuePreview = String(remoteValues.currentValue.toFixed(nDigits));
+                    valuePreview = fv(remoteValues.currentValue);
                 }
             } catch (e) {
                 valuePreview = i18n.localizeText("INFO_PARAMFIELD_IN_CALCULATION");
@@ -205,7 +206,7 @@ export class NgParameter extends InputField implements Observer {
             this._paramDef.valueMode = m;
             this.notifyObservers({
                 "action": "valueModeChange",
-                "value": Number(this._paramDef.getValue().toFixed(nDigits))
+                "value": Number(fv(this._paramDef.getValue()))
             });
         }
     }
diff --git a/src/app/services/internationalisation/internationalisation.service.ts b/src/app/services/internationalisation/internationalisation.service.ts
index 65a77c278..063fd0a3a 100644
--- a/src/app/services/internationalisation/internationalisation.service.ts
+++ b/src/app/services/internationalisation/internationalisation.service.ts
@@ -5,6 +5,7 @@ import { Message, MessageCode, Observable, Observer, CalculatorType, LoiDebit }
 import { StringMap } from "../../stringmap";
 import { ApplicationSetupService } from "../app-setup/app-setup.service";
 import { HttpService } from "../http/http.service";
+import { fv } from "../../util";
 
 @Injectable()
 export class I18nService extends Observable implements Observer {
@@ -160,7 +161,7 @@ export class I18nService extends Observable implements Observer {
                 const v: any = r.extraVar[k];
                 let s: string;
                 if (typeof v === "number") {
-                    s = v.toFixed(nDigits);
+                    s = fv(v);
                 } else {
                     s = v;
                 }
@@ -197,7 +198,7 @@ export class I18nService extends Observable implements Observer {
             return this.localizeText(`INFO_${label.substring(match).toUpperCase()}_${value}`);
         }
         const nDigits = this.applicationSetupService.displayDigits;
-        return value.toFixed(nDigits);
+        return fv(value);
     }
 
     // interface Observer
diff --git a/src/app/util.ts b/src/app/util.ts
index b40e36cfe..9131ccba8 100644
--- a/src/app/util.ts
+++ b/src/app/util.ts
@@ -1,3 +1,6 @@
+import { NgParameter } from "./formulaire/ngparam";
+import { ServiceFactory } from "./services/service-factory";
+
 export function logObject(obj: {}, m?: string) {
     // évite le message "Value below was evaluated just now" dans le debugger de Chrome
     if (m === undefined) {
@@ -10,3 +13,34 @@ export function logObject(obj: {}, m?: string) {
 export function isNumber(s: string): boolean {
     return Number(s) !== NaN;
 }
+
+/**
+ * fv (formatted value)
+ * Formats (rounds) the given number (or the value of the given parameter) with the
+ * number of decimals specified in app preferences; if given number is too low and
+ * more decimals would be needed, keep as much significative digits as the number of
+ * decimals specified in app preferences, except potential trailing zeroes
+ *
+ * ex. with 3 decimals:
+ * 1             => 1.000
+ * 65431         => 65431.000
+ * 0.002         => 0.002
+ * 0.00004521684 => 0.0000452
+ * 0.000001      => 0.000001
+ */
+export function fv(p: NgParameter | number): string {
+    let originalValue: number;
+    if (p instanceof NgParameter) {
+        originalValue = p.getValue();
+    } else if (typeof p === "number") {
+        originalValue = p;
+    }
+    const nDigits = ServiceFactory.instance.applicationSetupService.displayDigits;
+    const minRenderableNumber = Number("1E-" + nDigits);
+    // if required precision is too low, avoid rendering only zeroes
+    if (originalValue < minRenderableNumber) {
+        return String(Number(originalValue.toPrecision(nDigits))); // double casting avoids trailing zeroes
+    } else {
+        return originalValue.toFixed(nDigits);
+    }
+}
-- 
GitLab