跳至內容

d3-format

是否曾注意到 JavaScript 有時候不會以您預期的方式顯示數字?例如,您嘗試使用簡單迴圈列印十分位數

js
for (let i = 0; i < 10; ++i) {
  console.log(0.1 * i);
}

而您得到的是

0
0.1
0.2
0.30000000000000004
0.4
0.5
0.6000000000000001
0.7000000000000001
0.8
0.9

歡迎使用 二進制浮點數! ಠ_ಠ

然而,捨入誤差並非自訂數字格式化的唯一原因。數字表格應以一致的格式化進行比較;上述範例中,0.0 會比 0 更佳。大數字應分組數字(例如 42,000)或使用科學或公制記號(4.2e+4、42k)。貨幣應具有固定的精度($3.50)。報告的數值結果應四捨五入至有效數字(4021 變成 4000)。數字格式應適應讀者的語言環境(42.000,00 或 42,000.00)。清單可以繼續列下去。

d3-format 的目的是針對人類閱讀格式化數字,其範例是 Python 3 的 格式規範迷你語言 (PEP 3101)。重新檢視上面的範例

js
const f = d3.format(".1f");
for (let i = 0; i < 10; ++i) {
  console.log(f(0.1 * i));
}

現在您會得到這個

0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9

但 d3-format 遠遠不只是 number.toFixed 的別名!更多範例

js
d3.format(".0%")(0.123) // rounded percentage, "12%"
js
d3.format("($.2f")(-3.5) // localized fixed-point currency, "(£3.50)"
js
d3.format("+20")(42) // space-filled and signed, "                 +42"
js
d3.format(".^20")(42) // dot-filled and centered, ".........42........."
js
d3.format(".2s")(42e6) // SI-prefix with two significant digits, "42M"
js
d3.format("#x")(48879) // prefixed lowercase hexadecimal, "0xbeef"
js
d3.format(",.2r")(4223) // grouped thousands with two significant digits, "4,200"

請參閱 locale.format 以取得詳細規格,並嘗試對上述格式執行 d3.formatSpecifier 以解碼其含義。

另請參閱 number.toLocaleString

format(specifier)

js
const f = d3.format(".2f");

原始檔 · locale.format預設地區設定 的別名。

formatPrefix(specifier, value)

js
const f = d3.formatPrefix(",.0", 1e-6);

原始檔 · locale.formatPrefix預設地區設定 的別名。

formatLocale(definition)

js
const enUs = d3.formatLocale({
  thousands: ",",
  grouping: [3],
  currency: ["$", ""]
});

原始檔 · 傳回指定 definitionlocale 物件,其方法有 locale.formatlocale.formatPrefixdefinition 必須包含下列屬性

  • decimal - 小數點 (例如,".")。
  • thousands - 群組分隔符號 (例如,",")。
  • grouping - 群組大小的陣列 (例如,[3]),依需要循環。
  • currency - 貨幣字首和字尾 (例如,["$", ""])。
  • numerals - 選擇性;用於取代數字 0-9 的十個字串的陣列。
  • percent - 選擇性;百分比符號 (預設為 "%")。
  • minus - 選擇性;負號 (預設為 "−")。
  • nan - 選擇性;非數字值 (預設為 "NaN")。

請注意,thousands 屬性是一個錯誤的命名,因為群組定義允許千位數以外的群組。

formatDefaultLocale(definition)

js
const enUs = d3.formatDefaultLocale({
  thousands: ",",
  grouping: [3],
  currency: ["$", ""]
});

原始檔 · 等同於 d3.formatLocale,但它也會將 d3.formatd3.formatPrefix 重新定義為新地區設定的 locale.formatlocale.formatPrefix。如果您未設定預設地區設定,它會預設為 美國英語

locale.format(specifier)

js
const f = d3.format(".2f");

來源 · 傳回給定字串 specifier 的新格式函式。傳回的函式將數字作為唯一引數,並傳回表示已格式化數字的字串。specifier 的一般形式為

[​[fill]align][sign][symbol][0][width][,][.precision][~][type]

fill 可以是任何字元。fill 字元的出現由其後的 align 字元表示,它必須是下列其中一個

  • > - 強制欄位在可用空間中靠右對齊。(預設行為)。
  • < - 強制欄位在可用空間中靠左對齊。
  • ^ - 強制欄位在可用空間中置中。
  • = - 類似 >,但任何符號和符號在任何填補的左側。

sign 可以是

  • - - 零或正數為無,負數為負號。(預設行為)。
  • + - 零或正數為正號,負數為負號。
  • ( - 零或正數為無,負數為括號。
  •  (空白) - 零或正數為空白,負數為負號。

symbol 可以是

  • $ - 根據 locale 定義套用貨幣符號。
  • # - 對於二進位、八進位或十六進位表示法,分別加上前置詞 0b0o0x

zero (0) 選項啟用零填補;這會隱含地將 fill 設為 0,並將 align 設為 =width 定義欄位的最小寬度;如果未指定,則寬度將由內容決定。comma (,) 選項啟用群組分隔符號的使用,例如千位分隔號。

根據類型精度表示小數點後面的位數(類型f%),或有效數字的位數(類型egrsp)。如果未指定精度,則除了類型(無)預設為 12 外,所有類型預設為 6。對於整數格式(類型bodxX)和字元資料(類型c),會忽略精度。請參閱precisionFixedprecisionRound以取得選擇適當精度的說明。

~選項會修剪所有格式類型中不重要的尾數零。這最常與類型res%一起使用。例如

js
d3.format("s")(1500) // "1.50000k"
js
d3.format("~s")(1500) // "1.5k"

可用的類型值為

  • e - 指數符號。
  • f - 定點符號。
  • g - 十進位或指數符號,四捨五入為有效數字。
  • r - 十進位符號,四捨五入為有效數字。
  • s - 帶有SI 前綴的十進位符號,四捨五入為有效數字。
  • % - 乘以 100,然後使用百分比符號表示十進位符號。
  • p - 乘以 100,四捨五入為有效數字,然後使用百分比符號表示十進位符號。
  • b - 二進位符號,四捨五入為整數。
  • o - 八進位符號,四捨五入為整數。
  • d - 十進位符號,四捨五入為整數。
  • x - 十六進位符號,使用小寫字母,四捨五入為整數。
  • X - 十六進位符號,使用大寫字母,四捨五入為整數。
  • c - 字元資料,用於文字字串。

類型(無)也支援作為~g的簡寫(預設精度為 12,而非 6),而類型n,g的簡寫。對於gn(無)類型,如果結果字串的精度或位數較少,則使用十進位符號;否則,使用指數符號。例如

js
d3.format(".2")(42) // "42"
js
d3.format(".2")(4.2) // "4.2"
js
d3.format(".1")(42) // "4e+1"
js
d3.format(".1")(4.2) // "4"

locale.formatPrefix(specifier, value)

js
const f = d3.formatPrefix(",.0", 1e-6);

原始碼 · 等同於 locale.format,但回傳的函式會在以固定小數點符號格式化之前,將數值轉換為指定的數值參考的適當 國際單位制詞頭 的單位。支援下列詞頭

  • y - 微微,10⁻²⁴
  • z - 介微微,10⁻²¹
  • a - 阿托,10⁻¹⁸
  • f - 飛,10⁻¹⁵
  • p - 皮,10⁻¹²
  • n - 奈,10⁻⁹
  • µ - 微,10⁻⁶
  • m - 毫,10⁻³
  • (無) - 10⁰
  • k - 千,10³
  • M - 百萬,10⁶
  • G - 十億,10⁹
  • T - 兆,10¹²
  • P - 拍,10¹⁵
  • E - 艾,10¹⁸
  • Z - 澤,10²¹
  • Y - 堯,10²⁴

與使用 s 格式類型的 locale.format 不同,此方法回傳的格式化器具有固定的國際單位制詞頭,而不是針對每個數字動態計算詞頭。此外,給定 說明符精度表示小數點後方的數字位數(與 f 固定小數點符號相同),而不是有效數字的位數。例如

js
const f = d3.formatPrefix(",.0", 1e-6);
f(0.00042); // "420µ"
f(0.0042); // "4,200µ"

此方法在以相同單位格式化多個數字以利於比較時很有用。請參閱 precisionPrefix 以取得選擇適當精度的說明。

formatSpecifier(說明符)

js
d3.formatSpecifier(".1f")

原始碼 · 分析指定的 說明符,回傳一個物件,其中包含對應於 格式說明微語言 的公開欄位,以及一個重建說明符的 toString 方法。例如,formatSpecifier("s") 會回傳

js
FormatSpecifier {
  "fill": " ",
  "align": ">",
  "sign": "-",
  "symbol": "",
  "zero": false,
  "width": undefined,
  "comma": false,
  "precision": undefined,
  "trim": false,
  "type": "s"
}

此方法有助於了解格式說明符的分析方式,以及衍生新的說明符。例如,您可以使用 precisionFixed 根據您要格式化的數字計算適當的精度,然後建立新的格式

js
const s = d3.formatSpecifier("f");
s.precision = d3.precisionFixed(0.01);
const f = d3.format(s);
f(42); // "42.00";

new d3.FormatSpecifier(說明符)

js
new d3.FormatSpecifier({type: "f", precision: 1})

原始碼 · 給定指定的 說明符物件,回傳一個物件,其中包含對應於 格式說明微語言 的公開欄位,以及一個重建說明符的 toString 方法。例如,new FormatSpecifier({type: "s"}) 會回傳

js
FormatSpecifier {
  "fill": " ",
  "align": ">",
  "sign": "-",
  "symbol": "",
  "zero": false,
  "width": undefined,
  "comma": false,
  "precision": undefined,
  "trim": false,
  "type": "s"
}

precisionFixed(step)

js
d3.precisionFixed(0.01) // 2

來源 · 給定指定的數值 step 值,傳回固定小數點表示法的建議小數位數。step 表示將格式化的值之間的最小絕對差。(這假設要格式化的值也是 step 的倍數。)例如,給定數字 1、1.5 和 2,step 應該是 0.5,建議的小數位數為 1

js
const p = d3.precisionFixed(0.5);
const f = d3.format("." + p + "f");
f(1);   // "1.0"
f(1.5); // "1.5"
f(2);   // "2.0"

而對於數字 1、2 和 3,step 應該是 1,建議的小數位數為 0

js
const p = d3.precisionFixed(1);
const f = d3.format("." + p + "f");
f(1); // "1"
f(2); // "2"
f(3); // "3"

注意:對於 % 格式類型,減去 2

js
const p = Math.max(0, d3.precisionFixed(0.05) - 2);
const f = d3.format("." + p + "%");
f(0.45); // "45%"
f(0.50); // "50%"
f(0.55); // "55%"

precisionPrefix(step, value)

js
d3.precisionPrefix(1e5, 1.3e6) // 1

來源 · 給定指定的數值 step 和參考 value,傳回建議的小數位數,以搭配 locale.formatPrefix 使用。step 表示將格式化的值之間的最小絕對差,而 value 決定將使用哪個 SI 前綴。(這假設要格式化的值也是 step 的倍數。)例如,給定數字 1.1e6、1.2e6 和 1.3e6,step 應該是 1e5,value 可以是 1.3e6,建議的小數位數為 1

js
const p = d3.precisionPrefix(1e5, 1.3e6);
const f = d3.formatPrefix("." + p, 1.3e6);
f(1.1e6); // "1.1M"
f(1.2e6); // "1.2M"
f(1.3e6); // "1.3M"

precisionRound(step, max)

js
d3.precisionRound(0.01, 1.01) // 3

來源 · 給定指定的數值 stepmax 值,傳回建議的小數位數,以用於四捨五入到有效數字的格式類型。step 表示將格式化的值之間的最小絕對差,而 max 表示將格式化的最大絕對值。(這假設要格式化的值也是 step 的倍數。)例如,給定數字 0.99、1.0 和 1.01,step 應該是 0.01,max 應該是 1.01,建議的小數位數為 3

js
const p = d3.precisionRound(0.01, 1.01);
const f = d3.format("." + p + "r");
f(0.99); // "0.990"
f(1.0);  // "1.00"
f(1.01); // "1.01"

而對於數字 0.9、1.0 和 1.1,step 應該是 0.1,max 應該是 1.1,建議的小數位數為 2

js
const p = d3.precisionRound(0.1, 1.1);
const f = d3.format("." + p + "r");
f(0.9); // "0.90"
f(1.0); // "1.0"
f(1.1); // "1.1"

注意:對於 e 格式類型,減去 1

js
const p = Math.max(0, d3.precisionRound(0.01, 1.01) - 1);
const f = d3.format("." + p + "e");
f(0.01); // "1.00e-2"
f(1.01); // "1.01e+0"