我有一个跟踪文件大小的图表。我想设置一个轴(Y),显示文件大小与适当的Mebibyte后缀ex:KiB,MiB,GiB等。
现在,我正在以字节为单位提供数据,因此从理论上讲,一个简单的.tickFormat()
方法后面跟一个d3.format()
就可以了。不幸的是情况并非如此,因为文件大小实际上是1024(或2 ^ 20)的倍数,而不是典型的SI 10 ^ 6。这意味着我的线开始绘制,但轴很奇怪。
以文件大小587108352为例,如果将其舍入到最接近的MB,则得到560MiB(使用1024(2 ^ 20)乘数)。
如何设置我的轴才能使用它?
我试过了:
yAxis = d3.axisLeft(y)
.tickFormat(function (d) {
return d3.format(scope.formatOptions.specifier)(d * scope.formatOptions.multiplier) + scope.formatOptions.suffix;
});
格式选项对象是:
vm.FormatObjectSize = {
specifier: ".0s", // decimal notation with an SI prefix, rounded to significant digits.
multiplier: 1, // none
suffix: "b" // bytes
};
这不太合适:
答案 0 :(得分:2)
您可以将tickFormat
与函数一起使用来转换文件大小。在这里,我使用this answer中提供的函数,我将其命名为fileSize
。
因此,您的tickFormat
应为:
.tickFormat(function(d){
return fileSize(d)
}
这是一个演示,从0
到587108352
:
var scale = d3.scaleLinear()
.domain([0, 587108352])
.range([20, 470]);
var svg = d3.select("svg");
var gX = svg.append("g").attr("transform", "translate(0,50)")
.call(d3.axisBottom(scale).tickValues(scale.ticks(5).concat(scale.domain())).tickFormat(function(d) {
return fileSize(d)
}))
function fileSize(bytes) {
var thresh = 1024;
if (Math.abs(bytes) < thresh) {
return bytes + ' B';
}
var units = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>
如您所见,587108352
的最后一个值是559.9 Mebibytes,这是正确的值。
顺便说一句,你问题的标题有点不正确:你想要的实际上是 KiB,MiB,GiB 等,而不是Kb,Mb,Gb ......
此外,可以使用MB / GB / TB / etc或MiB / GiB / TiB /等提供文件/存储大小,具体取决于具体情况。例如,HD制造商通常使用十进制(1000),而RAM制造商通常使用1024。