If Cardinal interpolation mode (cardinal, cardinal-open, cardinal-closed) is used, then line can be further modified using tension settings. In this recipe, we will see how tension can be modified and its effect on line interpolation.
Open your local copy of the following file in your web browser:
https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter7/line-tension.html
Now, let's see how line tension can be changed and what effect it has on line generation:
<script type="text/javascript"> var width = 500, height = 500, margin = 30, duration = 500, x = d3.scale.linear() .domain([0, 10]) .range([margin, width - margin]), y = d3.scale.linear() .domain([0, 1]) .range([height - margin, margin]); var data = d3.range(10).map(function(i){ return {x: i, y: (Math.sin(i * 3) + 1) / 2}; }); var svg = d3.select("body").append("svg"); svg.attr("height", height) .attr("width", width); renderAxes(svg); render([1]); function render(tension){ var line = d3.svg.line() .interpolate("cardinal") .x(function(d){return x(d.x);}) .y(function(d){return y(d.y);}); svg.selectAll("path.line") .data(tension) .enter() .append("path") .attr("class", "line"); svg.selectAll("path.line") .data(tension) // <-A .transition().duration(duration).ease("linear") // <-B .attr("d", function(d){ return line.tension(d)(data); // <-C }); svg.selectAll("circle") .data(data) .enter().append("circle") .attr("class", "dot") .attr("cx", function(d) { return x(d.x); }) .attr("cy", function(d) { return y(d.y); }) .attr("r", 4.5); } // Axes related code omitted ... </script> <h4>Line Tension:</h4> <div class="control-group"> <button onclick="render([0])">0</button> <button onclick="render([0.2])">0.2</button> <button onclick="render([0.4])">0.4</button> <button onclick="render([0.6])">0.6</button> <button onclick="render([0.8])">0.8</button> <button onclick="render([1])">1</button> </div>
The preceding code generates a Cardinal line chart with configurable tension:
Tension sets the Cardinal spline interpolation tension to a specific number in the range of [0, 1]
. Tension can be set using the tension
function on line generator (see line C
):
svg.selectAll("path.line") .data(tension) // <-A .transition().duration(duration).ease("linear") // <-B .attr("d", function(d){ return line.tension(d)(data);} // <-C );
Additionally, we also initiated a transition on line B
to highlight the tension effect on line interpolation. If the tension is not set explicitly, Cardinal interpolation sets tension to 0.7
by default.