Skip to content

d3-format

你是否注意到 JavaScript 有时显示的数字与你预期的并不相符?例如,你尝试使用一个简单的循环打印十分之一:

¥Ever noticed how sometimes JavaScript doesn’t display numbers the way you expect? Like, you tried to print tenths with a simple loop:

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

你得到了这个:

¥And you got this:

0
0.1
0.2
0.30000000000000004
0.4
0.5
0.6000000000000001
0.7000000000000001
0.8
0.9

欢迎使用 二进制浮点数!ಠ_ಠ

¥Welcome to binary floating point! ಠ_ಠ

然而,舍入误差并非自定义数字格式的唯一原因。数字表应格式一致以便进行比较;以上,0.0 优于 0。大数应该使用分组数字(例如 42,000)或采用科学计数法或公制计数法(4.2e+4,42k)。货币应具有固定精度(3.50 美元)。报告的数值结果应四舍五入为有效数字(4021 变为 4000)。数字格式应与读者的语言环境相符(例如 42.000,00 或 42,000.00)。等等。

¥Yet rounding error is not the only reason to customize number formatting. A table of numbers should be formatted consistently for comparison; above, 0.0 would be better than 0. Large numbers should have grouped digits (e.g., 42,000) or be in scientific or metric notation (4.2e+4, 42k). Currencies should have fixed precision ($3.50). Reported numerical results should be rounded to significant digits (4021 becomes 4000). Number formats should appropriate to the reader’s locale (42.000,00 or 42,000.00). The list goes on.

d3-format 的目的是格式化数字以供人类理解,它以 Python 3 的 格式规范微语言 (PEP 3101) 为蓝本。回顾上面的例子:

¥Formatting numbers for human consumption is the purpose of d3-format, which is modeled after Python 3’s format specification mini-language (PEP 3101). Revisiting the example above:

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

现在你得到这个:

¥Now you get this:

0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9

但 d3-format 不仅仅是 number.toFixed 的别名!一些更多示例:

¥But d3-format is much more than an alias for number.toFixed! A few more examples:

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 来解码它们的含义。

¥See locale.format for a detailed specification, and try running d3.formatSpecifier on the above formats to decode their meaning.

另请参阅 number.toLocaleString

¥Also see number.toLocaleString.

format(specifier)

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

源代码 · 默认语言环境locale.format 的别名。

¥Source · An alias for locale.format on the default locale.

formatPrefix(specifier, value)

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

源代码 · 默认语言环境locale.formatPrefix 的别名。

¥Source · An alias for locale.formatPrefix on the default locale.

formatLocale(definition)

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

源代码 · 返回一个指定定义的语言环境对象,该对象包含 locale.formatlocale.formatPrefix 方法。定义必须包含以下属性:

¥Source · Returns a locale object for the specified definition with locale.format and locale.formatPrefix methods. The definition must include the following properties:

  • decimal - 小数点(例如 ".")。

    ¥decimal - the decimal point (e.g., ".").

  • thousands - 组分隔符(例如,",")。

    ¥thousands - the group separator (e.g., ",").

  • grouping - 组大小数组(例如 [3]),根据需要循环。

    ¥grouping - the array of group sizes (e.g., [3]), cycled as needed.

  • currency - 货币前缀和后缀(例如 ["$", ""])。

    ¥currency - the currency prefix and suffix (e.g., ["$", ""]).

  • numerals - 可选;十个字符串数组,用于替换数字 0-9。

    ¥numerals - optional; an array of ten strings to replace the numerals 0-9.

  • percent - 可选;百分号(默认为 "%")。

    ¥percent - optional; the percent sign (defaults to "%").

  • minus - 可选;减号(默认为 "−")。

    ¥minus - optional; the minus sign (defaults to "−").

  • nan - 可选;非数字值(默认为 "NaN")。

    ¥nan - optional; the not-a-number value (defaults "NaN").

请注意,千位属性用词不当,因为分组定义允许千位以外的组。

