Skip to content
Snippets Groups Projects
util.ts 6.17 KiB
Newer Older
import { NgParameter } from "./formulaire/elements/ngparam";
import { ServiceFactory } from "./services/service-factory";

import { formattedValue, Nub, VariatedDetails, ParamDefinition } from "jalhyd";
export function logObject(obj: {}, m?: string) {
    // évite le message "Value below was evaluated just now" dans le debugger de Chrome
David Dorchies's avatar
David Dorchies committed
    if (m === undefined) {
David Dorchies's avatar
David Dorchies committed
    } else {
        console.log(m + " " + JSON.stringify(obj));
David Dorchies's avatar
David Dorchies committed
    }
David Dorchies's avatar
David Dorchies committed
    return Number(s) !== NaN;
 * Proxy to jaLhyd.formattedValue() using number of digits from app preferences
 */
export function fv(p: NgParameter | number): string {
    let value: number;
    if (p instanceof NgParameter) {
        value = p.getValue();
    } else if (typeof p === "number") {
    const nDigits = ServiceFactory.applicationSetupService.displayPrecision;

    return formattedValue(value, nDigits);
mathias.chouet's avatar
mathias.chouet committed

/**
 * Trick to decode HTML entities in a string
 * https://stackoverflow.com/a/7394787/5986614
 * @param html string containing HTML entities, like  
 */
export function decodeHtml(html: string): string {
    const txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}

/**
 * Given a list of variated NgParameter, returns the parameter having the most
 * values, its index in the list, and the number of values it contains
 * @param varParams
 */
export function longestVarNgParam(varParams: NgParameter[]): { param: NgParameter, index: number, size: number } {
    const variated: VariatedDetails[] = [];
    for (const vp of varParams) {
        variated.push({
            param: vp.paramDefinition,
            values: vp.paramDefinition.paramValues
        });
    }
    const { param, index, size } = longestVarParam(variated);
    return {
        param: varParams[index],
        index,
        size
    };
}

/**
 * Given a list of variated ParamDefinition, returns the parameter having the most
 * values, its index in the list, and the number of values it contains
 * @param variated
 */
export function longestVarParam(variated: VariatedDetails[]): { param: ParamDefinition, index: number, size: number } {
    const { size, longest, minLinkedResultParam } = Nub.findVariatedSize(variated);
    let realSize = size;
    // if at least one linked variated result was found
    if (minLinkedResultParam !== undefined) {
        // if the size limited by linked variated results is shorter
        // than the size of the longest variating element, limit it
        if (minLinkedResultParam.values.valuesIterator.count() < realSize) {
            realSize = minLinkedResultParam.values.valuesIterator.count();
        param: longest !== undefined ? variated[longest].param : undefined,
        size: realSize
mathias.chouet's avatar
mathias.chouet committed


/**
 * 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);
    }
}

export function arraysAreEqual(arrayA: any[], arrayB: any[], property?: string, sort = false): boolean {
Mathias Chouet's avatar
Mathias Chouet committed
    const aA: any[] = JSON.parse(JSON.stringify(arrayA)); // array copy
    const aB: any[] = JSON.parse(JSON.stringify(arrayB)); // array copy
    if (sort) {
Mathias Chouet's avatar
Mathias Chouet committed
        aA.sort((a, b) => a - b);
        aB.sort((a, b) => a - b);
    }
    let equal = true;
Mathias Chouet's avatar
Mathias Chouet committed
    if (aA.length === aB.length) {
Mathias Chouet's avatar
Mathias Chouet committed
        for (let i = 0; i < aA.length; i++) {
Mathias Chouet's avatar
Mathias Chouet committed
            const eA = aA[i];
            const eB = aB[i];
            if (property === undefined) {
                equal = equal && (eA === eB);
            } else {
                equal = equal && (eA[property] === eB[property]);
            }
        }
    } else {
        equal = false;
    }
    return equal;
}