Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing speed of D3 path animation

Here is the code: http://jsfiddle.net/fJAwW/

This is what I am interested in:

path
  .attr("stroke-dasharray", totalLength + " " + totalLength)
  .attr("stroke-dashoffset", totalLength)
  .transition()
    .duration(2000)
    .ease("linear")
    .attr("stroke-dashoffset", 0);

I have my data variable lineData, which I add to the path with

.attr("d", line(lineData))

For the transition section:

  .transition()
    .duration(2000)

I would like to do something like

  .transition()
    .duration(function(d) {
      return d.x;
    })

Where d is one of my data points.

I am having trouble understanding the data structures and how they interact in d3.js, so any help would be appreciated.

like image 320
Jimmy Pitts Avatar asked Jul 24 '13 19:07

Jimmy Pitts


1 Answers

I believe you will need to create a set of chained transitions for changing the stroke-dashoffset value at each point in your line. As @ckersch pointed out, path is different than most things in d3 because the data is collapsed into a single path string rather than represented as individual values.

You can chain the initial transition from the path variable like you have done, and then chain the further transitions from the prior one. Something like this:

  // Add the path
  var path = svg.append('path')
    .attr( {d: line(lineData), stroke: "steelblue", 'stroke-width': 2, fill: 'none'} );

  var totalLength = path.node().getTotalLength();

  // start with the line totally hidden
  path.attr( {'stroke-dasharray': totalLength + " " + totalLength, 'stroke-dashoffset': totalLength } );

  // transition will be chained from either the original path or the last transition
  var transitionFrom = path;
  // start at 1 since no transition needed to first point
  for (var i = 1; i < lineData.length; i++) {
    transitionFrom = transitionFrom.transition()
      .duration(lineData[i].speed)
      .ease("linear")
      .attr("stroke-dashoffset", lengthAt[i-1] || 0);
  };

Where does this lengthAt array come from? Yeah that's the ugly part. My geometry skills are not good enough to know offhand how to approximate that to match the 'cardinal' interpolation in your line generator function, but in this example I've hacked up a way to do it by drawing hidden lines and reading it back out of svg:

http://bl.ocks.org/explunit/6082362

like image 149
explunit Avatar answered Nov 15 '22 22:11

explunit