Skip to content

Instantly share code, notes, and snippets.

@hlvoorhees
Last active August 29, 2015 14:04
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 hlvoorhees/ddc384ba7aec509a2003 to your computer and use it in GitHub Desktop.
Save hlvoorhees/ddc384ba7aec509a2003 to your computer and use it in GitHub Desktop.
affixing an element to a transitioning path in d3

Using attrtween to affix an svg element to an svg path undergoing transition.

In order to compute its position, 1/3 of the way along the path, the element binds the path as data. (See var linkLabel, toward the end of the javascript file.) Then it uses attrTween (not attr) to fetch the correct position at each animation frame during the transition.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Test Path Label Transition</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="test_path_transition.js"></script>
<style>
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
.diamond {
fill: steelblue;
}
</style>
</head>
<body>
<script>
test_path_transition();
</script>
</body>
</html>
function test_path_transition()
{
var root = {
name: "foo",
children: [
{ name: "bar" },
{ name: "baz" }]
}
var width = 500,
height = 500;
var tree = d3.layout.tree()
.size([height, width-190]);
var diagonal = d3.svg.diagonal()
.projection( function(d) { return [d.y, d.x]; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(40,0)");
var nodes = tree.nodes(root);
render(nodes, 0);
setTimeout( function() {
nodes.forEach(function(node) { node.x /= 0.8; });
render(nodes, 1000);
}, 1500);
function render(nodes, duration, message)
{
var links = tree.links(nodes);
var link = svg.selectAll("path.link")
.data(links);
link.enter().append("path")
.attr("class", "link")
link.transition().duration(duration)
.attr("d", diagonal);
var node = svg.selectAll("g.node")
.data(nodes);
var newNode = node.enter().append("g")
.attr("class", "node")
node.transition().duration(duration)
.attr("transform", function(node) { return "translate(" + node.y + "," + node.x + ")"; })
newNode.append("circle")
.attr("r", 5);
newNode.append("text")
.attr("dx", function(d) { return d.children ? -8 : 8; })
.attr("dy", 3)
.attr("text-anchor", function(node) { return node.children ? "end" : "start"; })
.text(function(node) { return node.name; });
var linkLabel = svg.selectAll("g.linkLabel")
.data(link[0])
linkLabel.enter()
.append("g")
.attr("class", "linkLabel")
.append("rect")
.attr("class", "diamond")
.attr("transform", "rotate(45)")
.attr("x", -5)
.attr("y", -5)
.attr("width", 10)
.attr("height", 10)
linkLabel.transition().duration(duration)
.attrTween("transform", function(path) {
return function(t) {
var point = path.getPointAtLength(0.33 * path.getTotalLength());
return "translate(" + point.x + "," + point.y + ")";
}})
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment