<svg width="960" height="600"></svg>

<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://measure-fps.surge.sh/measureFPS.js">
</script>
<script src="https://intervis-projects.ccs.neu.edu/ssvg/ssvg.js"></script>
.nodes circle {
        stroke: #fff;
        stroke-width: 1.5px;
    }
new SSVG({getFps: function(fps) {
      const fpsElement = document.getElementById("fps-element");
      fpsElement.innerHTML = fps;
    }});

var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeAccent);

function getCircle(cx, cy, r) {
  return {
    getPointFromAngle: function(angle) {
      return {
        x: cx + Math.sin(angle) * r,
        y: cy - Math.cos(angle) * r
      }
    }
  };
}

function getRandomString(numberOfCharacters) {
  var alphabet = '0123456789abcdef';
  var returnString = '';

  for(var i = 0; i < numberOfCharacters; i++) {
    returnString += alphabet[Math.floor(Math.random() * alphabet.length)];
  }
  return returnString;
}

var data = [];
for(var i = 0; i < 3000; i++) {
  const circle = getCircle(300, 300, 100 + Math.random() * 200);
  data.push({
    color: '#' + getRandomString(6), //color(Math.floor(Math.random() * 20)),
    circle: circle,
    angle: 0,
    angularSpeed: 0.001 + Math.random() * 0.01,
    position: circle.getPointFromAngle(0),
    id: i
  });
}

var updates = 0;
function updatePositions() {
  updates++;
  data.forEach(function(data, i) {
    var angle = data.angle;
    const circle = data.circle;
    if(updates > i) {
      angle += data.angularSpeed;
    }
    data.angle = angle;
    data.position = circle.getPointFromAngle(angle);
  })
}

function updateVis() {
  var circles = svg.selectAll('rect')
    .data(data, function(d) { return d.id });

  circles.enter()
    .append('rect')
    .attr('width', 5)
    .attr('height', 5)
    .attr('fill', function(d) { return d.color });

  circles
    .attr('x', function(d) {return d.position.x })
    .attr('y', function(d) {return d.position.y });
}

const raf = function() {
  updatePositions();
  updateVis();

  requestAnimationFrame(raf);
};
raf();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.