D3 force-directed graph drawing

by AndreaLigios

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.4/d3.js"></script>
<svg width="960" height="600"></svg>

CSS

svg {
  background: white;
}

.links line {
  stroke: #aaa;
}

.node circle {
  pointer-events: all;
  stroke: none;
  stroke-width: 40px;
}

JavaScript

var jsonData = '{"nodes": [{"id": "Dell", "group" : 1, "image":"https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Dell_Logo.svg/2000px-Dell_Logo.svg.png"},{"id": "Apple", "group" : 1, "image":"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Apple_logo_black.svg/1000px-Apple_logo_black.svg.png"},{"id": "Microsoft", "group" : 1, "image":"https://pbs.twimg.com/profile_images/709852306632744960/zQ0xyGGK.jpg"}], "links": [{"source": "Dell","target": "Microsoft","value": 1},{"source": "Microsoft","target": "Apple","value": 3},{"source": "Apple","target": "Dell","value": 2}]}';

var w = 960,
  h = 600;

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

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


var graph = JSON.parse(jsonData);


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

var node = svg.selectAll("g.node")
  .data(graph.nodes)
  .enter().append("svg:g")
  .attr("class", "node")
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));


node.append("svg:image")
  .attr("class", "circle")
  .attr("xlink:href", function(d) {
    return d.image
  })
  .attr("x", "-40px")
  .attr("y", "-25px")
  .attr("width", "50px")
  .attr("height", "50px");
//.attr("border-radius", "50%");

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

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;
   ...