statistic —— Статистические значения
Компонент статистических значений показывает «ключевые цифры»: дневная активность, выручка, процент выполнения. Его главный риск — не раскладка, а точность: Number(12345678901234567890).toFixed(2) в JS даёт неверный результат (превышение безопасного целого), а в (0.1).toFixed-подобном округлении таятся ловушки плавающей точки. formatStatisticValue из core/statistic закрывает эти ловушки в общем слое один раз для всех платформ.
Когда использовать
Заголовок раздела «Когда использовать»- При реализации
LhStatisticна каждой платформе: цифры приборных панелей, сводки отчётов, отображение степени выполнения. - Сценарии форматирования произвольного числа по схеме «фиксированное число десятичных знаков + разделитель разрядов» — можно вызывать
formatStatisticValueнапрямую, даже без компонента. - Не следует использовать: символы валют, пересчёт единиц, форматирование по часовым поясам — это задачи бизнес-слоя; для дат используйте
core/shared/date.
import { formatStatisticValue, getStatisticClassNames } from '@lh-ui/share/core/statistic'import type { LhStatisticState } from '@lh-ui/share/core/statistic'Замысел
Заголовок раздела «Замысел»Три рубежа точности в formatStatisticValue:
- Некорректный вход не выбрасывает исключение: NaN / Infinity возвращаются как
String(value), мы не пытаемся форматировать «то, что не числом». - Очистка precision:
toFixed(101)выбрасывает RangeError, поэтому здесь precision сначала проходит черезsafePrecisionизshared/sanitizeи приводится к целому в[0, 100]. Этим рубежом пользуется иinput-number(см. input-number). - Сверхбольшие целые идут по строковому пути: когда целая часть превышает
Number.MAX_SAFE_INTEGER, полного преобразования в Number не происходит вообще — округление делается десятичным переносом по строкам (внутреннийincrementDigits), а группировка — нарезкой строк (formatBigString). Это единственный способ гарантировать, что99999999999999999999отформатируется правильно.
Таблица функций
Заголовок раздела «Таблица функций»| Функция | Сигнатура | Возврат | Назначение |
|---|---|---|---|
formatStatisticValue |
(value: number | string, state: Pick<LhStatisticState, 'precision' | 'separator'>) => string |
форматированная строка | точность + разделитель разрядов |
getStatisticClassNames |
(prefixCls?: string) => string[] |
массив классов | класс контейнера, можно заменить префикс |
Детали поведения:
| Вход | Выход | Путь |
|---|---|---|
1234567.891, { precision: 2, separator: ',' } |
'1,234,567.89' |
toFixed + группировка |
1234567.8, { precision: 0, separator: '' } |
'1234568' |
без разделителя |
'99999999999999999999', { precision: 0, separator: ',' } |
'99,999,999,999,999,999,999' |
строковый путь |
NaN, любой |
'NaN' |
вернуть как есть |
'abc', любой |
'abc' |
Number('abc') равно NaN |
Разделитель используется только для группировки целой части, а десятичная точка фиксирована как . (если платформам нужна локализованная десятичная точка при отображении, замену делает UI-слой).
Определения типов
Заголовок раздела «Определения типов»export interface LhStatisticState { precision: number // количество десятичных знаков (через safePrecision приводится к [0, 100]) separator: string // разделитель разрядов; пустая строка означает без группировки}Доступность
Заголовок раздела «Доступность»core/statistic не выводит пакет aria-атрибутов. Ключевые моменты доступности статистических значений лежат в UI-слое:
- Само число читается скринридером как обычный текст, но разделитель-запятая будет прочитан как «запятая» (например, «1,234,567» читается как «один запятая двести тридцать четыре…»). Всему числовому блоку следует давать
aria-labelс разговорным представлением («один миллион двести тридцать четыре тысячи пятьсот шестьдесят семь» или поразрядно «1 2 3 4 5 6 7»). - Анимация изменения значения (прокрутка к целевому числу) чисто визуальна и не несёт информации; если в процессе анимации число нечитаемо, следует держать старый aria-label до её завершения.
Примеры использования
Заголовок раздела «Примеры использования»import { formatStatisticValue } from '@lh-ui/share/core/statistic'
formatStatisticValue(9876543.21, { precision: 1, separator: ' ' })// '9 876 543.2'
formatStatisticValue(0.1 + 0.2, { precision: 2, separator: '' })// '0.30' (а не часть от 0.30000000000000004)
formatStatisticValue('12345678901234567890', { precision: 0, separator: ',' })// '12,345,678,901,234,567,890'<!-- Vue3 --><div :class="getStatisticClassNames()"> <span v-if="prefix" class="lh-statistic__prefix">{{ prefix }}</span> <span class="lh-statistic__content"> <span class="lh-statistic__title">{{ title }}</span> <span class="lh-statistic__value" :aria-label="ariaLabel"> {{ formatStatisticValue(value, { precision, separator }) }} </span> </span> <span v-if="suffix" class="lh-statistic__suffix">{{ suffix }}</span></div>// Reactconst text = formatStatisticValue(value, { precision, separator })return ( <div className="lh-statistic"> <span className="lh-statistic__content"> <span className="lh-statistic__title">{title}</span> <span className="lh-statistic__value" aria-label={spoken}>{text}</span> </span> </div>)// uniapp: на выходе чистая строка, платформенных различий нет;// анимация на каждой платформе использует собственное решение прокруткиСтили и токены
Заголовок раздела «Стили и токены»| Класс | Семантика |
|---|---|
.lh-statistic |
базовый класс: раскладка |
.lh-statistic__title |
заголовок (вторичный цвет текста, мелкий шрифт) |
.lh-statistic__content |
область содержимого (заголовок + значение по вертикали) |
.lh-statistic__value |
значение (основной цвет текста, крупный шрифт, моноширные цифры font-variant-numeric: tabular-nums) |
.lh-statistic__prefix / .lh-statistic__suffix |
префикс/суффикс (например, ¥, %) |
Шрифт чисел идёт через токен --lh-font-family-numeric (если есть), что гарантирует выравнивание ширины цифр.
Замечания
Заголовок раздела «Замечания»- Верхний предел precision — 100: превышение усекается
safePrecision, а не выбрасывает исключение; отрицательный precision приводится к 0. - Семантика строкового входа:
formatStatisticValue('123', ...)сначала пытается выполнитьNumber('123')и при успехе идёт по числовому пути;'abc'же возвращается как есть. Сверхбольшое целое обязательно нужно передавать строкой — числовой литерал99999999999999999999в исходнике JS уже теряет точность, и core не сможет это исправить. - Не пишите в UI-слое собственное форматирование через
toLocaleString: оно зависит от локали во время выполнения, и на разных платформах результаты могут не совпадать; используйте единыйformatStatisticValue. - Параметр
prefixClsуgetStatisticClassNamesпозволяет заменить префикс (по умолчаниюlh-statistic) — для сценариев, когда платформе нужно сосуществовать с существующими классами.
@lh-ui/share/core/statistic → formatStatisticValue( )(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue