JSFiddle - React, Tailwind, and code Playground

by CoolBlue

HTML

<div id="vizcontainer"></div>

CSS

body, html {
      width:100%;
      height:100%;
  }
    #vizcontainer {
      width: 100%;
      height: 100%;
    }

   svg {
      outline: 1px solid red;
      width: 100%;
      height: 100%;
    }

    .output {
      pointer-events: none;  
      display: inline-block;
      z-index: 1;
      margin: 10px;
      outline: 1px solid red;
    }

JavaScript

;(function() {
var w = 90, h = 400, nodes = [], touch,

        svg = d3.select("#vizcontainer").append("svg")
				.attr("width", w)
				.attr("height", h),

        force = d3.layout.force()
        .size([w, h])
        .gravity(0)
        .charge(1)
        .friction(0.7),

              outputDiv = d3.select("body").insert("div", "#vizcontainer").attr("id", "output").attr("class", "output"),
              touchesDiv = d3.select("body").insert("div", "#output").attr("id", "touches")
              .style("margin-right", "10px").attr("class", "output");



    force.on("tick", function (e) {
      outputDiv.text("alpha:\t" + d3.format(".3f")(force.alpha())
        + "\tnodes:\t" + force.nodes().length)
      svg.selectAll("circle")
      .attr("cx", function (d) { return d.x; })
      .attr("cy", function (d) { return d.y; });
    });

    svg.on("mousemove", onMove);
    svg.on("touchmove", onTouch);
    svg.on("touchstart", onTouch);

    function onMove() {
      updateMethod.call(this)
    }
    function onTouch() {
      d3.event.preventDefault();
      d3.event.stopPropagation();
      updateMethod.call(this)
    }

    function idiomatic() {
      force.nodes(nodes);
      return function () {
        var pointM = d3.mouse(this), pointT = d3.touches(this),
            point = pointT.length ? pointT[0] : pointM
          node = { x: point[0], y: point[1] };

          touchesDiv.text(pointT.length ? pointT : "mouse");

        nodes.push(node);

        svg.selectAll("circle")
        .data(nodes)
        .enter().append("circle")
        .attr("r", 1e-6)
        .transition("in")
        .attr("r", 4.5)
        .transition("out")
        .delay(1000)
        .attr("r", 1e-6)
        .remove()
        .each("end.out", (function (n) {
          return function (d, i) {
            //console.log("length: " + nodes.length + "\tdeleting " + i)
            var i = nodes.indexOf(n);
            nodes.splice(i, 1)
          }
        })(node));

       ...