statistic —— 統計数値
統計数値コンポーネントは「重要な数字」を表示します:DAU、売上、完了率。その中核のリスクはレイアウトではなく精度です:Number(12345678901234567890).toFixed(2) は JS では誤った結果になります(安全整数を超えるため)、(0.1).toFixed 系の丸めにも浮動小数点の罠があります。core/statistic の formatStatisticValue がこれらの穴を共有層で一度に埋め、3 端で共用します。
- 各端が
LhStatisticを実装する:ダッシュボードの数値、レポートサマリー、達成度の表示。 - 任意の数値を「固定小数位 + 桁区切り」でフォーマットしたいケース。コンポーネントを使わなくても直接
formatStatisticValueを呼べます。 - 使うべきでない:通貨記号、単位換算、タイムゾーンのフォーマット——これらは業務層の仕事です;日付のフォーマットは
core/shared/dateを使います。
インポート方法
Section titled “インポート方法”import { formatStatisticValue, getStatisticClassNames } from '@lh-ui/share/core/statistic'import type { LhStatisticState } from '@lh-ui/share/core/statistic'formatStatisticValue の 3 つの精度の防線:
- 不正な入力でエラーを投げない:NaN / Infinity はそのまま
String(value)を返し、「数でないもの」のフォーマットは試みません。 - precision のサニタイズ:
toFixed(101)は RangeError を投げるため、事前にshared/sanitizeのsafePrecisionで[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 // 桁区切り文字、空文字はグループ化しないことを示す}アクセシビリティ
Section titled “アクセシビリティ”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:純粋な文字列出力で端差分なし;アニメーションは各端のスクロール方案を使うスタイルとトークン
Section titled “スタイルとトークン”| クラス名 | 意味 |
|---|---|
.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を使わないでください:実行時の locale に影響され、3 端で一致しない可能性があります;一律にformatStatisticValueを使います。 getStatisticClassNamesのprefixClsパラメータはプレフィックスの変更を許可し(デフォルトはlh-statistic)、一部の端で既存のクラス名と共存する必要があるケースに使います。
@lh-ui/share/core/statistic → formatStatisticValue( )返回值
(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue