Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active December 21, 2015 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/6354551 to your computer and use it in GitHub Desktop.
Save nitaku/6354551 to your computer and use it in GitHub Desktop.
Flowlines

An experiment that shows a possible way to visually encode link directionality in node-link diagrams as animation: Some kind of "flow" moves according to the direction.

More or less related to a Mike Bostock example.

For a comparison of different methods for representing link directionality (including animated dashed lines), see Holten et al. 2010

window.main = () ->
width = 960
height = 500
svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
### first example ###
ex1 = svg.append('g')
.attr('transform', 'translate(50 50)')
### draw links ###
ex1.append('path')
.attr('class', 'flowline')
.attr('d', 'M100 100 L300 100')
ex1.append('path')
.attr('class', 'flowline')
.attr('d', 'M200 300 L300 100')
ex1.append('path')
.attr('class', 'flowline')
.attr('d', 'M200 300 L300 250')
ex1.append('path')
.attr('class', 'flowline')
.attr('d', 'M300 250 L100 100')
### draw nodes ###
ex1.append('circle')
.attr('class', 'node')
.attr('cx', 100)
.attr('cy', 100)
.attr('r', 20)
ex1.append('circle')
.attr('class', 'node')
.attr('cx', 300)
.attr('cy', 100)
.attr('r', 20)
ex1.append('circle')
.attr('class', 'node')
.attr('cx', 200)
.attr('cy', 300)
.attr('r', 20)
ex1.append('circle')
.attr('class', 'node')
.attr('cx', 300)
.attr('cy', 250)
.attr('r', 20)
### second example ###
ex2 = svg.append('g')
.attr('transform', 'translate(450 50)')
### draw links ###
ex2.append('path')
.attr('class', 'flowline')
.attr('d', 'M100 100 S200 0 300 100')
ex2.append('path')
.attr('class', 'flowline')
.attr('d', 'M200 300 S200 200 300 100')
ex2.append('path')
.attr('class', 'flowline')
.attr('d', 'M200 300 S300 350 300 250')
ex2.append('path')
.attr('class', 'flowline')
.attr('d', 'M300 250 L100 100')
### draw nodes ###
ex2.append('circle')
.attr('class', 'node')
.attr('cx', 100)
.attr('cy', 100)
.attr('r', 20)
ex2.append('circle')
.attr('class', 'node')
.attr('cx', 300)
.attr('cy', 100)
.attr('r', 20)
ex2.append('circle')
.attr('class', 'node')
.attr('cx', 200)
.attr('cy', 300)
.attr('r', 20)
ex2.append('circle')
.attr('class', 'node')
.attr('cx', 300)
.attr('cy', 250)
.attr('r', 20)
.node {
fill: #dddddd;
stroke: gray;
stroke-width: 4;
}
.flowline {
fill: none;
stroke: black;
opacity: 0.5;
stroke-width: 4;
stroke-dasharray: 10, 4;
animation: flow 1s linear infinite;
-webkit-animation: flow 1s linear infinite;
}
@keyframes flow {
from {
stroke-dashoffset: 14;
}
to {
stroke-dashoffset: 0;
}
}
@-webkit-keyframes flow {
from {
stroke-dashoffset: 14;
}
to {
stroke-dashoffset: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flowlines</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="index.js"></script>
</head>
<body onload="main()"></body>
</html>
(function() {
window.main = function() {
var ex1, ex2, height, svg, width;
width = 960;
height = 500;
svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
/* first example
*/
ex1 = svg.append('g').attr('transform', 'translate(50 50)');
/* draw links
*/
ex1.append('path').attr('class', 'flowline').attr('d', 'M100 100 L300 100');
ex1.append('path').attr('class', 'flowline').attr('d', 'M200 300 L300 100');
ex1.append('path').attr('class', 'flowline').attr('d', 'M200 300 L300 250');
ex1.append('path').attr('class', 'flowline').attr('d', 'M300 250 L100 100');
/* draw nodes
*/
ex1.append('circle').attr('class', 'node').attr('cx', 100).attr('cy', 100).attr('r', 20);
ex1.append('circle').attr('class', 'node').attr('cx', 300).attr('cy', 100).attr('r', 20);
ex1.append('circle').attr('class', 'node').attr('cx', 200).attr('cy', 300).attr('r', 20);
ex1.append('circle').attr('class', 'node').attr('cx', 300).attr('cy', 250).attr('r', 20);
/* second example
*/
ex2 = svg.append('g').attr('transform', 'translate(450 50)');
/* draw links
*/
ex2.append('path').attr('class', 'flowline').attr('d', 'M100 100 S200 0 300 100');
ex2.append('path').attr('class', 'flowline').attr('d', 'M200 300 S200 200 300 100');
ex2.append('path').attr('class', 'flowline').attr('d', 'M200 300 S300 350 300 250');
ex2.append('path').attr('class', 'flowline').attr('d', 'M300 250 L100 100');
/* draw nodes
*/
ex2.append('circle').attr('class', 'node').attr('cx', 100).attr('cy', 100).attr('r', 20);
ex2.append('circle').attr('class', 'node').attr('cx', 300).attr('cy', 100).attr('r', 20);
ex2.append('circle').attr('class', 'node').attr('cx', 200).attr('cy', 300).attr('r', 20);
return ex2.append('circle').attr('class', 'node').attr('cx', 300).attr('cy', 250).attr('r', 20);
};
}).call(this);
.node
fill: #DDD
stroke: gray
stroke-width: 4
.flowline
fill: none
stroke: black
opacity: 0.5
stroke-width: 4
stroke-dasharray: 10,4
animation: flow 1s linear infinite
-webkit-animation: flow 1s linear infinite
@keyframes flow
from
stroke-dashoffset: 14
to
stroke-dashoffset: 0
@-webkit-keyframes flow
from
stroke-dashoffset: 14
to
stroke-dashoffset: 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment