如何使用d3.js避免图中的log 0

问题描述 投票:7回答:2

我目前正在使用库d3.js.I我有使用Dynamic Line Graph的折线图这里我们有绘制功率线性和日志的选项。但我的问题是我的数据集中可能有一些值为零,因为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轴?

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

javascript d3.js
2个回答
12
投票

我通过使用clamp函数解决了我的问题。这就是我改变代码的方式:

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

2
投票

如果您的域名具有其中一个域边界,则0对数比例将不适合您。此外,log scale为您提供了一个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()值,因为我必须限制刻度数,并且线性刻度更容易。

编辑:要注意根据您选择的PROJECTION,它会扭曲您的对数范围。你使用的间隔越宽,你的音阶越低。

© www.soinside.com 2019 - 2024. All rights reserved.