JSFiddle - React, Tailwind, and code Playground

by alexb

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.1/seedrandom.min.js"></script>
<svg width="480" height="320"></svg>
<div>Click to reset the simulation</div>

CSS

body {
  background: ghostwhite;
}

svg {
  background: white;
}

.links line {
  stroke: gray;
  stroke-opacity: 0.5;
  stroke-dasharray: 2 2;
}

.nodes circle.primary {
  fill: rgb(88, 80, 70);
  stroke: rgb(221, 222, 217);
  stroke-width: 4px;
}

.nodes circle.secondary {
  fill: rgb(215, 193, 168);
}

.nodes circle.tertiary {
  fill: rgb(190, 190, 190);
}

JavaScript 1.7

// Group property just sets a CSS class for styling.
const data = {
	nodes: [
  	{ name: "Tech", count: 48, group: 'primary' },
  	{ name: "Bigfour", count: 30, group: 'secondary' },
  	{ name: "Techgiants", count: 14, group: 'secondary' },
  	{ name: "a", count: 8, group: 'tertiary' },
  	{ name: "b", count: 8, group: 'tertiary' },
  	{ name: "c", count: 8, group: 'tertiary' },
  	{ name: "d", count: 8, group: 'tertiary' },
  	{ name: "e", count: 8, group: 'tertiary' },
  	{ name: "f", count: 8, group: 'tertiary' },
  	{ name: "g", count: 8, group: 'tertiary' },
  	{ name: "h", count: 8, group: 'tertiary' },
  	{ name: "i", count: 8, group: 'tertiary' },
  	{ name: "j", count: 8, group: 'tertiary' },
  	{ name: "k", count: 8, group: 'tertiary' },
  ],
	links: [
  	{ source: 0, target: 1 },
  	{ source: 0, target: 2 },
  	{ source: 1, target: 3 },
  	{ source: 1, target: 4 },
  	{ source: 1, target: 5 },
  	{ source: 1, target: 6 },
  	{ source: 1, target: 7 },
  	{ source: 1, target: 8 },
  	{ source: 2, target: 9 },
  	{ source: 2, target: 10 },
  	{ source: 2, target: 11 },
  	{ source: 2, target: 12 },
  	{ source: 2, target: 13 },
  ],
}

const svg = d3.select('svg');
const scaleY = 0.75;
const width = +svg.attr('width');
const height = +svg.attr('height') / scaleY;

svg.append('g').attr('class', 'links');
svg.append('g').attr('class', 'nodes');

// Fix root topic to center.
data.nodes[0].x = width / 2;
data.nodes[0].y = height / 2;
data.nodes[0].fixed = true;

let force;
function start() {
	if (force) {
  	force.stop();
  }
  
  const nodes = data.nodes.map(d => Object.assign({}, d));
  const links = data.links.map(d => Object.assign({}, d));

	const rng = new Math.seedrandom();//nodes[0].name);

  for (let i = 1; i < nodes.length; i++) {
  	const x = Math.cos(rng.quick() * Math.PI * 2);
  	const y = Math.sin(rng.quick() * Math.PI * 2);
    const r = 30 + rng.quick() * height / 3;
    nodes[i].x = width / 2 + x * r;
    nodes[i].y = height / 2 + y * r;
  }
...