以字节为单位使用 KiB、MiB、GiB 单位设置 d3 轴

Posted

技术标签:

【中文标题】以字节为单位使用 KiB、MiB、GiB 单位设置 d3 轴【英文标题】:setting up d3 axis with KiB, MiB, GiB units from values in bytes 【发布时间】:2017-10-05 21:53:39 【问题描述】:

我有一个跟踪文件大小的图表。我想设置一个显示文件大小的轴 (Y),并带有适当的 Mebibyte 后缀,例如: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
    ;

这不太好用:

【问题讨论】:

Sugar.js 库有一种方法可以为您将数字概括为字符串:sugarjs.com/docs/#/Number/bytes 【参考方案1】:

您可以将tickFormat 与转换文件大小的函数一起使用。在这里,我使用了this answer中提供的函数,我将其命名为fileSize

所以,你的tickFormat 应该是:

.tickFormat(function(d)
    return fileSize(d)
 

这是一个演示,从0587108352

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  ></svg>

如您所见,587108352 的最后一个值是 559.9 Mebibytes,这是正确的值。

顺便说一句,你的问题的标题有点不正确:你想要的实际上是 KiB、MiB、GiB 等,而不是 Kb、Mb、Gb...

此外,文件/存储大小可以使用 MB/GB/TB/etc 或 MiB/GiB/TiB/etc 来提供,这取决于具体情况。例如,HD 厂商通常使用十进制(1000),而 RAM 厂商通常使用 1024。

【讨论】:

一如既往的惊人答案和很好的解释。谢谢!

以上是关于以字节为单位使用 KiB、MiB、GiB 单位设置 d3 轴的主要内容,如果未能解决你的问题,请参考以下文章

存储GB与GiB之间的转换

以 MiB / GiB 为单位的 Ansible stat 模块目录大小输出。如何转换输出?

关于数据计量单位的一些混淆

文件大小换算

使用 kB,MB,GB,... 和 kiB,MiB,GiB 的 ISO 前缀格式化整数,

KiB和KB的区别