Yarrow
Simple SVG animated arrow pointer

Examples

Click on example to rerun. Check also online demo.

Basic Example

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow!"
}).render();

Curve path

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow!",
  d: 'M0,140 Q0,0 200,0'
}).render();

Text start offset

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow!",
  d: 'M0,140 Q0,0 200,0',
  textStartOffset: 80
}).render();

Text XY offset

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow!",
  d: 'M0,140 Q0,0 200,0',
  textDx: 80,
  textDy: 20
}).render();

Reverse text direction

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow!",
  d: 'M0,140 Q0,0 200,0',
  textReverseDirection: true,
  textStartOffset: 70
}).render();

Text HTML

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  d: 'M0,140 Q0,0 200,0',
  textStartOffset: 80,
  text: 'I\'m <tspan font-size="25" font-weight="bold" fill="red" >also</tspan> arrow!'
}).render();

Styles

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow!",
  arrowStyles: {
    'stroke': '#ff5a00',
    'stroke-width': 6
  },
  textStyles: {
    'fill': '#008080',
    'font-size': 20,
    'font-weight': 'bold'
  }
}).render();
Styles also can be defined via css.
.arrow { ... }
.arrow .tip1 { ... }
.arrow .tip2 { ... }
.arrow .text { ... }

Durations

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  duration: 2000,     // arrow duration
  duration1: 500,     // tip1 duration
  delay2: 2000 + 500, // tip2 delay
  duration2: 500      // tip2 duration
}).render();

Animation off

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: 300,
  y2: 80,
  text: "I'm arrow",
  animation: false
}).render();

Source element

var yarrow = new Yarrow();

yarrow.arrow({
  x1: function(_){
    return _.source.left + _.source.width/2;
  },
  y1: function(_){ return _.source.top; },
  x2: 300,
  y2: 80,
  source: "#source_id"
  text: "I'm arrow"
}).render();

Target element

var yarrow = new Yarrow();

yarrow.arrow({
  x1: 100,
  y1: 220,
  x2: function(_){
    return _.target.left + _.target.width/2;
  },
  y2: function(_){
    return _.target.top + _.target.height;
  },
  target: "#target_id"
  text: "I'm arrow"
}).render();

Paths

Piecewise linear arrow
var yarrow = new Yarrow();

yarrow.arrow({
  x1: 60,
  y1: 60,
  x2: 300,
  y2: 250,
  d: function(_, u){
    return u.join(u.M(0, 0), u.L(70, 0), u.L(_.w, _.h));
  },
  text: "I'm arrow",
  arrowStyles: {
    'stroke-width': 4,
    'stroke': '#ff5a00'
  }
}).render();
Hover over the section item
var yarrow = new Yarrow();
yarrow.arrow({
  x1: 350,
  y1: 80,
  x2: function(_){ return _.target.left + _.target.width; },
  y2: function(_){ return _.target.top + _.target.height/2; },
  d: function(_, u){
    return u.join(
      u.M(_.w, _.dy > 0 ? 0 : _.h),
      u.L(_.w - 70, _.dy > 0 ? 0 : _.h),
      u.L(0, _.dy > 0 ? _.h : 0)
    );
  },
  target: el, // section item element
  text: el.innerHTML,
  textReverseDirection: true,
  textStartOffset: 65,
  animation: false
}).render();

With D3 Chart

var max = getMaxPoint();

var yarrow = new Yarrow();
yarrow.arrow({
  x1: 100,
  y1: 100,
  x2: function(_){ return _.target.left + max.x - 10 },
  y2: function(_){ return _.target.top + max.y + 3 },
  d: function(_, u){
    return u.join(u.M(0,_.h), u.L(100,_.h), u.L(_.w, 0));
  },
  target: '#chart_id',
  text: max.value + '$ ' + max.date,
}).render();