hwilson1
hwilson1

Reputation: 499

d3 interpolation example explanation

Can I confirm my understanding of what's happening in the following code?

var color = d3.scale.linear()
    .range(["hsl(-180,50%,50%)", "hsl(180,50%,50%)"])
    .interpolate(interpolateHsl);

We're defining a scaling function called color (not sure why we're able to define a variable as a function but I've learnt to accept this - clarification would be helpful).

There's no domain specified, because using .interpolate() will only work with domain between 0 and 1? Or because domain == range in this case? Or some other reason?

Calling interpolateHsl from the interpolate function takes 'implicit parameters' (no need to specify - are they called implicit parameters or some other ref?) of the start and end points of the range (a and b).

function interpolateHsl(a, b) {
    var i = d3.interpolateString(a, b);
    return function(t) {
        return d3.hsl(i(t));
    }
}

Now we define an interpolation fn within interpolateHsl that interpolates strings - which I think will take say ['calibri 12px', 'calibri 24px'], pluck out the numerical part and interpolate over that and then rejoin it the text element? So in this case it'll pluck out the numerical components from the hsl string and interpolate over those?

Now (if it wasn't enough already) it gets really confusing.

t is the 'increment' - so if the total interpolation time was say 5000ms and we had a discrete range of 5 steps then t = 1000ms? So in a continuous context it's just very small?

i(t) will calculate the interpolated value at 'time' t, which is then converted to a true hsl value rather than just a string representation via d3.hsl().

Why does this have to be in a function within the function? To access the t?

Broadly speaking my understanding's patchy so a broader explanation of what's going on would be extremely helpful.

Upvotes: 0

Views: 4091

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109242

  1. In Javascript, you can use both var and function to declare functions (see e.g. this question) -- functions are are first-class citizens of the language and can be passed around just like variables.

  2. There's no domain specified because the default ([0,1]) is sufficient here. No other reason, in particular it's not affected by the setting of the range or interpolator.

  3. interpolate() takes a factory as argument (see the documentation). That is, it takes a function, not a value (this is related to point 1 -- functions can be passed around just like variables). The arguments to the functions are supplied by the implementation of the scale, transparent to the user. You're telling the scale how to interpolate in general, not how to interpolate specific values. When the time to interpolate comes, the scale will know to call this function with the appropriate arguments.

  4. Yes, interpolateHsl() will interpolate the number in the strings -- again I refer you to the documentation.

  5. t what tells the interpolation function how far the transition has progressed, i.e. where between start and end it is. It is a number between 0 and 1, where 0 is "transition hasn't started yet" and 1 "transition finished". This is also described in the documentation.

  6. The interpolation function returns a function which, given a t that tells it how far the transition has progressed, returns the current value. This is called a closure -- an anonymous (unnamed) function that captures the binding of the variables it references. In particular, this closure captures the interpolation between the two strings a and b. That is, when interpolateHsl() is called (by the scale internally), it is given the two target strings to interpolate. It is not given a t value. It returns a function that takes a t value and returns the appropriate position for the interpolation between the two strings (which "live" inside the i captured in the closure). Now the transition is set up and starts. It generates values for t which are passed to the interpolation function created earlier.

This page has a brief tutorial on closures that you may find helpful.

Upvotes: 4

Related Questions