Interpolating a string

In some cases, you might need to interpolate numbers embedded in a string; perhaps a CSS style for font.

In this recipe, we will examine how you can do that using D3 scale and interpolation. However, before we jump right into string interpolation, a bit of background research on interpolator is due and the following section will cover what interpolation is and how D3 implements interpolator functions.

Interpolator

In the first three recipes, we have gone over three different D3 scale implementations, now it is time to delve a little deeper into D3 scales. You are probably already asking the question, "How different scale knows what value to use for different inputs?" In fact this question can be generalized to:

We are given the values of a function f(x) at different points x0, x1, … ,xn. We want to find approximate values of the function f(x) for "new" x's that lie between these points . This process is called interpolation.

Kreyszig E & Kreyszig H & Norminton E. J. (2010)

Interpolation is not only important in scale implementation but also essential to many other core D3 capabilities, for example, animation and layout management. It is because of this essential role, D3 has designed a separate and re-usable construct called interpolator so that this common cross-functional concern can be addressed in a centralized and consistent fashion. Let's take a simple interpolator as an example:

var interpolate = d3.interpolateNumber(0, 100);
interpolate(0.1); // => 10
interpolate(0.99); //=> 99

In this simple example, we created a D3 number interpolator with a range of [0, 100]. The d3.interpolateNumber function returns an interpolate function which we can use to perform number-based interpolations. The interpolate function is an equivalent to the following code:

function interpolate(t) {
    return a * (1 - t) + b * t;
}

In this function, a represents the start of the range and b represents the end of the range. The parameter t passed into the interpolate() function, is a float-point number ranging from 0 to 1, and it signifies how far the return value is from a.

D3 provides a number of built-in interpolators. Due to limited scope in this book, we will focus on some of the more interesting interpolators for the next few recipes; we are ending our discussion on simple number interpolation here. Nevertheless, the fundamental approach and mechanism remains the same whether it is a number or an RGB color code interpolator.

Note

For more details on number and round interpolation, please refer to the D3 reference documents at https://github.com/mbostock/d3/wiki/Transitions#wiki-d3_interpolateNumber

Now with general interpolation concepts behind, let's take a look at how string interpolator works in D3.

Getting Ready

Open your local copy of the following file in your web browser:

https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter4/string-interpolation.html

How to do it...

String interpolator finds the numbers embedded in the string, then performs interpolation using D3 number interpolator:

<div id="font" class="clear">
    <span>Font Interpolation<br></span>
</div>

<script type="text/javascript">
    var max = 11, data = [];

    var sizeScale = d3.scale.linear() // <-A
        .domain([0, max])
        .range([  // <-B
            "italic bold 12px/30px Georgia, serif", 
            "italic bold 120px/180px Georgia, serif"
        ]);

    for (var i = 0; i < max; ++i){ data.push(i); }

    function render(data, scale, selector) { // <-C
        d3.select(selector).selectAll("div.cell")
                .data(data)
            .enter().append("div").classed("cell", true)
                .append("span");

        d3.select(selector).selectAll("div.cell")
                .data(data)
            .exit().remove();

        d3.select(selector).selectAll("div.cell")
                .data(data)
            .style("display", "inline-block")
            .select("span")
                .style("font", function(d,i){ 
                    return scale(d); // <-D
                })
                .text(function(d,i){return i;}); // <-E
    }

    render(data, sizeScale, "#font");
</script>

The preceding code produces the following output:

How to do it...

String interpolation

How it works...

In this example, we created a linear scale on line A with range specified between two strings representing start and end font styles:

var sizeScale = d3.scale.linear() // <-A
        .domain([0, max])
        .range([  // <-B
            "italic bold 12px/30px Georgia, serif", 
            "italic bold 120px/180px Georgia, serif"
        ]);

As you can see in the code of the string-interpolation.html file, the font style strings contain font-size numbers 12px/30px and 120px/180px, which we want to interpolate in this recipe.

On line C, the render() function simply creates 10 cells containing each one's index numbers (line E) styled using interpolated font style string calculated on line D.

.style("font", function(d,i){ 
    return scale(d); // <-D
})
.text(function(d,i){return i;}); // <-E

There's more...

Though we demonstrated string interpolation in D3 using a CSS font style as an example, D3 string interpolator is not only limited handling CSS styles. It can basically handle any string, and interpolates the embedded number as long as the number matches the following Regex pattern:

/[-+]?(?:d+.?d*|.?d+)(?:[eE][-+]?d+)?/g

Tip

When generating a string using interpolation, very small values, when stringified, may get converted to scientific notation, for example, 1e-7. To avoid this particular conversion, you need to keep your value larger than 1e-6.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset