首页 > 解决方案 > 更改 d3.format 用于“g”类型的表示法

问题描述

我们想要格式化一个数字,使得结果字符串的长度为 X(在我们的例子中它的长度为 3)。如果数字太小或太大,我们可以使用指数表示法,但是我们更喜欢在没有它的情况下显示数字。

这正是https://github.com/d3/d3-formatg的符号

但是,d3以某种方式决定输出数字何时以e符号表示。如果您在第一个非零数字前面放置超过 5 个零,它会选择e符号。我们想将其更改为较小的数字。

d3.format(".2g")(0.0000020852945934254138)
>> "0.0000021"
d3.format(".2g")(0.00000020852945934254138)
>> "2.1e-7"

有什么办法可以修改这种行为,以便我们可以获得不超过一定长度的字符串?

标签: javascriptd3.js

解决方案


这种情况下的决定不取决于 D3。

D3 显然是一个 JavaScript 库。在内部,d3.format使用Number.prototype.toPrecision()。我们可以在源代码中看到这一点:

export default {
    //...
    "g": function(x, p) { return x.toPrecision(p); },
    //...
}

因此,为了描述行为(即如何做出选择),我们必须查看Number.prototype.toPrecision(). 我们可以在§20.1.3.5找到它。这个问题最相关的部分是第 12.c 小节中的一个,注意-6那里:

20.1.3.5 Number.prototype.toPrecision(精度)

返回一个包含此 Number 值的字符串,该值以十进制指数表示法表示,有效数字小数点前一位,有效数字小数点后一位精度为 1 位,或以十进制固定表示法表示,有效数字精度高。如果精度未定义,请改为调用 ToString (7.1.12)。具体来说,执行以下步骤:

[...]

12.c。如果 e < –6 或 e ≥ p,则

[...]

七。返回 s、m、代码单元 0x0065(拉丁小写字母 E)、c 和 d 的串联。

正如我们所见,小于0.000001(即1e-6)的数字将使用指数表示法返回。

让我们检查一下:

console.log(d3.format("g")(0.000001))
<script src="https://d3js.org/d3.v5.min.js"></script>

正如我们所看到的,0.000001将被记录为常规十进制表示法,而不是1e-6.

请注意,如果没有设置精度,则该d3.format说明符默认为 6 个有效数字(因此0.00000100000),与大多数人的想法相反,1 右侧的五个零是有效数字

如果您只想显示直到 的数字1,让我们设置精度:

console.log(d3.format(".1g")(0.000001))
<script src="https://d3js.org/d3.v5.min.js"></script>

很清楚,让我们看看如果我们使用0.00000011e-7 会发生什么:

console.log(d3.format("g")(0.0000001))
<script src="https://d3js.org/d3.v5.min.js"></script>

如您所见,它返回1.00000e-7而不是0.0000001. 和相同的代码,使用 1 作为精度:

console.log(d3.format(".1g")(0.0000001))
<script src="https://d3js.org/d3.v5.min.js"></script>

结论

在我看来,您不能仅使用 D3 来改变这种行为。您的数字 ( 0.00000020852945934254138) 小于1e-6,因此此处应使用指数符号。要更改它,您必须编写自己的自定义函数。


推荐阅读