This is the second day of my participation in the First Challenge 2022


See the Data Visualization column for a series of articles


Reference:

  • Learn D3: Animation
  • Transitions (d3-transition)
  • D3-transition (Unofficial Chinese Translation)
  • D3-interpolate (Unofficial Chinese translation)
  • Animated Transitions in Statistical Data Graphics

This article mainly introduces the interpolate module.

D3 provides the D3-Transition module for the transition animation of graphic elements. It is similar to the Selection module in that it has similar methods, such as setting style attributes for selected DOM elements. But when setting these properties, are generally not directly set as the target, but used multiple times in the transition time interpolator (d3 – interpolate module provides a variety of built-in interpolator) calculate the transition between the starting value and the target value, so as to realize graphic elements of a visual variable smooth transformation from the initial value to the effect of the target value.


Interpolators are used to calculate transition values for tween animation.

When creating an interpolator in D3, you need to specify its starting value and target/end value, that is, set the interpolation range. Then, when the interpolator function is called, it takes a standard time t as an input parameter. It then returns a transition value at that time by combining a start and end value. For example, the built-in interpolator d3.interpolatenumber (a, b) has the following source code

export default function(a, b) {
  return a = +a, b = +b, function(t) {
    return a * (1 - t) + b * t;
  };
}
Copy the code
// Create an interpolator and configure the interpolation range
const i = d3.interpolateNumber(10.20);

// call the interpolator with standard time t and range [0, 1]
i(0.0); / / 10
i(0.2); / / 12
i(0.5); / / 15
i(1.0); / / 20
Copy the code

In the d3-interpolate module, D3 provides a variety of interpolators for different data types:

💡 In fact, these interpolators are ultimately for the numerical part of the interpolation, such as color interpolation, color deconstruction into the corresponding numerical parameters; For CSS transform style interpolation, it is the transform matrix operation.

Universal type interpolator

Interpolator creates an interpolator of a general type using the method d3.interpolatenumber (a, b). In fact, it automatically calls the corresponding data type interpolator based on the value type of B, and the selection algorithm is as follows:

  1. whenbThe data type isnull,undefinedOr Booleans, always use constantsbAs a transition value
  2. whenbThe data type is numeric and is usedd3.interpolateNumberinterpolator
  3. whenbThe data type is color (or a string that can be converted to color) and is usedd3.interpolateRgbinterpolator
  4. whenbThe data type is dated3.interpolateDateinterpolator
  5. whenbThe data type is a stringd3.interpolateStringinterpolator
  6. whenbThe data type is an array of declared types, usedd3.interpolateNumberArrayinterpolator
  7. whenbThe data type is arrayd3.interpolateArrayinterpolator
  8. whenbA data type is a type that can be converted to a numeric valued3.interpolateNumberinterpolator
  9. whenbIs another data type, used3.interpolateObjectinterpolator

