Changing line tension

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.

Getting Ready

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

How to do it...

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:

How to do it...

Line Tension

How it works...

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.

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

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