Why can I input an argument on a scale?

前端 未结 1 490
半阙折子戏
半阙折子戏 2021-01-21 20:19

I\'m doing a simple histogram:

var width = 500,
  height = 500,
  padding = 50;
d3.csv(\'mydata.csv\', function(data) {
  var map = data.map(function(i) {
    re         


        
相关标签:
1条回答
  • 2021-01-21 20:45

    You said that...

    The scale variable x and y aren't functions.

    Well, that's incorrect. D3 scales (in any version) are functions. In you case, you have a D3 v3 scale.

    To show you that this is a scale, and what argument it takes, let's see D3 v3 source code. It will take us through a labyrinth of functions returning functions.

    This is the d3.scale.linear() function:

    d3.scale.linear = function() {
        return d3_scale_linear([0, 1], [0, 1], d3_interpolate, false);
    };
    

    As you can see, it returns a function, d3_scale_linear. That function takes 4 arguments, the first two are the default range and domain. Obviously, you can change both the range and the domain later, as you did.

    If you look at d3_scale_linear, you'll see that it returns this function:

    function rescale() {
        var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear,
            uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
        output = linear(domain, range, uninterpolate, interpolate);
        input = linear(range, domain, uninterpolate, d3_interpolate);
        return scale;
    }
    

    Which by its turn returns this function:

    function scale(x) {
        return output(x);
    }
    

    And that x is the argument that you pass to the scale when you use it, like x(d.x) in your example. The passed argument is d.x.

    Just for completeness, the output function depends on either d3_scale_polylinear or d3_scale_bilinear, which are the functions that perform the real job:

    function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
        var u = uninterpolate(domain[0], domain[1]),
            i = interpolate(range[0], range[1]);
        return function(x) {
            return i(u(x));
        };
    }
    
    function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
        var u = [],
            i = [],
            j = 0,
            k = Math.min(domain.length, range.length) - 1;
        if (domain[k] < domain[0]) {
            domain = domain.slice().reverse();
            range = range.slice().reverse();
        }
        while (++j <= k) {
            u.push(uninterpolate(domain[j - 1], domain[j]));
            i.push(interpolate(range[j - 1], range[j]));
        }
        return function(x) {
            var j = d3.bisect(domain, x, 1, k) - 1;
            return i[j](u[j](x));
        };
    }
    
    0 讨论(0)
提交回复
热议问题