title: How do I draw an arrow between two points in d3v4?
body: <p>I have created a custom path renderer that draws an arrow between the nodes in my d3 graph as shown in the snippet. I have one last issue I am getting stuck on,</p>
  
  <p>How would I rotate the arrow portion so that it is pointing from the direction of the curve instead of the direction of the source?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var w2 = 6,
    ar2 = w2 * 2,
    ah = w2 * 3,
    baseHeight = 30;
  
  // Arrow function
  function CurvedArrow(context, index) {
    this._context = context;
    this._index = index;
  }
  CurvedArrow.prototype = {
    areaStart: function() {
      this._line = 0;
    },
    areaEnd: function() {
      this._line = NaN;
    },
    lineStart: function() {
      this._point = 0;
    },
    lineEnd: function() {
      if (this._line || (this._line !== 0 &amp;&amp; this._point === 1)) {
        this._context.closePath();
      }
      this._line = 1 - this._line;
    },
    point: function(x, y) {
      x = +x, y = +y; // jshint ignore:line
      switch (this._point) {
        case 0:
          this._point = 1;
          this._p1x = x;
          this._p1y = y;
          break;
        case 1:
          this._point = 2; // jshint ignore:line
        default:
          var p1x = this._p1x,
            p1y = this._p1y,
            p2x = x,
            p2y = y,
            dx = p2x - p1x,
            dy = p2y - p1y,
            px = dy,
            py = -dx,
            pr = Math.sqrt(px * px + py * py),
            nx = px / pr,
            ny = py / pr,
            dr = Math.sqrt(dx * dx + dy * dy),
            wx = dx / dr,
            wy = dy / dr,
            ahx = wx * ah,
            ahy = wy * ah,
            awx = nx * ar2,
            awy = ny * ar2,
            phx = nx * w2,
            phy = ny * w2,
  
            //Curve figures
            alpha = Math.floor((this._index - 1) / 2),
            direction = p1y &lt; p2y ? -1 : 1,
            height = (baseHeight + alpha * 3 * ar2) * direction,
  
  
            //             r5
            //r7         r6|\
            // ------------  \
            // ____________  /r4
            //r1         r2|/
            //             r3
  
            r1x = p1x - phx,
            r1y = p1y - phy,
            r2x = p2x - phx - ahx,
            r2y = p2y - phy - ahy,
            r3x = p2x - awx - ahx,
            r3y = p2y - awy - ahy,
            r4x = p2x,
            r4y = p2y,
            r5x = p2x + awx - ahx,
            r5y = p2y + awy - ahy,
            r6x = p2x + phx - ahx,
            r6y = p2y + phy - ahy,
            r7x = p1x + phx,
            r7y = p1y + phy,
            //Curve 1
            c1mx = (r2x + r1x) / 2,
            c1my = (r2y + r1y) / 2,
            m1b = (c1mx - r1x) / (r1y - c1my),
            den1 = Math.sqrt(1 + Math.pow(m1b, 2)),
            mp1x = c1mx + height * (1 / den1),
            mp1y = c1my + height * (m1b / den1),
            //Curve 2
            c2mx = (r7x + r6x) / 2,
            c2my = (r7y + r6y) / 2,
            m2b = (c2mx - r6x) / (r6y - c2my),
            den2 = Math.sqrt(1 + Math.pow(m2b, 2)),
            mp2x = c2mx + height * (1 / den2),
            mp2y = c2my + height * (m2b / den2);
  
          this._context.moveTo(r1x, r1y);
          this._context.quadraticCurveTo(mp1x, mp1y, r2x, r2y);
          this._context.lineTo(r3x, r3y);
          this._context.lineTo(r4x, r4y);
          this._context.lineTo(r5x, r5y);
          this._context.lineTo(r6x, r6y);
          this._context.quadraticCurveTo(mp2x, mp2y, r7x, r7y);
  
          break;
      }
    }
  };
  var w = 600,
    h = 220;
  var t0 = Date.now();
  
  var points = [{
    R: 100,
    r: 3,
    speed: 2,
    phi0: 190
  }];
  var path = d3.line()
    .curve(function(ctx) {
      return new CurvedArrow(ctx, 1);
    });
  
  var svg = d3.select("svg");
  var container = svg.append("g")
    .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")")
  
  container.selectAll("g.planet").data(points).enter().append("g")
    .attr("class", "planet").each(function(d, i) {
      d3.select(this).append("circle").attr("r", d.r).attr("cx", d.R)
        .attr("cy", 0).attr("class", "planet");
    });
  container.append("path");
  var planet = d3.select('.planet circle');
  
  d3.timer(function() {
    var delta = (Date.now() - t0);
    planet.attr("transform", function(d) {
      return "rotate(" + d.phi0 + delta * d.speed / 50 + ")";
    });
  
    var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    g.setAttributeNS(null, "transform", planet.attr('transform'));
    var matrix = g.transform.baseVal.consolidate().matrix;
    svg.selectAll("path").attr('d', function(d) {
      return path([
        [0, 0],
        [matrix.a * 100, matrix.b * 100]
      ])
    });
  });</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>path {
    stroke: #11a;
    fill: #eee;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
  &lt;svg width="600" height="220"&gt;&lt;/svg&gt;</code></pre>
  </div>
  </div>
  </p>