简体   繁体   English

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

[英]How to avoid log zero in graph using d3.js

I am current working on library d3.js.I have line graph using Dynamic Line Graph Here we have option of drawing power linear and log. 我目前正在使用库d3.js.I我有使用动态线图的线图这里我们有绘制功率线性和日志的选项。 But my problem is that I might have some values zero in my data set and as log 0 is undefined so the code is unable to plot it. 但我的问题是我的数据集中可能有一些值为零,因为log 0未定义,因此代码无法绘制它。 Here in my code the scale set like this 在我的代码中,比例设置如下

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

and this is how it is used 这就是它的使用方式

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

I know that its an odd question.But is there a way by which I can handle log 0 value so that if I have single zero value the rest of them are plotted correctly. 我知道这是一个奇怪的问题。但是有一种方法我可以处理log 0值,这样如果我有单个零值,其余的都正确绘制。 Can I gave two domain and range in same statement (to handle 0 value) if yes than how will it bind to y axis? 我是否可以在同一语句中给出两个域和范围(处理0值),如果是,它将如何绑定到y轴?

Thanks any help will be appreciated. 谢谢任何帮助将不胜感激。

I solved my problem by using a clamp function. 我通过使用钳位功能解决了我的问题。 This is how I have changed the code: 这就是我改变代码的方式:

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

If you have a domain which has one of the domain boundaries as 0 log scale won't work for you. 如果您的域名具有其中一个域边界,则0对数比例将不适合您。 Also log scale provides you a tick() function with uncofigurable number of ticks. 此外,log scale为您提供了一个tick()函数,其中包含无法使用的刻度数。

My current assignment is to display data with arbitrary domains and ranges on a linear scaled scatter chart BUT optionally the user can change over to logarithmic scale. 我目前的任务是在线性缩放散点图上显示具有任意域和范围的数据。但是,用户可以选择切换到对数刻度。 This includes the problematic [0,n] and [n,0] domains. 这包括有问题的[0,n]和[n,0]域。

Here's a solution i came up with to handle these cases: The issue can be avoided if we are using a linear scale to project our domain to an arbitrary range with positive boundaries. 这是我提出的解决这些问题的解决方案:如果我们使用线性比例将我们的域投影到具有正边界的任意范围,则可以避免该问题。 I choose [1,10] but it can take any positive numbers. 我选择[1,10]但它可以取任何正数。 After that we can use a normal log scale. 之后我们可以使用正常的对数刻度。

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;

}

Usage: 用法:

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

I only needed the range(), scale(), ticks() functions so i only included these but it shouldn't take more than 5 minutes to implement all the others. 我只需要range(),scale(),ticks()函数,所以我只包括这些函数,但实现所有其他函数不应超过5分钟。 Also: note that i was using the linear scale's ticks() values because I had to limit the number of ticks and that is easier with the linear scale. 另外:请注意,我使用的是线性刻度的ticks()值,因为我必须限制刻度数,并且线性刻度更容易。

EDIT: BE AWARE Depending on what you choose as PROJECTION it will distort your log scale. 编辑:要注意根据您选择的PROJECTION,它会扭曲您的对数范围。 The wider interval you use will strecth your scale's lower part more. 你使用的间隔越宽,你的音阶越低。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM