I will explain the problem that I have in my real project. I am consuming a web service and this returns me n points x, y. I'm simulating the web service with a settimeout. I want to put a circle in those coordinates and for each circle I want to draw a line that connects them. like this:
I would like to add a line between the circles but showing an animation. like this:
http://bl.ocks.org/duopixel/4063326
for example this animation, but point by point
when I run my application I want the line to have an animation from the initial circle to the end. and if I add a new circle I want a line to be created and have an animation to the circle. How can I do it?
http://jsfiddle.net/2rv0o8da/
var svg = d3.select('svg');
var dataSet = [10, 20, 30, 40];
function display(data){
var circle = svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr({
r:function(d){ return d },
cx:function(d, i){ return i * 100 + 50 },
cy:50,
fill: 'red'
});
}
display(dataSet);
setTimeout(function(){
display([5]);
},2000)
Answering how to connect the dots:
For creating the path that connect your circles, you just have to create a line generator which uses the same data.
For instance, this will create an array with 10 objects, each one having a x
and a y
position:
var dataSet = d3.range(10).map(function(d) {
return {x: someValue, y: someValue}
});
So, since we use those properties to position the circles, we just use the same properties in the line generator:
var lineGenerator = d3.svg.line()
.x(function(d) {return d.x})
.y(function(d) {return d.y})
.interpolate("monotone")
Then, use the function in the bl.ocks you linked:
var totalLength = path.node().getTotalLength();
path.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(2000)
.ease("linear")
.attr("stroke-dashoffset", 0);
Here is the demo:
var svg = d3.select('svg');
var backLayer = svg.append("g");
var frontLayer = svg.append("g");
var dataSet = d3.range(10).map(function(d) {
return {
x: d * 30 + 10,
y: Math.random() * 130 + 10
}
});
var lineGenerator = d3.svg.line()
.x(function(d) {
return d.x
})
.y(function(d) {
return d.y
})
.interpolate("monotone")
function displayCircles(data) {
var circle = frontLayer.selectAll(null)
.data(data)
.enter()
.append('circle')
.attr({
r: 6,
cx: function(d) {
return d.x
},
cy: function(d) {
return d.y
},
fill: 'white',
stroke: "black",
"stroke-width": "3px"
});
};
function displayLine(data) {
var line = backLayer.append("path")
.datum(data)
.attr({
d: lineGenerator(data),
fill: 'none',
stroke: "red",
"stroke-width": "3px",
"shape-rendering": "geometricPrecision"
});
var totalLength = line.node().getTotalLength();
line.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(2000)
.ease("linear")
.attr("stroke-dashoffset", 0);
}
displayCircles(dataSet);
setTimeout(function() {
displayLine(dataSet)
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg></svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With