d3.format中的变量精度

时间:2012-04-25 06:44:31

标签: javascript svg format d3.js

我正在使用带有d3.svg.axis.tickFormat的d3.format(“s”)来很好地格式化带有SI单位的刻度标签(来自国际单位制)。它在大多数情况下都能很好地工作,除了遇到舍入误差并返回大量小数位的某些值(1400,例如,1400 * 0.001 = 1.4000000000000001)。

为了解决这个问题,我可以指定一个精度,例如d3.format(“。2s”)但是在1会更好的情况下强制2位有效数字。例如,如果我有[5000,10000,15000],我现在会看到[5.0k,10k,15k]。最初当我没有指定精度时,我得到[5k,10k,15k]。

我想知道是否可以指定最大精度,只有当有效位数超过指定数量时才会应用它?所以5000将是5k而不是5.0k。

2 个答案:

答案 0 :(得分:2)

您可以通过在匿名函数中放置if / else语句来执行此操作,您将在其中输出文本字符串。在if / else中你可以满足你想要的任何条件并创建一个解析你的价值的函数。这是一个例子:

var w = 30, h = 300;
var data = [
  {'point':1, 'value':100.005},
  {'point':2, 'value':20.010},
  {'point':3, 'value':1000},
  {'point':4, 'value':5000.099},
  {'point':5, 'value':6000.934},
  {'point':6, 'value':9000.888},
  {'point':7, 'value':500.22},
  {'point':8, 'value':5.123},
  {'point':9, 'value':50.022},
  {'point':10, 'value':7000.999}
];
var chart = d3.select("body").append("svg")
  .attr('class', 'chart')
  .attr("width", w * data.length - 1)
  .attr("height", h);

chart.selectAll('text')
  .data(data)
.enter().append('text')
  .attr('x', function(d, i) { return x(i); })
  .attr('y', function(d) { return h - y(d.value); })
  .attr('dx', '0.75em')
  .attr('dy', '-0.3em')
  .attr('text-anchor', 'start')
  .text(function(d) { 
    if(d.value > 5000) {
      // Define your formatting function to return SI units
      var si = d3.format('s');
      return String(si(d.value));
    } else {
      // Otherwise round to the nearest integer
      return String(d3.round(d.value, 0));
    }
  });

希望有所帮助。

答案 1 :(得分:2)

1400 * .001为1.4000000000000001,1400 / 1000为1.4;将整数乘以10的负幂(例如.001)可能会引入舍入误差,但似乎将整数除以10的幂(例如1000)则不会。或者至少,它不太可能?我已经在fix-si-format-rounding分支中实现了一个暂定的修复。它严格地向后兼容,但由于d3.formatPrefix函数没有记录,我认为在下一个补丁版本中包含它是安全的。

编辑:此修补程序已在2.9.2版中发布。