Skip to content

Instantly share code, notes, and snippets.

@topologicallytony
Created August 18, 2017 17:07
Show Gist options
  • Save topologicallytony/70c3d7d328c05e5b247e12829cfd97e3 to your computer and use it in GitHub Desktop.
Save topologicallytony/70c3d7d328c05e5b247e12829cfd97e3 to your computer and use it in GitHub Desktop.
Wave 5
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Wave 5</title>
<!-- D3.js -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<style type="text/css">
</style>
</head>
<body>
<div id=svgContainer></div>
<script type="text/javascript">
//Width and height of the visualization. Smaller numbers will zoom in, larger numbers zoom out
var w = 500;
var h = 500;
//padding creates a buffer of white space around the chart to make it a little easier to look at
var padding = 20;
//This will hold the sampled function's data
var dataset = [];
var x = [];
var y = [];
var curr_t = 0;
//How finely to partition interval
var numDataPoints = 500;
//duration of a single transition in ms
var time = 3000;
//how fast will the frequency increase - another way to adjust time
var step = 1;
//initialize frequency of the function
var freq = 10;
//size of the circles, more data points should have smaller radii
var radius = 3;
//define y axis (domain of function)
//Note: if domain is 2pi then animation will reset after [numDataPoints] iterations
var y_min = 0;
var y_max = 2 * Math.PI;
//define x axis domain (range of function)
//var x_min = 2;
//var x_max = -2;
var x_min = 2*Math.exp(y_max);
var x_max = -2 * Math.exp(y_max);
//Generate a random sample of the space
for (var i = 1; i <= numDataPoints; i++) {
//Partition interval
var curr_t = ((i * (y_max - y_min)) / (numDataPoints)) + y_min;
//initialize as circle
var curr_x = Math.cos(curr_t);
var curr_y = Math.sin(curr_t);
dataset.push([curr_x, curr_y, curr_t]);
}
//Create x & y scales to convert points to proper svg canvas positions
var xScale = d3.scaleLinear()
.domain([-4, 4])
.range([padding, w + padding]);
var yScale = d3.scaleLinear()
.domain([-4, 4])
.range([h + padding, padding]);
//Create a canvas to display the chart on
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Make the background of the canvas white
svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#fff");
//Create group elements to layer the svg
//This is an easy way to make sure things you want on top are on top, and things you want behind stay behind
var layer1 = svg.append('g');
var layer2 = svg.append('g');
//'draw' the function using points sampled at a regular interval
function drawPts() {
var pts = layer2
.selectAll(".points")
.data(dataset);
pts
.enter()
.append("circle")
.attr("class", "points")
.attr("cy", function(d){ return yScale(d[1]); })
.attr("cx", function(d){ return xScale(d[0]); })
.attr("r", radius)
.attr("fill","steelblue");
pts
.transition()
.ease(d3.easeLinear)
.duration(time)
//transition the x position (aka the function value) from its current value to to its new value (the value after incrementing the amplitude). The transition path is determined by linearly interpolating the amplitude of the sine function between the two points
.attrTween('cx', function(d,i){
return function(t) {
return xScale((Math.cos(2 * Math.PI * t + d[2]) + 2) * Math.cos(freq * d[2]));
}
})
.attrTween('cy', function(d,i){
return function(t) {
return yScale((Math.sin(2 * Math.PI * t + d[2]) + 2 ) * Math.sin(freq * d[2]));
}
});
}
//initialize the animation
drawPts();
setInterval(function() {
drawPts();
}, time);
drawPts();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment