block by fogonwater 60c226a931bce550155e79d7ae93e0fa

D3.js v4 Force Directed Graph with Labels

Full Screen

A quick adaptation of Mike Bostock’s force-directed graph showing character co-occurence in Les Misérables. In this version, the character names are displayed. This is accomplished by wrapping both circles and text svg components within a group svg component.

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">
<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>
<svg width="960" height="960"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
console.clear()
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.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

d3.json("miserables.json", function(error, graph) {
  if (error) throw error;

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

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("g")
    .data(graph.nodes)
    .enter().append("g")
    
  var circles = node.append("circle")
      .attr("r", (d) => Math.sqrt(d.value) * 30)
      .attr("fill", 'steelblue')
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

  var labels = node.append("text")
      .text((d) => d.name + ' ' + Math.round(d.value * 100) + '%')
      .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>

miserables.json

{
  "links": [
    {
      "source": 13,
      "target": 14,
      "value": 0.174
    },
    {
      "source": 6,
      "target": 7,
      "value": 0.14
    },
    {
      "source": 13,
      "target": 15,
      "value": 0.139
    },
    {
      "source": 13,
      "target": 16,
      "value": 0.125
    },
    {
      "source": 13,
      "target": 17,
      "value": 0.116
    },
    {
      "source": 14,
      "target": 27,
      "value": 0.092
    },
    {
      "source": 16,
      "target": 33,
      "value": 0.091
    },
    {
      "source": 13,
      "target": 18,
      "value": 0.085
    },
    {
      "source": 17,
      "target": 34,
      "value": 0.079
    },
    {
      "source": 13,
      "target": 19,
      "value": 0.071
    },
    {
      "source": 15,
      "target": 28,
      "value": 0.07
    },
    {
      "source": 13,
      "target": 20,
      "value": 0.052
    },
    {
      "source": 7,
      "target": 8,
      "value": 0.046
    },
    {
      "source": 1,
      "target": 2,
      "value": 0.04
    },
    {
      "source": 13,
      "target": 21,
      "value": 0.038
    },
    {
      "source": 15,
      "target": 30,
      "value": 0.037
    },
    {
      "source": 20,
      "target": 43,
      "value": 0.035
    },
    {
      "source": 18,
      "target": 39,
      "value": 0.034
    },
    {
      "source": 15,
      "target": 29,
      "value": 0.032
    },
    {
      "source": 14,
      "target": 23,
      "value": 0.031
    },
    {
      "source": 7,
      "target": 9,
      "value": 0.028
    },
    {
      "source": 18,
      "target": 37,
      "value": 0.028
    },
    {
      "source": 19,
      "target": 40,
      "value": 0.028
    },
    {
      "source": 7,
      "target": 12,
      "value": 0.027
    },
    {
      "source": 19,
      "target": 41,
      "value": 0.027
    },
    {
      "source": 21,
      "target": 46,
      "value": 0.026
    },
    {
      "source": 14,
      "target": 24,
      "value": 0.024
    },
    {
      "source": 17,
      "target": 36,
      "value": 0.023
    },
    {
      "source": 18,
      "target": 38,
      "value": 0.023
    },
    {
      "source": 2,
      "target": 3,
      "value": 0.022
    },
    {
      "source": 7,
      "target": 10,
      "value": 0.022
    },
    {
      "source": 13,
      "target": 22,
      "value": 0.02
    },
    {
      "source": 16,
      "target": 31,
      "value": 0.02
    },
    {
      "source": 7,
      "target": 11,
      "value": 0.017
    },
    {
      "source": 14,
      "target": 25,
      "value": 0.017
    },
    {
      "source": 19,
      "target": 42,
      "value": 0.016
    },
    {
      "source": 16,
      "target": 32,
      "value": 0.014
    },
    {
      "source": 17,
      "target": 35,
      "value": 0.014
    },
    {
      "source": 21,
      "target": 47,
      "value": 0.013
    },
    {
      "source": 20,
      "target": 44,
      "value": 0.012
    },
    {
      "source": 2,
      "target": 4,
      "value": 0.011
    },
    {
      "source": 22,
      "target": 48,
      "value": 0.011
    },
    {
      "source": 14,
      "target": 26,
      "value": 0.01
    },
    {
      "source": 22,
      "target": 49,
      "value": 0.009
    },
    {
      "source": 2,
      "target": 5,
      "value": 0.007
    },
    {
      "source": 20,
      "target": 45,
      "value": 0.005
    }
  ],
  "nodes": [
    {
      "group": 1,
      "id": 1,
      "name": "_Communicable",
      "value": 0.04
    },
    {
      "group": 1,
      "id": 2,
      "name": "Communicable",
      "value": 0.04
    },
    {
      "group": 1,
      "id": 3,
      "name": "Neonatal",
      "value": 0.022
    },
    {
      "group": 1,
      "id": 4,
      "name": "Congenital birth defects",
      "value": 0.011
    },
    {
      "group": 1,
      "id": 5,
      "name": "Other communicable",
      "value": 0.007
    },
    {
      "group": 1,
      "id": 6,
      "name": "_Injuries",
      "value": 0.14
    },
    {
      "group": 1,
      "id": 7,
      "name": "Injuries",
      "value": 0.14
    },
    {
      "group": 1,
      "id": 8,
      "name": "Falls",
      "value": 0.046
    },
    {
      "group": 1,
      "id": 9,
      "name": "Road injuries",
      "value": 0.028
    },
    {
      "group": 1,
      "id": 10,
      "name": "Self-harm",
      "value": 0.022
    },
    {
      "group": 1,
      "id": 11,
      "name": "Mechanical forces",
      "value": 0.017
    },
    {
      "group": 1,
      "id": 12,
      "name": "Other injuries",
      "value": 0.027
    },
    {
      "group": 1,
      "id": 13,
      "name": "Non-communicable diseases",
      "value": 0.82
    },
    {
      "group": 1,
      "id": 14,
      "name": "Cancers",
      "value": 0.174
    },
    {
      "group": 1,
      "id": 15,
      "name": "Cardiovascular disease",
      "value": 0.139
    },
    {
      "group": 1,
      "id": 16,
      "name": "Other non-communicable diseases",
      "value": 0.125
    },
    {
      "group": 1,
      "id": 17,
      "name": "Musculoskeletal conditions",
      "value": 0.116
    },
    {
      "group": 1,
      "id": 18,
      "name": "Mental disorders",
      "value": 0.085
    },
    {
      "group": 1,
      "id": 19,
      "name": "Neurological disorders",
      "value": 0.071
    },
    {
      "group": 1,
      "id": 20,
      "name": "Chronic respiratory diseases",
      "value": 0.052
    },
    {
      "group": 1,
      "id": 21,
      "name": "Diabetes, chronic kidney diseases",
      "value": 0.038
    },
    {
      "group": 1,
      "id": 22,
      "name": "Substance use disorders",
      "value": 0.02
    },
    {
      "group": 1,
      "id": 23,
      "name": "Tracheal, bronchus, lung cancer",
      "value": 0.031
    },
    {
      "group": 1,
      "id": 24,
      "name": "Colon and rectum cancer",
      "value": 0.024
    },
    {
      "group": 1,
      "id": 25,
      "name": "Breast cancer",
      "value": 0.017
    },
    {
      "group": 1,
      "id": 26,
      "name": "Prostate cancer",
      "value": 0.01
    },
    {
      "group": 1,
      "id": 27,
      "name": "Other cancers",
      "value": 0.092
    },
    {
      "group": 1,
      "id": 28,
      "name": "Ischemic heart disease",
      "value": 0.07
    },
    {
      "group": 1,
      "id": 29,
      "name": "Stroke",
      "value": 0.032
    },
    {
      "group": 1,
      "id": 30,
      "name": "Other cardiovascular",
      "value": 0.037
    },
    {
      "group": 1,
      "id": 31,
      "name": "Age-related and other hearing loss",
      "value": 0.02
    },
    {
      "group": 1,
      "id": 32,
      "name": "Oral disorders",
      "value": 0.014
    },
    {
      "group": 1,
      "id": 33,
      "name": "Other other non-communicable",
      "value": 0.091
    },
    {
      "group": 1,
      "id": 34,
      "name": "Low back pain",
      "value": 0.079
    },
    {
      "group": 1,
      "id": 35,
      "name": "Neck pain",
      "value": 0.014
    },
    {
      "group": 1,
      "id": 36,
      "name": "Other musculoskeletal",
      "value": 0.023
    },
    {
      "group": 1,
      "id": 37,
      "name": "Anxiety disorders",
      "value": 0.028
    },
    {
      "group": 1,
      "id": 38,
      "name": "Depressive disorders",
      "value": 0.023
    },
    {
      "group": 1,
      "id": 39,
      "name": "Other mental",
      "value": 0.034
    },
    {
      "group": 1,
      "id": 40,
      "name": "Headache disorders",
      "value": 0.028
    },
    {
      "group": 1,
      "id": 41,
      "name": "Alzheimer's disease and other dementias",
      "value": 0.027
    },
    {
      "group": 1,
      "id": 42,
      "name": "Other neurological",
      "value": 0.016
    },
    {
      "group": 1,
      "id": 43,
      "name": "Chronic obstructive pulmonary disease",
      "value": 0.035
    },
    {
      "group": 1,
      "id": 44,
      "name": "Asthma",
      "value": 0.012
    },
    {
      "group": 1,
      "id": 45,
      "name": "Other respiratory",
      "value": 0.005
    },
    {
      "group": 1,
      "id": 46,
      "name": "Diabetes mellitus",
      "value": 0.026
    },
    {
      "group": 1,
      "id": 47,
      "name": "Chronic kidney disease",
      "value": 0.013
    },
    {
      "group": 1,
      "id": 48,
      "name": "Drug use disorders",
      "value": 0.011
    },
    {
      "group": 1,
      "id": 49,
      "name": "Alcohol use disorders",
      "value": 0.009
    }
  ]
}