In Chapter 4, Tipping the Scales, we explored how custom interpolators can be implemented in D3. In this recipe, we will demonstrate how this technique can be combined with D3 transition to generate special transition effects by leveraging custom interpolation.
Open your local copy of the following file in your web browser:
This recipe builds on top of what we have discussed in the Implementing a custom interpolator recipe in Chapter 4, Tipping the Scales. If you are not familiar with the concept of custom interpolation, please review the related recipe before proceeding with this one.
Let's look at the code of the custom-interpolator-transition.html
file and see how it works:
<script type="text/javascript"> d3.interpolators.push(function(a, b) { // <-A var re = /^([a-z])$/, ma, mb; if ((ma = re.exec(a)) && (mb = re.exec(b))) { a = a.charCodeAt(0); var delta = a - b.charCodeAt(0); return function(t) { return String.fromCharCode(Math.ceil(a - delta * t)); }; } }); var body = d3.select("body"); var countdown = body.append("div").append("input"); countdown.attr("type", "button") .attr("class", "countdown") .attr("value", "a") // <-B .transition().ease("linear") // <-C .duration(4000).delay(300) .attr("value", "z"); // <-D </script>
The preceding code generates one ticking box that starts from a and finishes at z:
First thing we did in this recipe is register a custom interpolator that is identical to the alphabet interpolator we discussed in Chapter 4, Tipping the Scales:
d3.interpolators.push(function(a, b) { // <-A var re = /^([a-z])$/, ma, mb; if ((ma = re.exec(a)) && (mb = re.exec(b))) { a = a.charCodeAt(0); var delta = a - b.charCodeAt(0); return function(t) { return String.fromCharCode(Math.ceil(a - delta * t)); }; } });
Once the custom interpolator is registered, the transition part has pretty much no custom logic at all. Since it's based on the value that needs to be interpolated and transitioned upon, D3 will automatically pick the correct interpolator to perform the task:
countdown.attr("type", "button") .attr("class", "countdown") .attr("value", "a") // <-B .transition().ease("linear") // <-C .duration(4000).delay(300) .attr("value", "z"); // <-D
As we can see in the preceding code snippet, the start value is "a"
, defined on line B
. Afterwards, a standard D3 transition is created on line C
and finally all we had to do is set the end value to "z"
on line D
, then D3 and our custom interpolator takes care of the rest.