如果您有一个域边界之一为 0 对数刻度的域将不适合您。对数刻度还为您提供了一个带有不可配置的刻度数的 tick() 函数。
我目前的任务是在线性比例散点图上显示具有任意域和范围的数据,但用户可以选择切换到对数比例。这包括有问题的 [0,n] 和 [n,0] 域。
这是我想出的处理这些情况的解决方案:如果我们使用线性比例将我们的域投影到具有正边界的任意范围,则可以避免该问题。我选择 [1,10] 但它可以取任何正数。之后,我们可以使用正常的对数刻度。
d3.scale.genericLog = function() {
return GenericLog();
};
function GenericLog() {
var PROJECTION=[1,10];
var linearScale, logScale;
linearScale=d3.scale.linear();
linearScale.range(PROJECTION);
logScale=d3.scale.log();
logScale.domain(PROJECTION);
function scale(x) {
return logScale(linearScale(x));
}
scale.domain = function(x) {
if (!arguments.length) return linearScale.domain();
linearScale.domain(x);
return scale;
};
scale.range = function(x) {
if (!arguments.length) return logScale.range();
logScale.range(x);
return scale;
};
scale.ticks = function(m) {
return linearScale.ticks(m);
};
return scale;
}
用法:
var scale1 = d3.scale.genericLog().domain([0,1]).range([500,1000]);
var scale2 = d3.scale.genericLog().domain([-10,0]).range([500,1000]);
scale1(0) //500
scale2(-10) //500
scale2(0) //100
我只需要 range()、scale()、ticks() 函数,所以我只包含了这些,但实现所有其他函数的时间不会超过 5 分钟。另外:请注意,我使用的是线性刻度的 ticks() 值,因为我必须限制刻度的数量,而使用线性刻度更容易。
编辑:
注意
根据您选择的投影,它会扭曲您的对数刻度。您使用的更宽的间隔将更多地拉伸您的秤的下部。