0

So I am trying to smoothly draw five distinct curves using d3. JSFiddle here

The first 4 are hard-coded, for my sake, and the fifth I push onto an array of lineData in a for loop because I eventually want to more dynamically.

var lineData = [[{ "x": 1, "y": 300}, { "x": 200,  "y":70}, { "x": 450,  "y": 300}],
                  [{ "x": 1, "y": 300}, { "x": 250,  "y":70}, { "x": 550,  "y": 300}],
                  [{ "x": 1, "y": 300}, { "x": 300,  "y":70}, { "x": 620,  "y": 300}],
                  [{ "x": 1, "y": 300}, { "x": 350,  "y":70}, { "x": 720,  "y": 300}]];

for (var i = 0; i < 1; i++) {
    lineData.push([{ "x": 1, "y": 300}, { "x": 280,  "y":70}, { "x": 580,  "y": 300}]);
  };

I am using the stroke-offset technique used here, doubling the dash-array, setting the offset to the length of each path, and slowly making the offset return to 0.

However, this causes my last curves to be cut short, and I can't figure out why.

 $(".line").each(function(i,d){

    var t = [1100, 1304,4506,8101,10607, 12900],
    bases = ["first", "second", "third", "fourth"];

    var totalLength = d.getTotalLength();

      d.style.transition = d.style.WebkitTransition = 'none';

      d3.selectAll("path").attr("stroke-dasharray", totalLength + " " + totalLength)
      .attr("stroke-dashoffset", totalLength)
      .transition()
      .duration(function(d,i) { return t[i]; })
      .ease("linear")
      .attr("stroke-dashoffset", 0)
      .each("end", function() { 
        svg.append("text")
        .attr("class", "t")
        .attr("x", w / 2)
        .attr("y", h)
        .attr("text-anchor", "middle");

     });

I've played around with the length I gave the dash-array and the animation times, but I can't seem to find what's causing this weird behavior.

I also hardcoded the fifth line, and that worked well, so the problem may be in my adding of the lines?

Here's a jsfiddle with my problem: any help is greatly appreciated!

Community
  • 1
  • 1
user2799712
  • 25
  • 1
  • 5

1 Answers1

0

The problem is that inside the loop that iterates over all lines, you're selecting all paths again (d3.selectAll("path")). That is, for each line you're selecting all the other lines and setting the animation up according to the length of that line you've selected in the outer loop. The lines are different lengths, hence some of them fall short.

To fix, simply select the current line in the inner loop instead of all lines:

d3.select(this).attr("stroke-dasharray", totalLength + " " + totalLength)
// ...

Complete demo here. There are a few other things in there (such as appending the labels) that you're running for each line when it's only needed once, but I didn't fix those.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204