Interpolators for specific data types

  • D3.interpolatenumber (a, b) creates a numerical interpolator whose interpolation range is [a, b]

    💡 avoids using 0 as the endpoint of the range, because the transition values are converted to scientific notation (representing numbers as strings) as they approach 0, for example, the value 0.0000001 is converted to the string 1E-7. If 0 is to be used at the end of the interpolation range, 0.000001 should be used instead (this is the smallest number that will not be converted to scientific notation)

  • InterpolateRound (a, b) A numeric interpolator whose interpolation range is [a, b], but whose transition value is modified to approximate the nearest integer

  • InterpolateString (a, b) An interpolator for a string that automatically analyzes a string using the text part of B (which remains unchanged) as a template and interpolates the transition values of the numeric part to form a complete string.

    const a="300 12px sans-serif";
    const b="500 36px Comic-Sans";
    const interpolator = d3.interpolateString(a, b);
    
    interpolator(0.5); // "400 24px Comic-Sans"
    Copy the code
  • InterpolateDate (a, b) creates an interpolator whose date range is [A, B] ⚠️. For the sake of performance, the interpolator returns a non-defensive copy of NO DEFENSIVE copy. The interpolated values are all referred to the same date object. Therefore, the date object keeps changing during the transition. If you want to perform additional operations on the date object, copy it first.

  • InterpolateArray (a, b) interpolates an array by interpolating pairs of elements (based on indexes) of two arrays. Interpolates an array of “intermediate states” using the target array B as a template.

    const a=[0.1];
    const b=[1.10.100];
    const interpolator = d3.interpolateArray(a, b);
    
    interpolator(0.5); / / [0.5, 5.5, 100]
    Copy the code

    ⚠️ For the sake of performance, the transition values returned by the interpolator also use a non-defensive copy, no defensive copy

  • D3. InterpolateNumberArray (a, b) to interpolation of array, the array elements of the data type is numerical

  • InterpolateObject (a, interpolateObject) interpolates an object based on the name of the attribute. InterpolateObject (a, interpolateObject) interpolates an object based on the name of the attribute.

    const a={x: 0.y: 1};
    const b={x: 1.y: 10.z: 100};
    const interpolator = d3.interpolateObject(a, b);
    
    interpolator(0.5); // {x: 0.5, y: 5.5, z: 100}
    Copy the code

    ⚠️ For the sake of performance, the transition values returned by the interpolator also use a non-defensive copy, no defensive copy

  • D3. InterpolateTransformCss (a, b) to create a 2 d CSS transformation properties transform interpolator, transition value can be decomposed into a standard transform properties (string), according to the starting value and target, Transition values may include translation Translate, rotate, x-skew along the horizontal axis, and scale 💡, which is actually interpolated based on the Transform matrix. Therefore, the transform matrix can also be used to set the interpolation range when creating the interpolator.

    const a = "translateY(12px) scale(2)";
    const b = "translateX(30px) rotate(5deg)";
    const interpolator = d3.interpolateTransformCss(a, b);
    
    interpolator(0.5); Rotate (15px, 6px) rotate(2.4999999999999996deg) scale(1.5,1.5)"
    
    const c = Matrix (1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
    const d = "translate(3px,90px)";
    const interpolator = d3.interpolateTransformCss(c, d);
    
    interpolator(0.5); // "translate(4px, 48 px) rotate (58.282525588538995 deg) skewX (39.847576765616985 deg) scale (0.6180339887498949, 0.9472135954999579)"
    Copy the code
  • D3. InterpolateTransformSvg (a, b) create a SVG transformation transform interpolator

  • D3.interpolatezoom (a, b) creates a two-dimensional flat view zoom switching interpolator. Each view has an array of three elements to define [cx, cy, width], where (cx, cy) represents the view’s midpoint, viewPort Center, and width represents the view’s size.

    💡 The interpolator calculates a recommended transition time (in milliseconds) based on the length of the switching path between two views, interpolateZoom.duration, based on which the transition duration can be set (or multiplied by any coefficient)

    const start = [30.30.40];
    const end = [135.85.60];
    const interpolator = d3.interpolateZoom(start, end);
    const duration = interpolator.duration * 1.5 // 33% slower than the recommendation
    
    // set transition duration
    transition()
      .duration(duration)
    Copy the code

    💡 You can set the curvature parameter of the interpolator interpolateZoom.rho(rho) where the parameter rho defaults to SQRT (2). The closer the input rHO is to 0, the more linear the view switching trajectory becomes.

  • D3.interpolatediscrete (values) Creates a discrete interpolator whose input parameter VALUES is an array whose elements will be used as transitional values. When the interpolator is called, the standard time is divided by the length of the array values n=values.length, that is, when t is in the range [0, 1/n], the interpolator returns a transition value of values[0]; When t is in the range [1/n, 2/n], the interpolator returns a transition value of values[1]; And so on.

    💡 can be used as the stratified Quantize Scale with a range of [0, 1]

Color interpolator

  • d3.interpolateRgb(a, b)The interpolator can be configured with the gamma parameterinterpolate.gamma(gamma)
  • d3.interpolateRgbBasis(colors)
  • d3.interpolateRgbBasisClosed(colors)
  • d3.interpolateHsl(a, b)
  • d3.interpolateHslLong(a, b)
  • d3.interpolateLab(a, b)
  • d3.interpolateHcl(a, b)
  • d3.interpolateHclLong(a, b)
  • d3.interpolateCubehelix(a, b)The interpolator can be configured with the gamma parameterinterpolate.gamma(gamma)
  • d3.interpolateCubehelixLong(a, b)The interpolator can be configured with the gamma parameterinterpolate.gamma(gamma)
  • d3.interpolateHue(a, b)

Other interpolators

  • d3.interpolateBasis(values)
  • d3.interpolateBasisClosed(values)
  • d3.piecewise([interpolate, ]values)Create a segmented interpolator that will be an arrayvaluesCreates interpolators between each element of
    const interpolate = d3.piecewise(d3.interpolateRgb, ["red"."green"."blue"]);
    Copy the code

    The above example creates a segmented interpolator when standard timet[0, 1 / (3-1)]When in the range, interpolators are usedd3.interpolateRgb("red", "green"); Normal timet[1 / (3, 1), (3-1) / 2]When in the range, interpolators are usedd3.interpolateRgb("green", "blue")

The sampling

Interpolators are generally used in transitions, which accept the standard time T as an input parameter and calculate the corresponding intermediate value to realize the tween animation.

D3 also provides a method d3.quantize(interpolator, n) to employ an interpolator for its interpolating range [a, b].

The second parameter n is a positive integer greater than 1 to indicate the number of samples to be sampled. It is interpolated to a specified interpolator at the corresponding standard time t=k/n (k is interpolated from 1 to n).

The method can be used to construct the stratified Quantize Scale (as range) by taking discrete values from a continuous range through an interpolator

⚠️ For interpolators working in a non-defensive no defensive copy mode, such as D3. interpolateArray, D3. interpolateDate, and D3. interpolateObject, this method will not sample normally. These interpolators must first be rewrapped so that they return a copy of the transition value rather than a reference to the object.