block by gabrielflorit 14435cead80c690105ebbbc35b75796f

f(x) = sin(a * sin(b * sin(c * sin(x))))

Full Screen

index.html

<!DOCTYPE html>
<head>
	<title>f(x) = sin(a * sin(b * sin(c * sin(x))))</title>
	<meta charset="utf-8">
	<style>
		path.line {
			stroke: red;
			stroke-width: 2px;
			fill: none;
		}
		.chart {
			width: 100%;
			overflow: hidden;
		}
		form {
			float: left;
			width: 250px;
		}
		svg {
			float: left;
		}
		form fieldset {
			border: none;
		}
	</style>
	<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>

	<h1>Tweak the sliders below!</h1>
	<div class='chart'>
		<form>

			<fieldset>
				<label>a:</label>
				<input id=a type=range min=1 max=10 step=1 oninput='draw()' value=1 />
				<output />
			</fieldset>

			<fieldset>
				<label>b:</label>
				<input id=b type=range min=1 max=10 step=1 oninput='draw()' value=2 />
				<output />
			</fieldset>

			<fieldset>
				<label>c:</label>
				<input id=c type=range min=1 max=10 step=1 oninput='draw()' value=3 />
				<output />
			</fieldset>

		</form>
		<svg />
	</div>
	<script>

		// This is for convenience - we'll use it to create the data
		var sin = Math.sin;

		// Setup chart dimensions and margins
		var margin = { top: 20, right: 20, bottom: 20, left: 20 };
		var width = 500 - margin.left - margin.right;
		var height = 300 - margin.top - margin.bottom;

		// Setup scales - notice no domain, we'll do that on chart render
		var x = d3.scaleLinear().range([0, width]);
		var y = d3.scaleLinear().range([height, 0]);

		// Setup line generator
		var line = d3.line()
			.x(function (d) { return x(d.x); })
			.y(function (d) { return y(d.y); });

		// Setup svg element
		var svg = d3.select('svg')
				.attr('width', width + margin.left + margin.right)
				.attr('height', height + margin.top + margin.bottom)
			.append('g')
				.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');

		// Create axes
		svg.append('g')
			.attr('class', 'axis axis--x')
			.attr('transform', 'translate(0,' + height/2 + ')')
			.call(d3.axisBottom(x));

		svg.append('g')
			.attr('class', 'axis axis--y')
			.attr('transform', 'translate(' + width/2 + ',0)')
			.call(d3.axisLeft(y));

		// Draw chart
		function draw() {

			// Grab slider values and update their <output /> tags
			var aNode = document.querySelector('#a');
			var a = aNode.value;
			aNode.parentNode.querySelector('output').textContent = a;

			var bNode = document.querySelector('#b');
			var b = bNode.value;
			bNode.parentNode.querySelector('output').textContent = b;

			var cNode = document.querySelector('#c');
			var c = cNode.value;
			cNode.parentNode.querySelector('output').textContent = c;

			// Construct the h1
			var title = 'f(x) = sin(' + a + ' * sin(' + b + ' * sin(' + c + ' * sin(x))))';
			document.querySelector('h1').textContent = title;

			// Construct data from a, b, c
			var data = d3.range(-10, 10, 0.01).map(function(v) {
				return {
					x: v,
					y: sin(a * sin(b * sin(c * sin(v))))
				};
			});

			// Get x,y extents
			var xMax = Math.abs(d3.max(data, function(d) { return d.x; }))
			var yMax = Math.abs(d3.max(data, function(d) { return d.y; }))

			// Set x,y domains
			x.domain([-xMax, xMax]);
			y.domain([-yMax, yMax]);

			// JOIN
			var paths = svg.selectAll('path.line')
				.data([data]);

			// ENTER
			paths.enter().append('path')
				.attr('class', 'line')
				// ENTER + UPDATE
				.merge(paths)
				.transition()
				.duration(500)
				.attr('d', line);

		}

		// Draw the initial chart - this will also be called every time we update the sliders
		draw();

	</script>
</body>
</html>