JSFiddle - React, Tailwind, and code Playground
by Paolo Salvagione
CSS
html, body {
height: 100%;
overflow: hidden;
}
svg {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
circle {
opacity: .6;
cursor: pointer;
}
circle:hover {
opacity: 1;
}
path.face {
fill-opacity: .1;
}
line {
stroke: #ccc;
stroke-width: 1px;
stroke-linecap: round;
}
JavaScript
var width = 500,
height = 500,
svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height].join(" ")),
g = svg.append("g"),
rows = 8,
cols = 8,
grid = d3.range(0, rows + 1).map(function() { return []; }),
links = [],
nodes = [],
faces = [],
padding = 20,
dx = d3.scale.linear()
.domain([0, cols - 1])
.range([padding, width - padding]),
dy = d3.scale.linear()
.domain([0, rows - 1])
.range([padding, height - padding]);
for (var x = 0; x < cols; x++) {
for (var y = 0; y < rows; y++) {
var node = grid[y][x] = {x: dx(x), y: dy(y)};
nodes.push(node);
}
}
for (var x = 0; x < cols; x++) {
for (var y = 0; y < rows; y++) {
var node = grid[y][x];
if (x > 0) { makeLink(grid[y][x - 1], node); }
if (x < cols - 1) { makeLink(node, grid[y][x + 1]); }
if (y > 0) { makeLink(grid[y - 1][x], node); }
if (y < rows - 1) { makeLink(node, grid[y + 1][x]); }
if (x < cols - 1 && y < rows - 1) {
var face = [
node,
grid[y][x + 1],
grid[y + 1][x + 1],
grid[y + 1][x]
];
faces.push(face);
}
}
}
var line = svg.append("g")
.attr("class", "links")
.selectAll(".link")
.data(links)
.enter()
.append("line")
.attr("class", "link")
.call(linkPosition);
var poly = svg.append("g")
.attr("class", "faces")
.selectAll(".face")
.data(faces)
.enter()
.append("path")
.attr("class", "face")
.call(drawFace);
var drop = svg.append("g")
.attr("class", "dropped");
var dist = nodes[1].x - nodes[0].x;
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.linkStrength(.5)
.linkDistance(dist)
.charge(-200)
.on("tick", tick)
.start();
var circle = svg.append("g")
.attr("class", "nodes")
.selectAll(".node")
.data(nodes)
.enter()
.append("circle")
...