Accepted answer


To add arrows at the end of the line you need to define a marker using SVG. Only slight modifications are required to update the d3 v3 code to do this with v4. The example you provided sets up three arrow definitions (one for each type of relationship) but to create a single one you can use this:

    .attr("id", "arrow")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 20)
    .attr("refY", 0)
    .attr("markerWidth", 8)
    .attr("markerHeight", 8)
    .attr("orient", "auto")
    .attr("d", "M0,-5L10,0L0,5");

The values of markerWidth, markerHeight, refX, refY are significant and determine the placement of the markers - unfortunately I don't know how they interplay with the viewBox or the circle radius so these were selected by trial and error.

No need to capture the marker as a variable because it will be referred to using a URL specifier as follows:

  var link = svg.append("g")
      .attr("class", "links")
      .attr("stroke", function(d) { return color(d.type); })
      .attr("marker-end", "url(#arrow)");


Again, slight modifications to the v3 code will work. Text labels need to be appended to the SVG separately, not as children of the nodes, and translated independently in the ticked function.

To set up the labels:

var text = svg.append("g").attr("class", "labels").selectAll("g")

    .attr("x", 14)
    .attr("y", ".31em")
    .style("font-family", "sans-serif")
    .style("font-size", "0.7em")
    .text(function(d) { return; });

And then to translate them to the right location when the force simulation ticks:

  function ticked() {
    // ...
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })

The horizontal offset is defined by the value of x when setting up the labels (14 in this case).


See this fiddle for the complete example.

Related Query

More Query from same tag