diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index 45d11200ab78f9b1713af8a79eb8fa1fe62e2f10..28ed8e3363c24634cdbfd0c14e44523d6af9aa7d 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -14,10 +14,10 @@ import { acSection, ParamDefinition, round, - VariatedDetails + Nub } from "jalhyd"; -import { longestVarParam } from "../../util"; +import { generateValuesCombination } from "../../util"; import { AppComponent } from "../../app.component"; import { FormulaireService } from "../../services/formulaire.service"; @@ -714,115 +714,33 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe } /** - * Génère une liste de valeurs de tirant d'eau pour un couple Z1/ZF1 ou Z2/ZF2 donné, que ces - * paramètres soient fixés, variés et/ou calculés - * @TODO factoriser avec generateIfValuesForSP() la partie "générer des combinaisons de valeurs depuis N paramètres" + * Génère une liste de valeurs de tirant d'eau pour un couple Z1/ZF1 ou Z2/ZF2 donné * @param Z cote de leau (Z1 ou Z2) * @param ZF cote de fond (ZF1 ou ZF2) */ private generateYValuesForSP(Z: ParamDefinition, ZF: ParamDefinition): number | number[] { const bief = (this._formulaire.currentNub as Bief); - if ( - (Z.isCalculated && bief.resultHasMultipleValues()) - || Z.hasMultipleValues - || ZF.hasMultipleValues - ) { - // find longest values list with standard Nub method - const { size } = longestVarParam(bief.findVariatedParams()); - - // extend values list for Z / Z1 if they vary - let ZVals: number[]; - if (Z.isCalculated) { - ZVals = bief.result.getCalculatedValues(); - } else { - if (Z.hasMultipleValues) { - ZVals = Z.getInferredValuesList(size); - } else { - ZVals = [ Z.singleValue ]; - } - } - let ZFVals: number[]; - if (ZF.hasMultipleValues) { - ZFVals = ZF.getInferredValuesList(size); - } else { - ZFVals = [ ZF.singleValue ]; + return generateValuesCombination( + bief, + [ Z, ZF ], + (nub: Nub, values: { [key: string]: number }): number => { + return round(values[Z.symbol] - values[ZF.symbol], 3); } - - // calculate Y values - const Ys: number[] = []; - for (let i = 0; i < size; i++) { - // using "%" because one of the two lists might have only 1 value - Ys.push(round(ZVals[i % ZVals.length] - ZFVals[i % ZFVals.length], 3)); - } - return Ys; - - } else { - // .V returns calculated value or latest .v; no problem since no parameter is varying - // @TODO check that .v is not polluted by any DICHO calc ? - const Y = round(Z.V - ZF.V, 3); - return Y; - } + ); } /** - * Génère une liste de valeurs de pente en fonction de ZF1, ZF2 et Long, - * que ces paramètres soient fixés, variés et/ou calculés + * Génère une liste de valeurs de pente en fonction de ZF1, ZF2 et Long */ private generateIfValuesForSP(): number | number[] { const bief = (this._formulaire.currentNub as Bief); - const ZF1 = bief.prms.ZF1; - const ZF2 = bief.prms.ZF2; - const Long = bief.prms.Long; - if (ZF1.hasMultipleValues || ZF2.hasMultipleValues || Long.hasMultipleValues) { - // find longest values list - const variated: VariatedDetails[] = [ - { - param: ZF1, - values: ZF1.paramValues - }, - { - param: ZF2, - values: ZF2.paramValues - }, - { - param: Long, - values: Long.paramValues - } - ]; - const { size } = longestVarParam(variated); - - // extend values list for ZF1 / ZF2 / Long if they vary - let ZF1Vals: number[]; - if (ZF1.hasMultipleValues) { - ZF1Vals = ZF1.getInferredValuesList(size); - } else { - ZF1Vals = [ ZF1.singleValue ]; - } - let ZF2Vals: number[]; - if (ZF2.hasMultipleValues) { - ZF2Vals = ZF2.getInferredValuesList(size); - } else { - ZF2Vals = [ ZF2.singleValue ]; - } - let LongVals: number[]; - if (Long.hasMultipleValues) { - LongVals = Long.getInferredValuesList(size); - } else { - LongVals = [ Long.singleValue ]; + return generateValuesCombination( + bief, + [ bief.prms.ZF1, bief.prms.ZF2, bief.prms.Long ], + (nub: Nub, values: { [key: string]: number }): number => { + return round((values["ZF1"] - values["ZF2"]) / values["Long"], 5); } - - // calculate If values - const Ifs: number[] = []; - for (let i = 0; i < size; i++) { - // using "%" because one of the three lists might have only 1 value - Ifs.push(round((ZF1Vals[i % ZF1Vals.length] - ZF2Vals[i % ZF2Vals.length]) / LongVals[i % LongVals.length], 5)); - } - return Ifs; - - } else { - const If = round((ZF1.singleValue - ZF2.singleValue) / Long.singleValue, 5); - return If; - } + ); } /** diff --git a/src/app/util.ts b/src/app/util.ts index 5339bad8dbe662967ecbb775c7a118a833644360..6f5719bc5b0888c222f55633d3a6171b17a90e81 100644 --- a/src/app/util.ts +++ b/src/app/util.ts @@ -85,3 +85,79 @@ export function longestVarParam(variated: VariatedDetails[]): { param: ParamDefi size: realSize }; } + + +/** + * Generates a combination of values from a list of parameters, by extending the values + * list of each parameter if needed, then applying a formula to every values n-uple + * + * @param nub the Nub holding the parameters + * @param params the parameters to combine + * @param formula the formula to apply, receives 2 args: the Nub, and a map of current + * values for each combined parameter symbol + * @param variatedParams an optional list of parameters used to determine maximum length + * of combined values list; if undefined, all params of the Nub will be used + */ +export function generateValuesCombination( + nub: Nub, + params: ParamDefinition[], + formula: (nub: Nub, values: { [key: string]: number }) => number, + variatedParams?: ParamDefinition[] +): number | number[] { + + let variates = false; + for (const p of params) { + variates = variates || p.hasMultipleValues; // manages CALC mode too + } + if (variates) { + let size: number; + // find longest values list with standard Nub method + if (variatedParams !== undefined) { + const variated: VariatedDetails[] = []; + for (const vp of variatedParams) { + variated.push({ + param: vp, + values: vp.paramValues + }); + } + size = longestVarParam(variated).size; + } else { + size = longestVarParam(nub.findVariatedParams()).size; + } + + // extend values list for all params + const values: { [key: string]: number[] } = {}; + for (const p of params) { + if (p.isCalculated) { + values[p.symbol] = nub.result.getCalculatedValues(); + } else { + if (p.hasMultipleValues) { + values[p.symbol] = p.getInferredValuesList(size); + } else { + values[p.symbol] = [ p.singleValue ]; + } + } + } + + // calculate Y values + const Vs: number[] = []; + for (let i = 0; i < size; i++) { + const vals: { [key: string]: number } = {}; + for (const p of params) { + // using "%" because lists might have only 1 value + vals[p.symbol] = values[p.symbol][i % values[p.symbol].length]; + } + Vs.push(formula(nub, vals)); + } + // variated result + return Vs; + + } else { + const vals: { [key: string]: number } = {}; + for (const p of params) { + vals[p.symbol] = p.V; + } + // single result + return formula(nub, vals); + } +}