Constructed in the video tutorial: The Pentagon. Inspired by a figure from chapter 5 of Tamara Munzner's excellent book "Visualization Analysis and Design".
Built with blockbuilder.org
| license: mit |
Constructed in the video tutorial: The Pentagon. Inspired by a figure from chapter 5 of Tamara Munzner's excellent book "Visualization Analysis and Design".
Built with blockbuilder.org
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| </head> | |
| <body> | |
| <svg width="960" height="500"></svg> | |
| <script> | |
| var rotateAngle = 1; | |
| var length = 1; | |
| var reverse = false; | |
| setInterval(function() { | |
| reRender(); | |
| }, 10); | |
| function reRender() { | |
| d3.selectAll("svg > *").remove(); | |
| rotateAngle += 1; | |
| if (rotateAngle === 361) { | |
| rotateAngle = 1; | |
| } | |
| if (reverse === false && length > 300) { | |
| reverse = true; | |
| } | |
| if (length < 0) { | |
| reverse = false; | |
| } | |
| if (reverse) { | |
| length -= 1; | |
| } else { | |
| length += 1; | |
| } | |
| drawCircle(rotateAngle, 50, length); | |
| } | |
| function drawCircle(rotateAngle, numPoints, length) { | |
| const svg = d3.select('svg'); | |
| const width = svg.attr('width'); | |
| const height = svg.attr('height'); | |
| const centerX = width / 2; | |
| const centerY = height / 2; | |
| const radius = length; | |
| const points = d3.range(numPoints) | |
| .map(i => { | |
| const angle = i / numPoints * Math.PI * 2 + rotateAngle; | |
| return { | |
| x: Math.sin(angle) * radius + centerX, | |
| y: Math.cos(angle) * radius + centerY | |
| }; | |
| }); | |
| const spokes = points.map(point => ({ | |
| x1: centerX, | |
| y1: centerY, | |
| x2: point.x, | |
| y2: point.y | |
| })); | |
| const wheelLines = d3.range(numPoints).map(i => ({ | |
| x1: points[i].x, | |
| y1: points[i].y, | |
| x2: points[(i + 1) % numPoints].x, | |
| y2: points[(i + 1) % numPoints].y | |
| })); | |
| const lines = spokes.concat(wheelLines); | |
| svg.selectAll('line').data(lines) | |
| .enter().append('line') | |
| .attr('x1', d => d.x1) | |
| .attr('y1', d => d.y1) | |
| .attr('x2', d => d.x2) | |
| .attr('y2', d => d.y2) | |
| .attr('stroke', 'black') | |
| .attr('stroke-width', 2); | |
| } | |
| </script> | |
| </body> |