swoopyarrows makes swoopy arrows between things
JavaScript HTML
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
LICENSE Initial commit Jun 12, 2014
README.md
bwhaasgroteskhead-95black.woff Much-improved demo! Feb 26, 2016
index.html Update index.html Mar 21, 2016
kookyArrow.js newlines! Feb 26, 2016
loopyArrow.js
priorart.jpg
swoopyArrow.js Improving examples and docs a little. Ditching the useless d3.svg nam… Feb 26, 2016
swoopyArrows.js newlines! Feb 26, 2016

README.md

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