JSFiddle - React, Tailwind, and code Playground

by Paolo Salvagione

HTML

<svg></svg>

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")
     ...