JSFiddle - React, Tailwind, and code Playground
by alexb
HTML
<svg width="480" height="320"></svg>
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: 9, group: 'tertiary' },
{ name: "b", count: 9, group: 'tertiary' },
{ name: "c", count: 8, group: 'tertiary' },
{ name: "d", count: 8, group: 'tertiary' },
{ name: "e", count: 8, group: 'tertiary' },
{ name: "f", count: 7, group: 'tertiary' },
{ name: "g", count: 7, group: 'tertiary' },
{ name: "h", count: 6, group: 'tertiary' },
{ name: "i", count: 6, group: 'tertiary' },
{ name: "j", count: 5, group: 'tertiary' },
{ name: "k", count: 5, group: 'tertiary' },
],
links: [
{ source: "Tech", target: "Bigfour" },
{ source: "Tech", target: "Techgiants" },
{ source: "Bigfour", target: "a" },
{ source: "Bigfour", target: "b" },
{ source: "Bigfour", target: "c" },
{ source: "Bigfour", target: "d" },
{ source: "Bigfour", target: "e" },
{ source: "Bigfour", target: "f" },
{ source: "Techgiants", target: "g" },
{ source: "Techgiants", target: "h" },
{ source: "Techgiants", target: "i" },
{ source: "Techgiants", target: "j" },
{ source: "Techgiants", target: "k" },
],
}
const svg = d3.select('svg');
const width = +svg.attr('width');
const height = +svg.attr('height');
// Fix root topic to center.
data.nodes[0].fx = width / 2;
data.nodes[0].fy = height / 2;
const simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(d => d.name))
// Strength here attracts/repels all nodes to/from each other.
.force("charge", d3.forceManyBody().strength(d => Math.sqrt(d.count) * -10))
.force("collide", d3.forceCollide().radius(d => d.count))
.force("forceY", d3.forceY(height / 2).strength(0.02))
.force("center", d3.forceCenter(width / 2, height / 2))
/*.force("groups", d3.forceX(d => {
const x = ["primary",...