title: How to call JSON from a file instead of in-line for Multi-Edge D3 Example
body: <p>I am following this example: <a href="http://bl.ocks.org/mbostock/1153292" rel="nofollow noreferrer">http://bl.ocks.org/mbostock/1153292</a></p>
  
  <p>I have row upon row of JSON data that looks like this:</p>
  
  <pre><code>{"source":"Michael Scott","target":"Jim Halpert","type":"pro"},
  {"source":"Jim Halpert","target":"Dwight Schrute","type":"pro"}
  </code></pre>
  
  <p>Current code to render this data looks like this:</p>
  
  <pre><code>var links = [
  {"source":"Michael Scott","target":"Jim Halpert","type":"pro"},
  {"source":"Jim Halpert","target":"Dwight Schrute","type":"pro"}
  ];
  
  var nodes = {};
  
  links.forEach(function(link) {
  link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
  });
  
  var width = 2000,
  height = 1000;
  
  var force = d3.layout.force()
  .nodes(d3.values(nodes))
  .links(links)
  .size([width, height])
  .linkDistance(60)
  .charge(-300)
  .on("tick", tick)
  .start();
  
  var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);
  
  svg.append("defs").selectAll("marker")
  .data(["pro"])
  .enter().append("marker")
  .attr("id", function(d) { return d; })
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", -1.5)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("path")
  .attr("d", "M0,-5L10,0L0,5");
  
  var path = svg.append("g").selectAll("path")
  .data(force.links())
  .enter().append("path")
  .attr("class", function(d) { return "link " + d.type; })
  .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
  
  var circle = svg.append("g").selectAll("circle")
  .data(force.nodes())
  .enter().append("circle")
  .attr("r", 6)
  .call(force.drag);
  
  var text = svg.append("g").selectAll("text")
  .data(force.nodes())
  .enter().append("text")
  .attr("x", 8)
  .attr("y", ".31em")
  .text(function(d) { return d.name; });
  
  function tick() {
    path.attr("d", linkArc);
    circle.attr("transform", transform);
    text.attr("transform", transform);
  }
  
  function linkArc(d) {
    var dx = d.target.x - d.source.x,
    dy = d.target.y - d.source.y,
    dr = Math.sqrt(dx * dx + dy * dy);
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
  }
  
  function transform(d) {
    return "translate(" + d.x + "," + d.y + ")";
  }
  
  &lt;/script&gt;
  </code></pre>
  
  <p>How do I call the data from an external <code>data.json</code> file? I've looked at all the other related SO questions and other D3 examples, but I haven't been able to get anything to work. </p>
  
  <p>I've tried (and then changing all references to <code>links</code> to <code>data</code>):</p>
  
  <pre><code>d3.json("data.json", function(error, data) {
  });
  </code></pre>
  
  <p>Here is that full code:</p>
  
  <pre><code>&lt;body&gt;
  &lt;script src="//d3js.org/d3.v3.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
  
  d3.json("data.json", function(error, data) {
  });
  
  
  var nodes = {};
  
  data.forEach(function(link) {
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
  });
  
  var width = 2000,
  height = 1000;
  
  var force = d3.layout.force()
  .nodes(d3.values(nodes))
  .data(data)
  .size([width, height])
  .linkDistance(60)
  .charge(-300)
  .on("tick", tick)
  .start();
  
  var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);
  
  svg.append("defs").selectAll("marker")
  .data(["pro"])
  .enter().append("marker")
  .attr("id", function(d) { return d; })
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", -1.5)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("path")
  .attr("d", "M0,-5L10,0L0,5");
  
  var path = svg.append("g").selectAll("path")
  .data(force.data())
  .enter().append("path")
  .attr("class", function(d) { return "link " + d.type; })
  .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
  
  var circle = svg.append("g").selectAll("circle")
  .data(force.nodes())
  .enter().append("circle")
  .attr("r", 6)
  .call(force.drag);
  
  var text = svg.append("g").selectAll("text")
  .data(force.nodes())
  .enter().append("text")
  .attr("x", 8)
  .attr("y", ".31em")
  .text(function(d) { return d.name; });
  
  function tick() {
  path.attr("d", linkArc);
  circle.attr("transform", transform);
  text.attr("transform", transform);
  }
  
  function linkArc(d) {
  var dx = d.target.x - d.source.x,
    dy = d.target.y - d.source.y,
    dr = Math.sqrt(dx * dx + dy * dy);
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
  }
  
  function transform(d) {
    return "translate(" + d.x + "," + d.y + ")";
  }
  
  &lt;/script&gt;
  </code></pre>
  
  <p>This results in the error <code>Uncaught Reference Error: "data" is not defined</code> for this line <code>data.forEach(function(link) {</code>. <code>data.json</code> is located in the same directory as <code>index.html</code></p>
  
  <p>I've tried various other implementations as well that I picked up from other D3 examples on blocks.org. Any and all insight would be greatly appreciated. Please let me know if there's anything I can do to improve my question!</p>