JSFiddle - React, Tailwind, and code Playground

Have multiple edges drawn as arcs between two given nodes

by bigman73

HTML

<script src="http://mbostock.github.com/d3/d3.js"></script>
<div id="chart"></div>

CSS

path.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}

marker#licensing {
  fill: green;
}

path.link.licensing {
  stroke: green;
}

path.link.resolved {
  stroke-dasharray: 0, 2 1;
}

circle {
  fill: #ccc;
  stroke: #333;
  stroke-width: 1.5px;
}

text {
  font: 10px sans-serif;
  pointer-events: none;
}

text.shadow {
  stroke: #fff;
  stroke-width: 3px;
  stroke-opacity: .8;
}

JavaScript

var links = [{
    source: "Microsoft",
    target: "Amazon",
    type: "licensing"
  },
  {
    source: "Microsoft",
    target: "Amazon",
    type: "suit"
  },
  {
    source: "Samsung",
    target: "Apple",
    type: "suit"
  },
  {
    source: "Microsoft",
    target: "Amazon",
    type: "resolved"
  }
];
//sort links by source, then target
links.sort(function(a, b) {
  if (a.source > b.source) {
    return 1;
  } else if (a.source < b.source) {
    return -1;
  } else {
    if (a.target > b.target) {
      return 1;
    }
    if (a.target < b.target) {
      return -1;
    } else {
      return 0;
    }
  }
});
//any links with duplicate source and target get an incremented 'linknum'
for (var i = 0; i < links.length; i++) {
  if (i != 0 &&
    links[i].source == links[i - 1].source &&
    links[i].target == links[i - 1].target) {
    links[i].linknum = links[i - 1].linknum + 1;
  } else {
    links[i].linknum = 1;
  };
};

var nodes = {};

// Compute the distinct nodes from the links.
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 w = 600,
  h = 600;

var force = d3.layout.force()
  .nodes(d3.values(nodes))
  .links(links)
  .size([w, h])
  .linkDistance(60)
  .charge(-300)
  .on("tick", tick)
  .start();

var svg = d3.select("body").append("svg:svg")
  .attr("width", w)
  .attr("height", h);

// Per-type markers, as they don't inherit styles.
svg.append("svg:defs").selectAll("marker")
  .data(["suit", "licensing", "resolved"])
  .enter().append("svg:marker")
  .attr("id", String)
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", -1.5)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

var path = svg.append("svg:g").selectAll("path")
  .data(force.links())
  .enter().append("svg:path")
 ...