d3-format
有没有注意到JavaScript有时不会按你期望的方式显示数字?比如,你试着用一个简单的循环打印0.1:
for (var 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
欢迎来到binary floating point(二进制浮点数)!
然而舍入错误并不是定制数字格式的唯一原因。一个数字表应该格式一致以便比较;上面的情况中,0.0比0要好。当数值过大时应该有grouped digits(分位数)(如42,000)或者使用科学计数法,又或者使用metric notation(度量符号)(4.2e+4, 42k)。货币应该有固定精度($3.50)。报告的数值结果应舍入到有效数字(4021变为4000)。数字格式应适合读者所在的地区(42.000,00 或 42,000.00)。
格式化数字是d3-format的目的,它仿照了Python 3的format specification mini-language(PEP 3101)。重温上面的的例子:
var f = d3.format(".1f");
for (var 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的别名!在举个例子:
d3.format(".0%")(0.123); // rounded percentage, "12%"
d3.format("($.2f")(-3.5); // localized fixed-point currency, "(£3.50)"
d3.format("+20")(42); // space-filled and signed, " +42"
d3.format(".^20")(42); // dot-filled and centered, ".........42........."
d3.format(".2s")(42e6); // SI-prefix with two significant digits, "42M"
d3.format("#x")(48879); // prefixed lowercase hexadecimal, "0xbeef"
d3.format(",.2r")(4223); // grouped thousands with two significant digits, "4,200"
另请参阅locale.format查看详细说明,并尝试对上面的例子使用d3.formatSpecifier,查看其结果。
Installing
如果你使用npm,请键入npm install d3-format。否则,请下载最新版本。你也可以直接从d3js.org加载,作为standalone library(独立库)或D3 4.0的一部分来使用。支持AMD,CommonJS和vanilla环境。在vanilla环境下,会输出一个全局的d3
:
<script src="https://d3js.org/d3-format.v1.min.js"></script>
<script>
var format = d3.format(".2s");
</script>
本地文件托管在unpkg上,可以使用d3.json加载。例如,将默认语言设置为俄语:
d3.json("https://unpkg.com/d3-format@1/locale/ru-RU.json", function(error, locale) {
if (error) throw error;
d3.formatDefaultLocale(locale);
var format = d3.format("$,");
console.log(format(1234.56)); // 1 234,56 руб.
});
API Reference
d3.format(specifier)
d3.formatPrefix(specifier, value)
默认locale下locale.formatPrefix的别名。
locale.format(specifier)
为给定specifier返回一个格式化函数。返回的函数以一个数字作为唯一参数,返回一个表示格式化数字的字符串。specifier的通用格式为:
[[fill]align][sign][symbol][0][width][,][.precision][type]
fill可以是任意字符,fill的存在是由其后面align标识的,align必须是下列之一:
>
- 强制字段在可用空间中右对齐。(默认行为)<
- 强制字段在可用空间中左对齐。^
- 强制字段在可用空间中居中对齐。=
- 和>
类似,只是在字段左侧任意间距下可以有任意符号。
sign可以是:
-
- 对于0和正数不做处理,对于负数则添加减号。(默认行为)+
- 对于0和正数添加加号,对于负数则添加减号。(
- 对于0和正数不做处理,对于负数则添加圆括号。
symbol可以是:
$
- 根据定义地区添加货币符号。#
- 为二进制、八进制或十六进制分别添加0b
,0o
,或0x
前缀。
zero(0
)表示间距为0;这种隐式设置将fill设为0
,algin设为=
。width定义最小字段宽度;如果未指定,则宽度将由内容决定。逗号(,
)表示使用分组符,如千位分隔符。
根据不同的type,precision可以表示小数点后的位数(类型为f
或者%
),或者有效数字的位数(类型为`,
e,
g,
r,
s和
p)。如果不指定_precision_,则所有类型的精度都默认为6,而
(空)为12。整数格式(类型为
b,
o,
d,
x,
X和
c`)的精度会被忽略。另请参阅precisionFixed和precisionRound以挑选合适的精度。
可用的type有:
e
- 指数。f
- 不动点。g
- 十进制数或指数,舍入为有效数字。r
- 十进制数,舍入为有效数字。s
- 带有SI prefix(SI前缀)的十进制数,舍入为有效数字。%
- 乘以100,带有百分号的十进制数。p
- 乘以100,舍入为有效数字,带有百分号的十进制数。b
- 二进制数,舍入为整数。o
- 八进制数,舍入为整数。d
- 十进制数,舍入为整数。x
- 十六进制数,使用小写字母,舍入为整数。X
- 十六进制数,使用大写字母,舍入为整数。c
- 在打印之前将整数转换为对应的unicode字符。-
`\(空\) - 和
g`类似,但是会去掉尾随零
类型n
也支持简写为,g
。为g
、n
和
(空)的的类型,如果结果字符串具有精度或位数较少,则使用十进制计数法;否则,使用指数计数法。例如:
d3.format(".2")(42); // "42"
d3.format(".2")(4.2); // "4.2"
d3.format(".1")(42); // "4e+1"
d3.format(".1")(4.2); // "4"
locale.formatPrefix(specifier, value)
相当于locale.format,除了在使用定点计数法进行格式化前,返回的函数会将value转换为有适当SI prefix(SI前缀)的组合。支持以下前缀:
y
- yocto, 10⁻²⁴z
- zepto, 10⁻²¹a
- atto, 10⁻¹⁸f
- femto, 10⁻¹⁵p
- pico, 10⁻¹²n
- nano, 10⁻⁹µ
- micro, 10⁻⁶m
- milli, 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²⁴
与locale.format格式化类型为s
时不同的是,此方法返回的SI prefix是一致的,而不是为每个数字计算前缀。给定specifier的precision表示的是小数点前的数字个数(和f
定点计数法一样),而不是有效数字的位数。例如:
var f = d3.formatPrefix(",.0", 1e-6);
f(0.00042); // "420µ"
f(0.0042); // "4,200µ"
当在同一个units中格式化多个数字以便于比较时,此方法非常有用。另请参阅precisionPrefix挑选合适的精度,另请参阅bl.ocks.org/9764126查看示例。
d3.formatSpecifier(specifier)
解析给定的specifier,返回一个符合format specification mini-language的对象,同时会调用toString方法重构此specifier。例如,formatSpecifier("s")
会返回:
{
"fill": " ",
"align": ">",
"sign": "-",
"symbol": "",
"zero": false,
"width": undefined,
"comma": false,
"precision": 6,
"type": "s"
}
此方法用于了解格式化specifier是如何解析并生成新的specifier的。例如,你可以根据你想使用的precisionFixed为你的数字计算一个合适的精度,然后创建一个新的格式:
var s = d3.formatSpecifier("f");
s.precision = precisionFixed(0.01);
var f = d3.format(s);
f(42); // "42.00";
d3.precisionFixed(step)
根据给定的定点计数法表示的step返回一个推荐的十进制精度。step表示将被格式化的数值间的最小绝对差(这里假设要格式化的值也是step的倍数)。例如,给定数字1、1.5和2,则step就是0.5,建议精度就是1:
var p = d3.precisionFixed(0.5),
f = d3.format("." + p + "f");
f(1); // "1.0"
f(1.5); // "1.5"
f(2); // "2.0"
然而对于数字1、2和3,step则为1,建议精度为0:
var p = d3.precisionFixed(1),
f = d3.format("." + p + "f");
f(1); // "1"
f(2); // "2"
f(3); // "3"
注意:对于%
格式类型,减去2:
var p = Math.max(0, d3.precisionFixed(0.05) - 2),
f = d3.format("." + p + "%");
f(0.45); // "45%"
f(0.50); // "50%"
f(0.55); // "55%"
d3.precisionPrefix(step, value)
与locale.formatPrefix一同根据给定的step和value返回一个推荐的十进制精度。step表示将被格式化的数值间的最小绝对差,value决定了将使用哪种SI prefix(SI前缀)(这里假设要格式化的值也是step的倍数)。例如,给定数字1.1e6,1.2e6,和1.3e6,则step为1e5,value为1.3e6,建议精度为1:
var p = d3.precisionPrefix(1e5, 1.3e6),
f = d3.formatPrefix("." + p, 1.3e6);
f(1.1e6); // "1.1M"
f(1.2e6); // "1.2M"
f(1.3e6); // "1.3M"
d3.precisionRound(step, max)
根据给定的step和max为舍入到有效数字的格式类型返回一个推荐的十进制精度。step表示将被格式化的数值间的最小绝对差,max表示将被格式化的最大绝对值(这里假设要格式化的值也是step的倍数)。例如,给定数字0.99、1和1.01,则step为0.01,max为1.01,建议精度为3:
var p = d3.precisionRound(0.01, 1.01),
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,建议精度,为0:
var p = d3.precisionRound(0.1, 1.1),
f = d3.format("." + p + "r");
f(0.9); // "0.90"
f(1.0); // "1.0"
f(1.1); // "1.1"
注意:对于e
格式类型,减去1:
var p = Math.max(0, d3.precisionRound(0.01, 1.01) - 1),
f = d3.format("." + p + "e");
f(0.01); // "1.00e-2"
f(1.01); // "1.01e+0"
Locales
d3.formatLocale(definition)
根据给定的definition使用locale.format和locale.formatPrefix方法返回一个locale对象。definition必须具有以下属性:
decimal
- 小数点(如:“.”
)。thousands
- 组分隔符 (如:","
)。grouping
- 每个分组数组的长度(如:[3]
),需要时会循环。currency
- 货币前缀和后缀(如:[“$”,“”]
)。numerals
- optional; an array of ten strings to replace the numerals 0-9.percent
- 可选,百分比后缀(默认为“%”
)。
注意:属性名thousands是不恰当的,grouping定义的是分组方式,不是thousands。
d3.formatDefaultLocale(definition)
相当于d3.formatLocale,除了它将d3.format和d3.formatPrefix重新定义成适合当地语言环境的locale.format和locale.formatPrefix。如果不设置默认语言环境,则默认为U.S. English(美国英语)。