block by ee2dev fba676f35926b2705173564e13bf87cb

D3.js v4 Force Directed Graph with Labels

Full Screen

An example for stackoverflow https://stackoverflow.com/questions/55313363/d3-visualization-of-network-data-nodes-and-links-via-json-file/55315091

Compare to the original diagram by Mike Bostock.

forked from heybignick‘s block: D3.js v4 Force Directed Graph with Labels

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<head>
  <style>
    .links line {
      stroke: #999;
      stroke-opacity: 0.6;
    }

    .nodes circle {
      stroke: #fff;
      stroke-width: 1.5px;
    }

    text {
      font-family: sans-serif;
      font-size: 10px;
    }
  </style>
</head>
<body>
  <svg width="960" height="600"></svg>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>

  var svg = d3.select("svg"),
      width = +svg.attr("width"),
      height = +svg.attr("height");

  var color = d3.scaleOrdinal(d3.schemeCategory20);

  var simulation = d3.forceSimulation()
      .force("link", d3.forceLink().id(function(d) { return d.name; }))
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter(width / 2, height / 2));

  d3.json("miserables.json", function(error, graph) {
    if (error) throw error;
    
    graph.links = graph.links.map(function(ele) {
      return {
        source: ele.source, target: ele.dest, value: +ele.value
      }
    });

    var link = svg.append("g")
        .attr("class", "links")
      .selectAll("line")
      .data(graph.links)
      .enter().append("line")
        .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

    var node = svg.append("g")
        .attr("class", "nodes")
      .selectAll("g")
      .data(graph.nodes)
      .enter().append("g")

    var circles = node.append("circle")
        .attr("r", 5)
        .attr("fill", function(d) { return color(d.name); })
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

    var lables = node.append("text")
        .text(function(d) {
          return d.name; 
        })
        .attr('x', 6)
        .attr('y', 3);

    node.append("title")
        .text(function(d) { return d.name; });

    simulation
        .nodes(graph.nodes)
        .on("tick", ticked);

    simulation.force("link")
        .links(graph.links);

    function ticked() {
      link
          .attr("x1", function(d) { return d.source.x; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });

      node
          .attr("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
          })
    }
  });

  function dragstarted(d) {
    if (!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
  }

  function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }

  </script>
</body>
</html>

miserables.json

    {
  "nodes": [
    {
      "name": "ser1"
    },
    {
      "name": "ser2"
    },
    {
      "name": "ser3"
    },
    {
      "name": "ser4"
    },
    {
      "name": "ser5"
    }
  ],
  "links": [
    {
      "source": "ser1",
      "dest": "ser3",
      "value": "10"
    },
    {
      "source": "ser1",
      "dest": "ser5",
      "value": "10"
    },
    {
      "source": "ser2",
      "dest": "ser4",
      "value": "30"
    },
    {
      "source": "ser3",
      "dest": "ser4",
      "value": "10"
    },
    {
      "source": "ser3",
      "dest": "ser5",
      "value": "10"
    }
  ]
}