Skip to content

Instantly share code, notes, and snippets.

@clhenrick
Created April 24, 2017 21:26
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 clhenrick/41cf59742a5942e1f19929405c188100 to your computer and use it in GitHub Desktop.
Save clhenrick/41cf59742a5942e1f19929405c188100 to your computer and use it in GitHub Desktop.
Sinusoidal interpolation
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
var svg = d3.select("body").append("svg")
.attr("width", width = 960)
.attr("height", height = 500)
var parset = d3.timeParse('%m/%d/%y %H:%M');
var data = d3.csvParse(`Date_Time,Event,Speed
3/31/17 0:24,flood,1.59
3/31/17 3:42,slack,0
3/31/17 7:12,ebb,-1.86
3/31/17 10:30,slack,0
3/31/17 13:12,flood,1.43
3/31/17 17:00,slack,0
3/31/17 20:00,ebb,-1.45
3/31/17 22:42,slack,0
4/1/17 1:12,flood,1.48
4/1/17 4:24,slack,0
4/1/17 8:06,ebb,-1.74
4/1/17 11:30,slack,0
4/1/17 14:06,flood,1.23
4/1/17 18:06,slack,0
4/1/17 21:00,ebb,-1.25
4/1/17 23:36,slack,0`)
.map(d => {
d.time = +parset(d.Date_Time);
d.speed = +d.Speed;
return d;
});
var x = d3.scaleLinear()
.domain(d3.extent(data.map(d => d.time)))
.range([0,width]);
var y = d3.scaleLinear()
.domain(d3.extent(data.map(d => d.speed)))
.range([height,0]);
function inter(t){
var prev = d3.bisectLeft(data.map(d => d.time), t)-1,
r = 0;
if (!data[prev]) return 0;
var alpha = (t - data[prev].time) / (data[prev+1].time - data[prev].time);
if (data[prev].Event == 'slack')
alpha = Math.sin(Math.PI/2 * alpha);
else
alpha = 1-Math.cos(Math.PI/2 * alpha);
r = d3.interpolateNumber(data[prev].speed, data[prev+1].speed)(alpha);
return r;
}
var line = d3.line().x(x).y(u => y(inter(u)));
svg.append('path')
.attr('fill', 'none')
.attr('stroke', 'lightblue')
.attr('d', line(d3.range(...x.domain(),36000)))
svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('r', 4)
.attr('cx', d => x(d.time))
.attr('cy', d => y(d.speed))
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment