Skip to content

krispo/yarrow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yarrow

Build Status NPM Version

SVG animated arrow pointer and tooltip.

Simple With D3

Demos:

  1. Web page.
  2. Plnkr.

Install

npm install yarrow

and include it in html head section:

<link  href="node_modules/yarrow/build/yarrow.css" rel="stylesheet" type="text/css"/>
<script src="node_modules/d3-selection/build/d3-selection.min.js"></script>
<script src="node_modules/svg-path-utils/build/svg-path-utils.min.js"></script>
<script src="node_modules/yarrow/build/yarrow.min.js"></script>

Usage

// for es6
import {Yarrow} from 'yarrow';
var yarrow = new Yarrow();

// or in older versions use require:
// var Yarrow = require('yarrow');
// var yarrow = new Yarrow.Yarrow(); 

// add new arrow
var arrow = yarrow.arrow({
  x1: 0,                // source x coordinate
  y1: 0,                // source y coordinate
  x2: 100,              // target x coordinate
  y2: 100,              // target y coordinate
  text: "I'm arrow!"    // arrow label    
});

// render arrow on the page
arrow.render();

// dispose arrow with duration=1000 after delay=500
arrow.dispose(1000, 500);

the same with chaining notation:

yarrow.arrow({...}).render().dispose(1000, 500);

API Reference

Yarrow

Yarrow is a container of arrows.

# yarrow.arrow(opts)

Create new arrow with specified options. Returns created arrow.

# yarrow.arrows([opts])

Create multiple arrows with specified options at a time. If opts are not specified, returns the current array of arrow.

# yarrow.renderAll()

Render all arrows at a time.

# yarrow.disposeAll(duration, delay)

Dispose all arrows with specified duration, and after specified delay time. Arrows are removed completely.

Arrow

Single arrow instance. Available options are listed below.

# arrow.render()

Render the current arrow.

# arrow.dispose(duration, delay)

Dispose the current arrow with specified duration, and after specified delay time. The arrow is removed completely.

Options behaviour

Options can be initialized using the following methods:

  1. yarrow.arrow(opts)
  2. yarrow.arrows([opts])
  3. arrow.options(opts)

Under initialization, a set of options

x1, y1, x2, y2, d, d1, d2, textReverseDirection, textStartOffset 

can be define as function

function(opts, utils) {
  // opts   - the current options, after initialization
  // utils  - svg-path-utils
  return 'some_value'; 
}

that takes 2 parameters: the current options opts, and svg-path-utils utilities. It can help us to manipulate dynamic arrow behaviour. For example, it is useful when we don't know the coordinates of the source or target elements.

Let's show how it works. Define options

var opts = {

  source: '#source_id', // define source element via id

  target: document.getElementById('target_id'), // or define target element via document element 

  x1: function(_, u) {
    // _ - this options object has already had explicit values for `source` and `target`
    return _.source.left + _.source.width / 2;
  },

  y1: function(_, u) {     
    return _.source.top + _.source.height / 2;
  },

  x2: function(_, u) {   
    return _.target.left + _.target.width / 2;
  },

  y2: function(_, u) {     
    return _.target.top + _.target.height / 2;
  },

  d: function(_, u) {
    // _ - this options object has already had explicit values for x1, y1, x2, y2;
    // _.w and _.h are calculated based on x1, y1, x2, y2
    return u.join(u.M(0, 0), u.Q(_.w, 0, _.w, _.h));
  }
};

yarrow.arrow(opts).render();

The resulting arrow will start from the middle of the source element, and then will go to the middle of the target element, and will draw a quadratic Bézier curve.

Arrow options

All options have get/set behaviour, except the options with READONLY property.

# .options(opts)

Specifies the arrow options. If opts is not defined, returns the current options.

# .x1()

Source x coordinate

# .y1()

Source y coordinate

# .x2()

Target x coordinate

# .y2()

Target y coordinate

# .dx()

READONLY property, equals (x2 - x1)

# .dy()

READONLY property, equals (y2 - y1)

# .w()

READONLY property, equals |x2 - x1|

# .h()

READONLY property, equals |y2 - y1|

# .source()

Selector or node element for source point. Eg, source: '#source_id'. After initialization it's converted into object with props: element, top, left, width, height.

arrow.options({
  ...,
  source: "#source_id",
  ...
});

arrow.options(); 
/* returns:
{
  ...,
  source: {
    element: < html element >,
    top: 10,
    left: 20,
    width: 100,
    height: 200
  },  
  ...
}
*/

# .target()

Selector or node element for target point. Eg, target: '#target_id'. After initialization it's converted into object with props: element, top, left, width, height.

arrow.options({
  ...,
  target: "#target_id",
  ...
});

arrow.options(); 
/* returns:
{
  ...,
  target: {
    element: < html element >,
    top: 10,
    left: 20,
    width: 100,
    height: 200
  },  
  ...
}
*/

# .duration()

Render duration for the arrow curve

# .delay()

Delay before start rendering for the arrow curve

# .d()

Path for the arrow curve (by default it's a simple line)

# .duration1()

Render duration for the first tip

# .delay1()

Delay before start rendering for the first tip

# .d1()

Path for the first tip (by default it's a simple line)

# .duration2()

Render duration for the second tip

# .delay2()

Delay before start rendering for the second tip

# .d2()

Path for the second tip (by default it's a simple line)

# .arrowStyles()

Specify styles for arrow

# .textStyles()

Specify styles for text

# .text()

Label text for arrow

# .textReverseDirection()

Direct arrow text in a end -> start way (default direction is start -> end)

# .textStartOffset()

Text offset from the start of the path (or from the end of the path if used textReverseDirection)

# .textDx()

Horizontal text offset

# .textDy()

Vertical text offset

# .margin()

An outer margin for drawing rectangle. Eg, suppose (x1,y1)=(100,100), (x2,y2)=(200,200). If margin = { top: 0, right: 0, bottom: 0, left: 0 }, the drawing rectangle will be (100,100),(200,200). If margin = { top: 50, right: 20, bottom: 10, left: 30 }, the drawing rectangle will be (70,50),(220,210).

Licence

MIT