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;
}
...