12

我目前正在研究库 d3.js。我有使用 动态线图的线图 这里我们可以选择绘制功率线性和对数。但我的问题是我的数据集中可能有一些值为零,并且由于 log 0 未定义,因此代码无法绘制它。在我的代码中,规模集是这样的

y = d3.scale.log().domain([0.1, max_y _value]).range([h, 0]).nice();

这就是它的使用方式

  lineFunction = d3.svg.line()
        .y(function(d) {
          return y(d);
        });

我知道这是一个奇怪的问题。但是有没有一种方法可以处理 log 0 值,这样如果我有单个零值,其余的都可以正确绘制。如果是,我可以在同一个语句中给出两个域和范围(处理 0 值),而不是如何绑定到 y 轴?

感谢任何帮助将不胜感激。

4

2 回答 2

21

我通过使用钳位功能解决了我的问题。这就是我更改代码的方式:

y = d3.scale.log().clamp(true).domain([0.1, max_y _value]).range([h, 0]).nice();
于 2012-07-04T05:19:05.090 回答
2

如果您有一个域边界之一为 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() 值,因为我必须限制刻度的数量,而使用线性刻度更容易。

编辑: 注意 根据您选择的投影,它会扭曲您的对数刻度。您使用的更宽的间隔将更多地拉伸您的秤的下部。

于 2012-11-05T08:35:51.727 回答