2012-07-04 31 views
7

我当前工作的图书馆d3.js.I有使用 Dynamic Line Graph 我们这里有图纸功率线性和日志的选项线图。 但我的问题是,我的数据集中可能有一些值为零,因为日志0未定义,所以代码无法绘制它。 这里在我的代码规模设置这样如何避免在图形登录使用零d3.js

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

,这是它是如何使用

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

我知道它的奇数question.But是由有我可以处理日志的方式0值,这样如果我有单个零值,其余部分绘制正确。 如果是,我可以在同一语句中给出两个域和范围(处理0值),而不是如何绑定到y轴?

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

回答

12

我使用clamp函数解决了我的问题。这就是我如何更改代码:

y = d3.scale.log().clamp(true).domain([0.1, max_y _value]).range([h, 0]).nice(); 
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 

我只需要范围(),规模(),蜱()函数,所以我只包括这些,但它不应该超过5分钟,以实现所有其他。此外:请注意,我使用线性刻度的ticks()值,因为我必须限制刻度的数量,而使用线性刻度更容易。

编辑: 注意 根据你选择什么作为投影它会扭曲你的日志规模。你使用的更宽的时间间隔将更加拉伸你的比例尺的下半部分。