SVG animated arrow pointer and tooltip.
Simple | With D3 |
---|---|
Demos:
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>
// 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);
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.
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 can be initialized using the following methods:
- yarrow.arrow(opts)
- yarrow.arrows([opts])
- 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.
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)
.
MIT