0

I am new for D3. How can I add an arrow to the beginning and to the end of this line?

var x = 100;
var y = 100;

var canvas = d3.select("#canvasContainer")
            .append("svg")
            .attr("width", 600)
            .attr("height", 500);
var line1 = canvas.append("line")
            .attr("x1", x)
            .attr("y1", y)
            .attr("x2", x)
            .attr("y2", y + 50)
            .attr("stroke", "red")
            .attr("stroke-width", "3");
Andrea
  • 11,801
  • 17
  • 65
  • 72
Ganchimeg L
  • 83
  • 1
  • 1
  • 6

1 Answers1

-1

All you need is:

  svg
  .append('svg:defs')
  .append('svg:marker')
  .attr('id', 'triangle')
  .attr('refX', 6)
  .attr('refY', 6)
  .attr('markerWidth', 30)
  .attr('markerHeight', 30)
  .attr('markerUnits', 'userSpaceOnUse')
  .attr('orient', 'auto')
  .append('path')
  .attr('d', 'M 0 0 12 6 0 12 3 6')
  .style('fill', 'black');

Next:

const pathNodes = svg
    .append('path')
    .datum(path)
    .attr('d', line)
    .attr('fill', 'none')
    .attr('stroke-width', '3')
    .attr('stroke', (d) => d.color)
    .attr('marker-end', 'url(#triangle)');

Or with animation in my case:

const arrow = svg
    .append('svg:path')
    .attr('d', 'M 0 0 12 6 0 12 3 6')
    .attr('fill', 'black');
  arrow
    .transition()
    .duration(2000)
    .delay(1500)
    .ease(d3.easeLinear)
    .attrTween('transform', this.arrowAnimation(pathNodes.node()));

arrowAnimation(path) => {
const l = path.getTotalLength();
let prevX = 0;
let prevY = 0;
return (d, i, a) => {
  return (t) => {
    const p = path.getPointAtLength(t * l);
    const deltaY = prevY - p.y;
    const deltaX = prevX - p.x;
    prevY = p.y;
    prevX = p.x;

    let rotTran;
    if (deltaY === 0) {
      if (deltaX > 0) {
        rotTran = 'rotate(-180)';
      } else {
        rotTran = 'rotate(180)';
      }
    } else if (deltaX === 0) {
      if (deltaY > 0) {
        rotTran = 'rotate(-90)';
      } else {
        rotTran = 'rotate(90)';
      }
    } else {
      rotTran = 'rotate(0)';
    }

    return 'translate(' + p.x + ',' + p.y + ') ' + rotTran;
  };
};

}