block by bycoffe 3404776

Placing n elements around a circle with radius r

Full Screen

This demonstrates the math used to create the “seating chart”-style shapes on our House Outlook page.

index.html

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      * { 
        font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;
        font-size:13px;
      }
      circle {
        fill: steelblue;
        fill-opacity: .8;
      }
    </style>
  </head>

  <body>
    <form>
      <label for="radius">Radius:</label>
      <input type="text" id="radius" name="radius" value=200>

      <label for="numNodes">Number of elements:</label>
      <input type="text" id="numNodes" name="radius" value=100>
    </form>

    <div id="canvas"></div>

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript" src="//mbostock.github.com/d3/d3.v2.min.js"></script>
    <script type="text/javascript">
      (function() {

       var createNodes = function (numNodes, radius) {
         var nodes = [], 
             width = (radius * 2) + 50,
             height = (radius * 2) + 50,
             angle,
             x,
             y,
             i;
         for (i=0; i<numNodes; i++) {
          angle = (i / (numNodes/2)) * Math.PI; // Calculate the angle at which the element will be placed.
                                                // For a semicircle, we would use (i / numNodes) * Math.PI.
          x = (radius * Math.cos(angle)) + (width/2); // Calculate the x position of the element.
          y = (radius * Math.sin(angle)) + (width/2); // Calculate the y position of the element.
          nodes.push({'id': i, 'x': x, 'y': y});
         }
         return nodes;
       }

       var createSvg = function (radius, callback) {
         d3.selectAll('svg').remove();
         var svg = d3.select('#canvas').append('svg:svg')
                    .attr('width', (radius * 2) + 50)
                    .attr('height', (radius * 2) + 50);
         callback(svg);
       }

       var createElements = function (svg, nodes, elementRadius) {
         element = svg.selectAll('circle')
                        .data(nodes)
                      .enter().append('svg:circle')
                        .attr('r', elementRadius)
                        .attr('cx', function (d, i) {
                          return d.x;
                        })
                        .attr('cy', function (d, i) {
                          return d.y;
                        });
       }

       var draw = function () {
         var numNodes = $("#numNodes").val() || 100;
         var radius = $("#radius").val() || 200;
         var nodes = createNodes(numNodes, radius);
         createSvg(radius, function (svg) {
           createElements(svg, nodes, 5);
         });
       }

      $(document).ready(function() {
          draw();
      });

      $("#radius, #numNodes").bind('keyup', function(e) {
          draw();
      });

      })();
    </script>
  </body>
</html>