block by d3noob ced1b9b18bd8192d2c898884033b5529

v4 curve interpolation comparison

Full Screen

This bl.ock demonstrates the range of interpolation curves available in v4 of d3.js.

You can click on any of the legend labels to toggle visibility of the lines.

Details of the curve can be found on the D3 wiki.

This graph is part of the code samples for the update to the book D3 Tips and Tricks to version 4 of d3.js.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */

.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 2px;
}

body { font: 12px Arial;}

.legend {
    font-size: 16px;
    font-weight: bold;
    text-anchor: left;
}
</style>
<body>

<!-- load the d3.js library -->    	
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

// set the dimensions and margins of the graph
var margin = {top: 20, right: 150, bottom: 30, left: 50},
    width = 960 - margin.left - margin.right,
    height = 470 - margin.top - margin.bottom;

// array of curve functions and tites
var curveArray = [
    {"d3Curve":d3.curveLinear,"curveTitle":"curveLinear"},
    {"d3Curve":d3.curveStep,"curveTitle":"curveStep"},
    {"d3Curve":d3.curveStepBefore,"curveTitle":"curveStepBefore"},
    {"d3Curve":d3.curveStepAfter,"curveTitle":"curveStepAfter"},
    {"d3Curve":d3.curveBasis,"curveTitle":"curveBasis"},
    {"d3Curve":d3.curveCardinal,"curveTitle":"curveCardinal"},
    {"d3Curve":d3.curveMonotoneX,"curveTitle":"curveMonotoneX"},
    {"d3Curve":d3.curveCatmullRom,"curveTitle":"curveCatmullRom"}
  ];

// parse the date / time
var parseTime = d3.timeParse("%d-%b-%y");

// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);

// define the line
var valueline = d3.line()
    .curve(d3.curveCatmullRomOpen)
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.close); });

// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");

// Get the data
d3.csv("data-3.csv", function(error, data) {
  if (error) throw error;

  // format the data
  data.forEach(function(d) {
      d.date = parseTime(d.date);
      d.close = +d.close;
  });

  // set the colour scale
  var color = d3.scaleOrdinal(d3.schemeCategory10);

  curveArray.forEach(function(daCurve,i) { 

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain(d3.extent(data, function(d) { return d.close; }));

    // Add the paths with different curves.
    svg.append("path")
      .datum(data)
      .attr("class", "line")
      .style("stroke", function() { // Add the colours dynamically
              return daCurve.color = color(daCurve.curveTitle); })
      .attr("id", 'tag'+i) // assign ID
      .attr("d", d3.line()
                   .curve(daCurve.d3Curve)
                   .x(function(d) { return x(d.date); })
                   .y(function(d) { return y(d.close); })
               );

    // Add the Legend
    svg.append("text")
        .attr("x", width+5)  // space legend
        .attr("y", margin.top + 20 + (i * 20))
        .attr("class", "legend")    // style the legend
        .style("fill", function() { // Add the colours dynamically
            return daCurve.color = color(daCurve.curveTitle); })
        .on("click", function(){
            // Determine if current line is visible 
            var active   = daCurve.active ? false : true,
            newOpacity = active ? 0 : 1; 
            // Hide or show the elements based on the ID
            d3.select("#tag"+i)
                .transition().duration(100) 
                .style("opacity", newOpacity); 
            // Update whether or not the elements are active
            daCurve.active = active;
            })  
        .text(daCurve.curveTitle);
  });

  // Add the scatterplot
  svg.selectAll("dot")
      .data(data)
    .enter().append("circle")
      .attr("r", 4)
      .attr("cx", function(d) { return x(d.date); })
      .attr("cy", function(d) { return y(d.close); });

  // Add the X Axis
  svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

  // Add the Y Axis
  svg.append("g")
      .attr("class", "axis")
      .call(d3.axisLeft(y));
});

</script>
</body>

data-3.csv

date,close
1-May-12,558.13
30-Apr-12,553.98
27-Apr-12,567.00
26-Apr-12,589.70
25-Apr-12,599.00
24-Apr-12,630.28
23-Apr-12,666.70
20-Apr-12,634.98
19-Apr-12,645.44
18-Apr-12,643.34
17-Apr-12,543.70
16-Apr-12,580.13
13-Apr-12,605.23
12-Apr-12,622.77
11-Apr-12,626.20
10-Apr-12,628.44
9-Apr-12,636.23
5-Apr-12,633.68
4-Apr-12,624.31
3-Apr-12,629.32
2-Apr-12,618.63
30-Mar-12,599.55
29-Mar-12,609.86
28-Mar-12,617.62
27-Mar-12,614.48
26-Mar-12,606.98