¥Note that the thousands property is a misnomer, as the grouping definition allows groups other than thousands.

formatDefaultLocale(definition)

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

源代码 · 等同于 d3.formatLocale,但它还将 d3.formatd3.formatPrefix 重新定义为新语言环境的 locale.formatlocale.formatPrefix。如果你未设置默认语言环境,则默认为 U.S.英语

¥Source · Equivalent to d3.formatLocale, except it also redefines d3.format and d3.formatPrefix to the new locale’s locale.format and locale.formatPrefix. If you do not set a default locale, it defaults to U.S. English.

locale.format(specifier) {#locale_format}

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

源代码 · 返回给定字符串说明符的新格式化函数。返回的函数以数字作为唯一参数,并返回一个表示格式化数字的字符串。说明符的一般形式为:

¥Source · Returns a new format function for the given string specifier. The returned function takes a number as the only argument, and returns a string representing the formatted number. The general form of a specifier is:

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

填充可以是任何字符。填充字符的存在由其后的对齐字符表示,该对齐字符必须是以下之一:

¥The fill can be any character. The presence of a fill character is signaled by the align character following it, which must be one of the following:

  • > - 强制场场在可用空间内右对齐。(默认行为)。

    ¥> - Forces the field to be right-aligned within the available space. (Default behavior).

  • < - 强制场场在可用空间内左对齐。

    ¥< - Forces the field to be left-aligned within the available space.

  • ^ - 强制场场在可用空间内居中。

    ¥^ - Forces the field to be centered within the available space.

  • = - 类似 >,但在任何填充左侧可以添加任何符号和符号。

    ¥= - like >, but with any sign and symbol to the left of any padding.

符号可以是:

¥The sign can be:

  • - - 零或正数不显示,负数显示负号。(默认行为。)

    ¥- - nothing for zero or positive and a minus sign for negative. (Default behavior.)

  • + - 一个加号表示零或正数,一个减号表示负数。

    ¥+ - a plus sign for zero or positive and a minus sign for negative.

  • ( - 零或正数不显示,负数用括号括起来。

    ¥( - nothing for zero or positive and parentheses for negative.

  • (空格) - 零或正数的空间,以及负数的负号。

    ¥  (space) - a space for zero or positive and a minus sign for negative.

符号可以是:

¥The symbol can be:

  • $ - 根据语言环境定义应用货币符号。

    ¥$ - apply currency symbols per the locale definition.

  • # - 对于二进制、八进制或十六进制表示法,分别以 0b0o0x 为前缀。

    ¥# - for binary, octal, or hexadecimal notation, prefix by 0b, 0o, or 0x, respectively.

零 (0) 选项启用零填充;这隐式地将填充设置为 0,并将对齐设置为 =。宽度定义最小字段宽度;如果未指定,则宽度将由内容决定。逗号 (,) 选项允许使用组分隔符,例如用逗号表示千位。

¥The zero (0) option enables zero-padding; this implicitly sets fill to 0 and align to =. The width defines the minimum field width; if not specified, then the width will be determined by the content. The comma (,) option enables the use of a group separator, such as a comma for thousands.

根据类型,精度表示小数点后的位数(类型 f%),或有效位数(类型 egrsp)。如果未指定精度,则除 (无)之外的所有类型的精度默认为 6, 的精度默认为 12。整数格式(类型 bodxX)和字符数据(类型 c)的精度将被忽略。有关选择合适精度的帮助,请参阅 precisionFixedprecisionRound

¥Depending on the type, the precision either indicates the number of digits that follow the decimal point (types f and %), or the number of significant digits (types , e, g, r, s and p). If the precision is not specified, it defaults to 6 for all types except (none), which defaults to 12. Precision is ignored for integer formats (types b, o, d, x, and X) and character data (type c). See precisionFixed and precisionRound for help picking an appropriate precision.

~ 选项会修剪所有格式类型中不重要的尾随零。此方法最常与类型 res% 结合使用。例如:

¥The ~ option trims insignificant trailing zeros across all format types. This is most commonly used in conjunction with types r, e, s and %. For example:

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

可用的类型值包括:

¥The available type values are:

  • e - 指数表示法。

    ¥e - exponent notation.

  • f - 定点符号。

    ¥f - fixed point notation.

  • g - 小数或指数表示法,四舍五入到有效数字。

    ¥g - either decimal or exponent notation, rounded to significant digits.

  • r - 以十进制表示法,四舍五入为有效数字。

    ¥r - decimal notation, rounded to significant digits.

  • s - 以 SI 前缀 结尾的十进制表示法,四舍五入为有效数字。

    ¥s - decimal notation with an SI prefix, rounded to significant digits.

  • % - 乘以 100,然后以百分号表示十进制数。

    ¥% - multiply by 100, and then decimal notation with a percent sign.

  • p - 乘以 100,四舍五入为有效数字,然后以百分号表示十进制数。

    ¥p - multiply by 100, round to significant digits, and then decimal notation with a percent sign.

  • b - 二进制表示法,四舍五入为整数。

    ¥b - binary notation, rounded to integer.

  • o - 八进制表示法,四舍五入为整数。

    ¥o - octal notation, rounded to integer.

  • d - 以十进制表示法,四舍五入为整数。

    ¥d - decimal notation, rounded to integer.

  • x - 十六进制表示法,使用小写字母,四舍五入为整数。

    ¥x - hexadecimal notation, using lower-case letters, rounded to integer.

  • X - 十六进制表示法,使用大写字母,四舍五入为整数。

    ¥X - hexadecimal notation, using upper-case letters, rounded to integer.

  • c - 字符数据,用于文本字符串。

    ¥c - character data, for a string of text.

同时还支持 (none)类型作为 ~g 的简写(默认精度为 12 位,而不是 6 位),n 类型是 ,g 的简写。对于 gn(无)类型,如果生成的字符串具有精度或更少的数字,则使用十进制表示法;否则,使用指数表示法。例如:

¥The type (none) is also supported as shorthand for ~g (with a default precision of 12 instead of 6), and the type n is shorthand for ,g. For the g, n and (none) types, decimal notation is used if the resulting string would have precision or fewer digits; otherwise, exponent notation is used. For example:

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) {#locale_formatPrefix}

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

源代码 · 等同于 locale.format,但它返回的函数会将值转换为指定数值参考值的相应 SI 前缀 的单位,然后再以定点表示法进行格式化。支持以下前缀:

¥Source · Equivalent to locale.format, except the returned function will convert values to the units of the appropriate SI prefix for the specified numeric reference value before formatting in fixed point notation. The following prefixes are supported:

  • y - yocto, 10⁻²⁴

  • z - zepto, 10⁻²¹

  • a - atto,10⁻¹⁸

  • f - 飞秒级,10⁻¹⁵

    ¥f - femto, 10⁻¹⁵

  • p - pico,10⁻¹²

  • n - 纳米,10⁻⁹

    ¥n - nano, 10⁻⁹

  • µ - micro,10⁻⁶

  • m - milli,10⁻³

  • (无) - 10⁰

    ¥ (none) - 10⁰

  • k - kilo,10³

  • M - mega,10⁶

  • G - giga,10⁹

  • T - tera,10¹²

  • P - peta,10¹⁵

  • E - exa,10¹⁸

  • Z - zetta, 10²¹

  • Y - yotta, 10²⁴

Unlike locale.format with the s format type, this method returns a formatter with a consistent SI prefix, rather than computing the prefix dynamically for each number.此外,给定说明符的精度表示小数点后的位数(与 f 定点表示法相同),而不是有效位数。例如:

¥Unlike locale.format with the s format type, this method returns a formatter with a consistent SI prefix, rather than computing the prefix dynamically for each number. In addition, the precision for the given specifier represents the number of digits past the decimal point (as with f fixed point notation), not the number of significant digits. For example:

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

此方法在使用相同单位格式化多个数字以便于比较时非常有用。有关选择合适精度的帮助,请参阅 precisionPrefix

¥This method is useful when formatting multiple numbers in the same units for easy comparison. See precisionPrefix for help picking an appropriate precision.

formatSpecifier(specifier)

js
d3.formatSpecifier(".1f")

源代码 · 解析指定的说明符,返回一个对象,该对象包含与 格式规范微语言 对应的公开字段以及一个用于重建说明符的 toString 方法。例如,formatSpecifier("s") 返回:

¥Source · Parses the specified specifier, returning an object with exposed fields that correspond to the format specification mini-language and a toString method that reconstructs the specifier. For example, formatSpecifier("s") returns:

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

此方法有助于理解格式说明符的解析方式以及派生新的说明符。例如,你可以根据要使用 precisionFixed 格式化的数字计算适当的精度,然后创建新的格式:

¥This method is useful for understanding how format specifiers are parsed and for deriving new specifiers. For example, you might compute an appropriate precision based on the numbers you want to format using precisionFixed and then create a new format:

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

new d3.FormatSpecifier(specifier)

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

源代码 · 给定指定的说明符对象,返回一个对象,该对象包含与 格式规范微语言 对应的公开字段以及一个用于重建说明符的 toString 方法。例如,new FormatSpecifier({type: "s"}) 返回:

¥Source · Given the specified specifier object, returning an object with exposed fields that correspond to the format specification mini-language and a toString method that reconstructs the specifier. For example, new FormatSpecifier({type: "s"}) returns:

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 的倍数。)例如,给定数字 1、1.5 和 2,步长应为 0.5,建议精度为 1:

¥Source · Returns a suggested decimal precision for fixed point notation given the specified numeric step value. The step represents the minimum absolute difference between values that will be formatted. (This assumes that the values to be formatted are also multiples of step.) For example, given the numbers 1, 1.5, and 2, the step should be 0.5 and the suggested precision is 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,步长应为 1,建议精度为 0:

¥Whereas for the numbers 1, 2 and 3, the step should be 1 and the suggested precision is 0:

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

注意:对于 % 格式类型,减二:

¥Note: for the % format type, subtract two:

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

源代码 · 返回建议的小数精度,以便与 locale.formatPrefix 一起使用,并给出指定的数值步长和参考值。step 表示将被格式化的值之间的最小绝对差,value 决定将使用哪个 SI 前缀。(这假设要格式化的值也是 step 的倍数。)例如,给定数字 1.1e6、1.2e6 和 1.3e6,步长应为 1e5,值可以为 1.3e6,建议精度为 1:

¥Source · Returns a suggested decimal precision for use with locale.formatPrefix given the specified numeric step and reference value. The step represents the minimum absolute difference between values that will be formatted, and value determines which SI prefix will be used. (This assumes that the values to be formatted are also multiples of step.) For example, given the numbers 1.1e6, 1.2e6, and 1.3e6, the step should be 1e5, the value could be 1.3e6, and the suggested precision is 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

源代码 · 返回给定指定数值步长和最大值的四舍五入到有效数字的格式类型的建议小数精度。step 表示将被格式化的值之间的最小绝对差,max 表示将被格式化的最大绝对值。(这假设要格式化的值也是 step 的倍数。)例如,给定数字 0.99、1.0 和 1.01,步长应为 0.01,最大值应为 1.01,建议精度为 3:

¥Source · Returns a suggested decimal precision for format types that round to significant digits given the specified numeric step and max values. The step represents the minimum absolute difference between values that will be formatted, and the max represents the largest absolute value that will be formatted. (This assumes that the values to be formatted are also multiples of step.) For example, given the numbers 0.99, 1.0, and 1.01, the step should be 0.01, the max should be 1.01, and the suggested precision is 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,步长应为 0.1,最大值应为 1.1,建议精度为 2:

¥Whereas for the numbers 0.9, 1.0, and 1.1, the step should be 0.1, the max should be 1.1, and the suggested precision is 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 格式类型,减一:

¥Note: for the e format type, subtract one:

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"