@seasketch/geoprocessing
Version:
Geoprocessing and reporting framework for SeaSketch 2.0
104 lines • 4.07 kB
JavaScript
/**
* Rounds number to a fixed number of decimals
* @param value Value to round
* @param decimals Number of digits after the decimal point to keep
* @param options.keepSmallValues If true, will keep any small value as-is which would be rounded to 0, defaults to false
* @returns rounded number
*/
export const roundDecimal = (
/** Value to round */
value,
/** Number of digits after the decimal point to keep */
decimals = 1, options = {}) => {
const { keepSmallValues = false } = options;
const roundedValue = Number(Math.round(Number.parseFloat(`${value}e${decimals}`)) + `e-${decimals}`);
return keepSmallValues && value && !roundedValue ? value : roundedValue;
};
/**
* Rounds number to a fixed number of decimals, then formats as a human readable string
* @param value Value to round
* @param decimals Number of digits after the decimal point to keep
* @param options.keepSmallValues If true, will keep any small value as-is which would be rounded to 0, defaults to false
* @returns rounded number as a human readable string
*/
export const roundDecimalFormat = (
/** Value to round */
value,
/** Number of digits after the decimal point to keep */
decimals = 1, options = {}) => {
const NumberFormatter = new Intl.NumberFormat("en", { style: "decimal" });
return NumberFormatter.format(roundDecimal(value, decimals, options));
};
/** Formats number to string, if less than zero will leave as-is, otherwise will format as large number */
export const numberFormat = (val) => {
const NumberFormatter = new Intl.NumberFormat("en", { style: "decimal" });
return val < 0 ? `${val}` : NumberFormatter.format(val);
};
/**
* Special percent formatter designed to produce readable percent values for
* display with special handling of numbers within some edge range of
* user-defined lower or upper bounds. Defaults to handle only lower edge with
* lowerBound = 0 and lower = .001. All bound values are expected to be in
* decimal percent. So 1/10th of a percent is .001
*/
export const percentWithEdge = (val, options = {}) => {
const { digits = 1, digitsIfMatchLower = 0, lower = 0.001, lowerBound = 0, lowerOverride, upper, upperBound, upperOverride, } = options;
const PercentFormatter = new Intl.NumberFormat("en", {
style: "percent",
maximumFractionDigits: digits,
});
const MatchPercentFormatter = new Intl.NumberFormat("en", {
style: "percent",
maximumFractionDigits: digitsIfMatchLower,
});
if (val === lowerBound) {
return MatchPercentFormatter.format(val);
}
else if (val > lowerBound && val < lower) {
if (lowerOverride) {
return lowerOverride;
}
else {
return `< ${PercentFormatter.format(lower)}`;
}
}
else if (upper !== undefined &&
upperBound !== undefined &&
val < upperBound &&
val > upper) {
if (upperOverride) {
return upperOverride;
}
else {
return PercentFormatter.format(upper);
}
}
else {
return PercentFormatter.format(val);
}
};
/**
* Special percent formatter designed to produce readable percent values for display given an upper percent goal
* All parameters are expected to be decimal percent values e.g. .001 = 1/10th of a percent.
*/
export const percentGoalWithEdge = (
/** Actual percent value */
val,
/** Goal percent value */
goal,
/** Override options passed to percentWithEdge, supports same parameters */
options) => {
return percentWithEdge(val, {
upperBound: goal,
upper: goal - 0.001,
...options,
});
};
/** Formats number to string, rounding decimal to number of digits, if value is less than lower will clamp to lower value */
export const roundLower = (val, { lower } = { lower: 1 }) => {
const NumberFormatter = new Intl.NumberFormat("en", { style: "decimal" });
return val < lower
? `< ${lower}`
: NumberFormatter.format(roundDecimal(val, 1));
};
//# sourceMappingURL=number.js.map