There will be cases when what you need to interpolate in your visualization is not a simple value but rather an object consisting of multiple and different values, for example, a rectangular object with width, height, and color attributes. Fortunately, D3 has a built-in support for this type of compound object interpolation.
Open your local copy of the following file in your web browser:
https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter4/compound-interpolation.html
In this recipe, we will examine how compound object interpolation is performed in D3. The code for the compound-interpolation.html
file is as follows:
<div id="compound" class="clear"> <span>Compound Interpolation<br></span> </div> <script type="text/javascript"> var max = 21, data = []; var compoundScale = d3.scale.pow() .exponent(2) .domain([0, max]) .range([ {color:"#add8e6", height:"15px"}, // <-A {color:"#4169e1", height:"150px"} // <-B ]); for (var i = 0; i < max; ++i) data.push(i); function render(data, scale, selector) { // <-C d3.select(selector).selectAll("div.v-bar") .data(data) .enter().append("div").classed("v-bar", true) .append("span"); d3.select(selector).selectAll("div.v-bar") .data(data) .exit().remove(); d3.select(selector).selectAll("div.v-bar") .data(data) .classed("v-bar", true) .style("height", function(d){ // <-D return scale(d).height; }) .style("background-color", function(d){ // <-E return scale(d).color; }) .select("span") .text(function(d,i){return i;}); } render(data, compoundScale, "#compound"); </script>
The preceding code generates the following visual output:
This recipe is different from the previous recipes of this chapter by the fact that the scale we use in this recipe has a range defined using two objects rather than simple primitive data types:
var compoundScale = d3.scale.pow() .exponent(2) .domain([0, max]) .range([ {color:"#add8e6", height:"15px"}, // <-A {color:"#4169e1", height:"150px"} // <-B ]);
We can see on line A
and B
that the start and end of the scale range are two objects which contain two different kinds of values; one for RGB color and the other one for CSS height style. When you interpolate this kind of a scale containing compound range, D3 will iterate through each of the fields inside an object and recursively apply the simple interpolation rule on each one of them. Thus, in other words, for this example, D3 will interpolate the color
field using color interpolation from #add8e6
to #4169e1
while using string interpolation on height field from 15px
to 150px
.
{ color:"#add8e6", size{ height:"15px", width: "25px" } }
A compound scale function, when invoked, returns a compound object that matches the given range definition:
.style("height", function(d){ return scale(d).height; // <-D }) .style("background-color", function(d){ return scale(d).color; // <-E })
As we can see on line D
and E
, the returned value is a compound object, and this is why we can access its attribute to retrieve the interpolated values.
var compoundScale = d3.scale.pow() .exponent(2) .domain([0, max]) .range([ {color:"#add8e6", height:"15px"}, // <-A {color:"#4169e1"} // <-B ]);