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.
xxxxxxxxxx
<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>
https://d3js.org/d3.v4.min.js