Skip to content

Instantly share code, notes, and snippets.

@tomeustace
Last active October 6, 2016 21:48
Show Gist options
  • Save tomeustace/ed08af45b12fb6aff8cc776e07d76f68 to your computer and use it in GitHub Desktop.
Save tomeustace/ed08af45b12fb6aff8cc776e07d76f68 to your computer and use it in GitHub Desktop.
d3 animated path with segment selection
<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class="flex-container">
<h2>d3 Animated Path with Segment Selection</h2>
<div id="target" class="row"></div>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var lineFunction = d3.line()
.x(function(d)
{
return d.x;
})
.y(function(d)
{
return d.y;
});
var svgContainer = d3.select("#target").append("svg")
.attr("width", 500)
.attr("height", 200);
var lineData = [
{
"x": 30,
"y": 50
},
{
"x": 100,
"y": 10
},
{
"x": 200,
"y": 50
},
{
"x": 300,
"y": 10
},
{
"x": 400,
"y": 50
},
{
"x": 500,
"y": 10
}];
var path = svgContainer.append('path')
.attr('d', lineFunction(lineData[0]))
.attr('stroke-width', 5)
.attr('stroke', 'black')
.attr('fill', 'none')
.on('mouseover', overlayPathOnSegment)
.transition()
.duration(1000)
.attrTween('d', pathTween);
svgContainer.select('path')
.transition()
.delay(1500)
.duration(500)
.attr("stroke", "green")
.attr("stroke-opacity", 0.5)
.attr("stroke-width", 15)
.attr("fill", "none");
function overlayPathOnSegment(d) {
var mousePoint = d3.mouse(this);
var pathLength = path.node().getTotalLength()
var scale = d3.scaleLinear().domain([0, 540]).range([0, pathLength]);
var seg = path.node().getPathSegAtLength(scale(mousePoint[0]));
var pathSplit = d3.select(this).attr('d').split('L');
var newPath;
if(pathSplit[seg-1].startsWith('M') ) {
newPath = pathSplit[seg-1] + ',L' + pathSplit[seg];
} else {
newPath = 'M' + pathSplit[seg-1] + ',L' + pathSplit[seg];
}
svgContainer.append('path')
.attr('d', newPath)
.attr('stroke-width', 20)
.attr('stroke', 'green')
.attr('opacity','0.5')
.on('mouseout', removePathOnSegment);
}
function removePathOnSegment()
{
d3.select(this).remove();
}
function pathTween()
{
var interpolate = d3.scaleQuantile()
.domain([0, 1])
.range(d3.range(1, lineData.length + 1));
return function(t)
{
return lineFunction(lineData.slice(0, interpolate(t)));
};
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment