Skip to content

About

swoopyarrows makes swoopy arrows between things

Resources

Stars

110 stars

Watchers

21 watching

Forks

Repository files navigation

swoopyarrows.js

Out of the crooked timber of JavaScript, no straight arrow was ever made.
— Immanuel Kant

Finally an open source project to match the scope of our ambition! A family of three path generators for making nice fun arrows. Use it more or less like d3.svg.line; the easiest thing is to just pass an array of two points, like [[0,0],[10,30]]. Each has x and y accessors and a couple other options.

Download, demo, demo source.

The only dependency is d3 v3. But it goes great with d3-jetpack! If you’re trying to annotate a bunch of things, you may also have more luck with Adam Pearce’s swoopyDrag.

Bring your own SVG markers. We typically use this simple arrowhead:

<marker id="arrowhead" viewBox="-10 -10 20 20" refX="0" refY="0" markerWidth="20" markerHeight="20" stroke-width="1" orient="auto"><polyline stroke-linejoin="bevel" points="-6.75,-6.75 0,0 -6.75,6.75"></polyline></marker>

swoopyArrow

Download. Connect points with circular arcs. The classic. Set angle to the angle the arrow should subtend, in radians, between 0 (basically straight) and Math.PI (a semicircle, 180º). It's not currently possible to subtend more than that.

var swoopy = swoopyArrow()
  .angle(Math.PI/4)
  .x(function(d) { return d[0]; })
  .y(function(d) { return d[1]; });

svg.append("path")
  .attr('marker-end', 'url(#arrowhead)')
  .datum([[100,200],[300,400]])
  .attr("d", swoopy);

loopyArrow

Download. Like a coiled telephone cord. Set the radius of the loop with radius; increase steps to add more coils — although it's only proportionate to the number of loops, not equal to, because I am bad at math and lazy.

var loopy = loopyArrow()
  .steps(30)
  .radius(20)
  .x(function(d) { return d[0]; })
  .y(function(d) { return d[1]; });

svg.append("path")
  .attr('marker-end', 'url(#arrowhead)')
  .datum([[400,600],[800,100]])
  .attr("d", loopy);

kookyArrow

Download. Follows a random path between two points. Increase steps to add more kinks; increase deviation to make the kinks deviate more from the path.

var kooky = kookyArrow()
  .steps(5)
  .deviation(100)
  .x(function(d) { return d[0]; })
  .y(function(d) { return d[1]; });

svg.append("path")
  .attr('marker-end', 'url(#arrowhead)')
  .datum([[1000,200],[700,600]])
  .attr("d", kooky);

For an idea of how you might use the x and y accessors — you could set them to get the offsetLeft and offsetTop of DOM elements, so you can just pass an array of two DOM elements and generate an arrow between them:

var swoopBetweenElements = swoopyArrow()
  .angle(Math.PI/4)
  .x(function(d) { return d.offsetLeft; })
  .y(function(d) { return d.offsetTop; });

svg.append("path")
  .attr('marker-end', 'url(#arrowhead)')
  .datum([document.querySelector('h1'), document.querySelector('h2')])
  .attr("d", swoopBetweenElements);

To-do

  • Handle passing in more than two points (go through all three? choose the closest two?)
  • Put together a bunch of Adobe Illustrator-style SVG markers
  • The whole thing should just be a d3-shape custom curve module
  • Add droopy catenaries

Swoopy arrows have been in use since Egyptian hieroglyphics. They belong to no one ↪↺↷⟲⤣⤥⤴⤵⤶⤷⤹⤳⤻⤿⤺
— Jennifer Daniel, patron saint

Prior art

About

swoopyarrows makes swoopy arrows between things

Resources

Stars

110 stars

Watchers

21 watching

Forks

Releases

Packages

Used by

Contributors

Languages