使用SI代码绘制图形时,我们非常想要。我们的y轴值往往是大货币值。例如:$ 10,411,504,201.20
简而言之,至少在美国本土,这应该转化为10.4亿美元。
但是对于SI代码使用d3.format的's'类型,这将显示为$ 10.4G。对于某些语言环境而言这可能很有用,并且在处理基于计算机的值时很好(例如:处理器速度,内存......),但对于货币或其他非计算机类型的值,情况则不然。
有没有办法让特定于语言环境的功能类似于将数十亿转换为B而不是G等的SI代码......?
(我意识到这主要是一个SI代码的东西,并不是特定于D3,但因为我使用D3这似乎是最合适的标签。)
答案 0 :(得分:12)
我更喜欢覆盖d3.formatPrefix。然后你可以忘记在你的viz代码中替换字符串。只需在加载D3.js后立即执行以下代码。
// Change D3's SI prefix to more business friendly units
// K = thousands
// M = millions
// B = billions
// T = trillion
// P = quadrillion
// E = quintillion
// small decimals are handled with e-n formatting.
var d3_formatPrefixes = ["e-24","e-21","e-18","e-15","e-12","e-9","e-6","e-3","","K","M","B","T","P","E","Z","Y"].map(d3_formatPrefix);
// Override d3's formatPrefix function
d3.formatPrefix = function(value, precision) {
var i = 0;
if (value) {
if (value < 0) {
value *= -1;
}
if (precision) {
value = d3.round(value, d3_format_precision(value, precision));
}
i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3));
}
return d3_formatPrefixes[8 + i / 3];
};
function d3_formatPrefix(d, i) {
var k = Math.pow(10, Math.abs(8 - i) * 3);
return {
scale: i > 8 ? function(d) { return d / k; } : function(d) { return d * k; },
symbol: d
};
}
function d3_format_precision(x, p) {
return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1);
}
运行此代码后,尝试使用SI前缀格式化数字:
d3.format(".3s")(1234567890) // 1.23B
通过在对象中包含特定于语言环境的d3_formatPrefixes
值,然后选择与您需要的语言环境匹配的正确值,可以非常简单地扩充此代码以支持不同的语言环境。