JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
  <div class="background">
  </div>
  </body>

CSS

body {
  padding: 0;
  margin: 0;
}
.background {
  width: 500px;
  height: 300px;
  border: 1px solid #007aff;
}
.message {
  display: inline-block;
  font-family: sans-serif;
  border-radius: 100vh;
  color: white;
  padding: 10px;
  background-color: #007aff;
  position: absolute;
}
.boundary {
  display: inline-block;
  width: 10px;
  height: 10px;
  background-color: red;
  position: absolute;
}

JavaScript

var background = d3.select('.background');

var width = background.node().getBoundingClientRect().width,
	height = background.node().getBoundingClientRect().height;

var nodes = d3.range(50).map(function(d, i) {
		return {
      		text: "Hello"
		};
	});

var messages = background.selectAll('.message')
	.data(nodes)
	.enter()
		.append('div')
		.attr('class', 'message')
		.text(d => d.text)
		.each(function(d, i) {
			d.width = this.getBoundingClientRect().width;
			d.height = this.getBoundingClientRect().height;
		});

var force = d3.forceSimulation(nodes)
.force("charge", d3.forceManyBody().strength(-10))
.force("collide", d3.forceCollide(30).strength(1).iterations(1))
.force('x', d3.forceX(width/2).strength(0.5))
.force('y', d3.forceY(height/2).strength(10));


force.on('tick', function(e) {
	messages.each(d => {
		d.x = Math.max(20, Math.min(width - (d.width+20), d.x));
		d.y = Math.max(20, Math.min(height - (d.height+20), d.y));
	});
	
	messages.style('left', d => `${d.x}px`)
		.style('top', d => `${d.y}px`);
});