我正在使用带有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。
答案 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版中发布。