自定义d3线性刻度,为空值而不是0返回null

时间:2015-02-04 17:53:24

标签: javascript d3.js

我正在尝试创建一个d3.scale.linear()比例,它在输入数据时为我的折线图输出值。我的数据集包含0到100之间的值,以及null值。图表必须显示数据中的间隙,因此除了为任何整数输入返回整数值之外,如果输入null,我需要使用我的比例来返回null。如果传入0,常规d3.scale.linear()将返回null

我最初的解决方案是执行以下操作:

    var customScale = function(val){
        if (val === null) return null;
        else return d3.scale.linear().domain([0, 100])(val);    
    }

以便customScale(50)返回0.5customScale(null)返回null

然而,这样做意味着我失去了d3.scale.linear()的其他功能,如.invert()

有没有办法以某种方式扩展d3.scale.linear(),以便它可以包含我的自定义条件?

2 个答案:

答案 0 :(得分:1)

这样做的D3方法不是在比例尺中处理这个,而是在你将比例传递给的形状生成函数中处理。 D3为此提供了函数.defined()。例如,如果你画一条线:

var line = d3.svg.line()
  .x(function(d) { return x(d.x); })
  .defined(function(d) { return d.x !== null; });

定义省略此类值的自定义比例的问题是,轴等其他内容会中断。同样,您也不会丢失规模为此方法提供的任何其他功能。

答案 1 :(得分:1)

对于null值,我的函数返回null(在这种情况下,d3.scale.liner()返回0)。主要方法是包装原始比例及其所有方法。

我没有为所有情况测试此功能。但是对于它的基本功能,它正在工作。不幸的是,我没有找到更简单的方法:(

/**
 * d3.scale.linear() retrun 0 for null value
 * I need to get null in this case
 * This is a wrapper for d3.scale.linear()
 */
_getLinearScaleWithNull: function() {
    var alternativeScale = function(origLineScale) {
        var origScale = origLineScale ? origLineScale : d3.scale.linear();

        function scale(x) {
            if (x === null) return null; //this is the implementation of new behaviour
            return origScale(x);
        }

        scale.domain = function(x) {
            if (!arguments.length) return origScale.domain();
            origScale.domain(x);
            return scale;
        }

        scale.range = function(x) {
            if (!arguments.length) return origScale.range();
            origScale.range(x);
            return scale;
        }

        scale.copy = function() {
            return alternativeScale(origScale.copy());
        }

        scale.invert = function(x) {
            return origScale.invert(x);
        }

        scale.nice = function(m) {
            origScale = origScale.nice(m);
            return scale;
        }

        scale.ticks = function(m) {
            return origScale.ticks(m);
        };


        scale.tickFormat = function(m, Format) {
            return origScale.tickFormat(m, Format);
        }

        return scale;
    }

    return alternativeScale();
},