From 4ae2fb27a8a9d818b0dd30f50be371d75fc8b06f Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 19 Jun 2025 14:15:09 +0200 Subject: Popover: Refactor area/length formatting. --- main.js | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'main.js') diff --git a/main.js b/main.js index 3dec92f..0f15ac9 100644 --- a/main.js +++ b/main.js @@ -4546,32 +4546,34 @@ const disposePopover = (function() { }; /* format value to HTML */ - const formatNumberLocale = new Intl.NumberFormat(LOCALE); + const numberFormatters = [ + { }, + { maximumFractionDigits: 1 }, + { maximumFractionDigits: 2 }, + ] + /* XXX would be nice to use Intl.NumberFormat()'s unit support, but m² and km² are not + * supported currently, see https://github.com/tc39/ecma402/issues/767 */ + .map((fmt) => new Intl.NumberFormat(LOCALE, fmt)); + const unitSeparator = '\u00A0'; /* U+00A0 NO-BREAK SPACE */ const formatValue = function(value, options) { - let unit = options?.unit; if (options?.fn == null) { /* no-op */ } else if (typeof options.fn === 'function') { value = options.fn(value); - } else if (options.fn === 'length' && typeof value === 'number' && unit == null) { - if (value < 1000) { - unit = 'm'; + } else if (options.fn === 'length' && typeof value === 'number' && options?.unit == null) { + if (value <= 5_000) { /* ≤ 5 km */ + value = numberFormatters[1].format(value) + unitSeparator + 'm'; } else { - value /= 1000; - value = Math.round(value*100) / 100; - unit = 'km'; + value = numberFormatters[2].format(value/1000) + unitSeparator + 'km'; } - } else if (options.fn === 'area' && typeof value === 'number' && unit == null) { - if (value < 10000) { - unit = 'm²'; - } else if (value < 10000 * 10000) { - value /= 10000; - unit = 'ha'; + } else if (options.fn === 'area' && typeof value === 'number' && options?.unit == null) { + if (value < 10_000) { /* < 1 ha */ + value = numberFormatters[1].format(value) + unitSeparator + 'm²'; + } else if (value < 100_000_000) { /* < 10000 ha (100 km²) */ + value = numberFormatters[2].format(value/10_000) + unitSeparator + 'ha'; } else { - value /= 1000000; - unit = 'km²'; + value = numberFormatters[2].format(value/1_000_000) + unitSeparator + 'km²'; } - value = Math.round(value*100) / 100; } if (value == null) { return null; @@ -4585,8 +4587,9 @@ const disposePopover = (function() { case 'string': return document.createTextNode(value); case 'number': - if (unit != null) { - return document.createTextNode(formatNumberLocale.format(value) + '\u00A0' + unit); + if (options?.unit != null) { + return document.createTextNode(numberFormatters[0].format(value) + + unitSeparator + options.unit); } return document.createTextNode(value.toString()); default: -- cgit v1.2.3