Skip to content

Instantly share code, notes, and snippets.

@micahstubbs
Created July 15, 2016 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micahstubbs/d1990e6f558a1ad159c93a66d0556f30 to your computer and use it in GitHub Desktop.
Save micahstubbs/d1990e6f558a1ad159c93a66d0556f30 to your computer and use it in GitHub Desktop.
v4 curve interpolation comparison
license: CC0-1.0
border: no

your favorite v4 curve interpolation demo, now with handy all and none selection buttons in the legend 🎉

this iteration also formats the x-axis tick labels as three-digit days of the year to resolve a label occlusion issue found with the default format, where 3/31 overplots it's neighbor 4/1. can't have that, now can we?

  var xAxis = d3.axisBottom(x)
    .tickFormat(d3.timeFormat('%j'));

more on time formatting with d3 v4 https://github.com/d3/d3-time-format#locale_format

a fork of the bl.ock v4 curve interpolation comparison from @d3noob


Original README.md:


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.

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
<!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 'all' option to the Legend
svg.append("text")
.attr("x", width+5) // space legend
.attr("y", margin.top + 20 + (8 * 20))
.attr("class", "legend") // style the legend
.style("fill", function() { // Add the colours dynamically
return d3.schemeCategory10[8];
})
.on("click", function(){
d3.selectAll(".line")
.transition().duration(100)
.style("opacity", 1);
})
.text("all");
// Add the 'none'option to the Legend
svg.append("text")
.attr("x", width+5) // space legend
.attr("y", margin.top + 20 + (9 * 20))
.attr("class", "legend") // style the legend
.style("fill", function() { // Add the colours dynamically
return d3.schemeCategory10[9];
})
.on("click", function(){
d3.selectAll(".line")
.transition().duration(100)
.style("opacity", 0);
})
.text("none");
// 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); });
// Configure the X Axis generator
var xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat('%j'));
// Add the X Axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y));
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment