<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>ID-based force layout</title>
  <link type="text/css" href="style.css" rel="stylesheet" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
  <script src="script.js"></script>
</head>

<body>
  <svg id="chart"></svg>
</body>

</html>
// Code goes here

(function() {


  var data = {
    'nodes': [{
      'id': 'A',
      'x': 469,
      'y': 410
    }, {
      'id': 'B',
      'x': 493,
      'y': 364
    }, {
      'id': 'C',
      'x': 442,
      'y': 365
    }, {
      'id': 'D',
      'x': 467,
      'y': 314
    }, {
      'id': 'E',
      'x': 477,
      'y': 248
    }, {
      'id': 'F',
      'x': 425,
      'y': 207
    }, {
      'id': 'G',
      'x': 402,
      'y': 155
    }, {
      'id': 'H',
      'x': 369,
      'y': 196
    }, {
      'id': 'I',
      'x': 350,
      'y': 148
    }, {
      'id': 'J',
      'x': 539,
      'y': 222
    }, {
      'id': 'K',
      'x': 594,
      'y': 235
    }, {
      'id': 'L',
      'x': 582,
      'y': 185
    }, {
      'id': 'M',
      'x': 633,
      'y': 200
    }],
    'links': [{
      'source': 'A',
      'target': 'B'
    }, {
      'source': 'B',
      'target': 'C'
    }, {
      'source': 'C',
      'target': 'A'
    }, {
      'source': 'B',
      'target': 'D'
    }, {
      'source': 'D',
      'target': 'C'
    }, {
      'source': 'D',
      'target': 'E'
    }, {
      'source': 'E',
      'target': 'F'
    }, {
      'source': 'F',
      'target': 'G'
    }, {
      'source': 'F',
      'target': 'H'
    }, {
      'source': 'G',
      'target': 'H'
    }, {
      'source': 'G',
      'target': 'I'
    }, {
      'source': 'H',
      'target': 'I'
    }, {
      'source': 'J',
      'target': 'E'
    }, {
      'source': 'J',
      'target': 'L'
    }, {
      'source': 'J',
      'target': 'K'
    }, {
      'source': 'K',
      'target': 'L'
    }, {
      'source': 'L',
      'target': 'M'
    }, {
      'source': 'M',
      'target': 'K'
    }]
  }
  
  var d3color = d3.scale.category20()

  var width = 960,
    height = 500

  var force = d3.layout.force()
    .size([width, height])
    .linkDistance(20)
    .charge(-30)
    .gravity(0.1)
    .linkStrength(1)
    .friction(0.9)
    .theta(0.8)
    .alpha(0.1)
    .on("tick", tick);



  var svg = d3.select('#chart')
    .attr("width", width)
    .attr("height", height);

  var drag = force.drag()
    .on("dragstart", dragstart);

  var link, node
  var nodes = data.nodes
  var edges = [];
  data.links.forEach(function(e) {
    var sourceNode = data.nodes.filter(function(n) {
        return n.id === e.source;
      })[0],
      targetNode = data.nodes.filter(function(n) {
        return n.id === e.target;
      })[0];

    edges.push({
      source: data.nodes.indexOf(sourceNode),
      target: data.nodes.indexOf(targetNode),
      value: e.value
    });
  });
  links = edges


  force
    .nodes(nodes)
    .links(links)
    .start();

  link = svg.selectAll(".link")
    .data(links)
    .enter().append("line")
    .attr("class", "link");


  node = svg.selectAll(".node")
    .data(nodes)
    .enter().append("g")
    .attr("class", "node")
    .on("dblclick", dblclick)
    .append('circle')
    .attr('r', 10)
    .style("fill", function(d) {
      return d3color(d.group)
    })
    .call(force.drag);




  node.append("text")
    .attr("dx", 12)
    .attr("dy", ".35em")
    .text(function(d) {
      
      return d.id
    });


  node.append("title").text(function(d) {
    return d.name ? d.name : (d.id ? d.id : '')
  });


  function tick() {
    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 dblclick(d) {
    d3.select(this).classed("fixed", d.fixed = false);
  }

  function dragstart(d) {
    d3.select(this).classed("fixed", d.fixed = true);
  }

})();
/* Styles go here */

.node > circle {
  stroke-width: 2px;
  stroke: gray;
  fill: #dddddd;
}

.node > text {
  pointer-events: none;
  font-family: sans-serif;
  text-anchor: middle;
}

.link {
  stroke-width: 2px;
  stroke: lightgrey;
}