Reputation: 2122
I have the following code which plots a line path based on sine function:
var data = d3.range(40).map(function(i) {
return {x: i / 39, y: (Math.sin(i / 3) + 2) / 4};
});
var margin = {top: 10, right: 10, bottom: 20, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 1])
.range([height, 0]);
var line = d3.svg.line()
.interpolate('linear')
.x(function(d){ return x(d.x) })
.y(function(d){ return y(d.y) });
var svg = d3.select("body").append("svg")
.datum(data)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("path")
.attr("class", "line")
.attr("d", line);
svg.selectAll('.point')
.data(data)
.enter().append("svg:circle")
.attr("cx", function(d, i){ return x(d.x)})
.attr("cy", function(d, i){ return y(d.y)})
.attr('r', 4);
What I want to do is to plot it smoothly from the first node to last node. I also want to have a smooth transition between two consecutive nodes and not just putting the whole line at once. Simply like connecting the dots using a pencil.
Any help would be really appreciated.
Upvotes: 18
Views: 22375
Reputation: 31
For those as me using actual SVG tags in JSX with CSS: You can re-write the solution from @methodofaction like this:
@keyframes animate-line {
0% {
stroke-dashoffset: 100;
stroke-dasharray: 100;
}
100% {
stroke-dashoffset: 0;
}
}
.animate {
animation-delay: 0.5s;
animation-duration: 2s;
animation-timing-function: linear;
animation-name: animate-line;
}
then add .animate
class to your JSX:
<path
...
/* Has to be the same value as in CSS for stroke-dashoffset */
pathLength={100}
className={styles.animate}
/>
I wasn't able to make it work with transition
property on mount, but I guess animation is good as well here. I hope that helps someone...
Upvotes: 0
Reputation: 72385
You can animate paths quite easily with stroke-dashoffset
and and path.getTotalLength()
var totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(2000)
.ease("linear")
.attr("stroke-dashoffset", 0);
Upvotes: 40