Skip to content

Instantly share code, notes, and snippets.

@dbarton-uk
Last active November 14, 2016 12:19
Show Gist options
  • Save dbarton-uk/b6f3c8daa6cf059f3159ca772c331877 to your computer and use it in GitHub Desktop.
Save dbarton-uk/b6f3c8daa6cf059f3159ca772c331877 to your computer and use it in GitHub Desktop.
d3-pathLayout
license: bsd-3-clause

The example shows the d3-pathLayout plugin fitting an array of nodes to custom SVG paths.

Each path is represented by a dotted light grey line, and each node is represented by a letter. For each path, d3-pathLayout positions each node and the example then transitions the nodes to the calculated position.

Source code for d3-pathLayout available here.

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.d3=t.d3||{})}(this,function(t){"use strict";var e=function(t){function e(){if(!o)return r;var t=document.createElementNS("http://www.w3.org/2000/svg","path");t.setAttribute("d",o);var e=t.getTotalLength(),u=n.length;return n.forEach(function(n,o){var r=e/u*o,i=t.getPointAtLength(r);n.x=i.x,n.y=i.y}),r}t=t||{};var n=t.nodes||[],o=t.path||void 0,r={nodes:function(t){return arguments.length?(n=t,e()):n},path:function(t){return arguments.length?(o=t,e()):o}};return e()};t.pathLayout=e,Object.defineProperty(t,"__esModule",{value:!0})});
.node > text {
alignment-baseline: middle;
text-anchor: middle;
font-size: 2em;
fill:darkblue
}
.path {
stroke: darkgray;
stroke-dasharray: 2;
fill: none;
}
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="d3-pathLayout.min.js"></script>
<link rel="stylesheet" type="text/css" href="index.css">
<script type="text/javascript">
var outerWidth = 960,
outerHeight = 500;
var margin = {
top : 20,
right : 10,
bottom: 20,
left : 10
};
var width = outerWidth - margin.left - margin.right,
height = outerHeight - margin.top - margin.bottom;
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var text = "Hello D3 World!".split('');
var nodes = [];
text.forEach(function (t) {
nodes.push({letter: t});
});
var horizontalPath = d3.path();
horizontalPath.moveTo(270, 240);
horizontalPath.lineTo(670, 240);
var verticalPath = d3.path();
verticalPath.moveTo(470, 40);
verticalPath.lineTo(470, 440);
var diagonalPath = d3.path();
diagonalPath.moveTo(270, 40);
diagonalPath.lineTo(670, 440);
var circle = d3.path();
circle.arc(470, 240, 200, Math.PI, Math.PI * 3);
var cubicBezier1 = d3.path();
cubicBezier1.moveTo(270, 240);
cubicBezier1.bezierCurveTo(370, 40, 570, 440, 670, 240);
var cubicBezier2 = d3.path();
cubicBezier2.moveTo(270, 240);
cubicBezier2.bezierCurveTo(370, 440, 570, 40, 670, 240);
var paths = [
horizontalPath,
verticalPath,
diagonalPath,
circle,
cubicBezier1,
cubicBezier2
];
svg.selectAll(".path")
.data(paths)
.enter()
.append("path")
.attr("d", function (d) {
return d;
})
.attr("class", "path");
svg.nodes = svg.selectAll('.node')
.data(nodes)
.enter()
.append("g")
.attr("class", "node");
svg.nodes
.append("text")
.text(function(d) {
return d.letter;
});
svg.nodes
.transition()
.on("start", function repeat() {
var transition = d3.active(this);
paths.forEach(function (p) {
transition = transition.call(transitionToPath, p).transition();
});
transition.on("start", repeat);
});
function transitionToPath(transition, path) {
d3.pathLayout({
nodes: nodes,
path : path
});
transition.duration(2000)
.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
</script>
</body>
@dbarton-uk
Copy link
Author

dbarton-uk commented Nov 14, 2016

Click here for example at bl.ocks.org

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment