d3 animated line graph

2019-07-24 13:55发布

I am trying to create an animated line graph where the line draws out its path from left to right, as in the first scene of this example. I have been closely following the code for mbostock's example, but still am having a couple issues.

When I try to run my code, I get an error saying "'d' is undefined", in the attr method inside the draw function shown below:

    var line = d3.svg.line()
        .interpolate('linear')
        .x(function(d,i) {return x(i);})
        .y(function(d,i) {return y(d['measures'][i]);});

    chart.append('path')
            .attr('class','line')
            .data(array);

    function draw(k) {
        chart.select('.line')
            .attr('d',function(d) { return line(d.measures.slice(0,k+1));});
    }

    var k=1, n = array.measures.length;
    d3.timer( function() { 
        draw(k);
        if((k+=2) >= n-1) {
            draw(n-1);
            //next transitions
            return true;
        }

This leads me to believe that my data has not been correctly bound to the path. However, I can't seem to understand why it would not be binding correctly

Any help would be much appreciated!

1条回答
Viruses.
2楼-- · 2019-07-24 14:44

The example you picked as a starting point is binding the data for each ticker symbol to a <g> element, and then within each of those it's creating lines, etc. based on child data of that ticker. The .selectAll and .data methods are used when you're binding a list of data to a list of DOM nodes (e.g. <circle>, <rect>, <g>). But <path> is just a single DOM node with a long string of path data for rendering the line. You call the line function once to give you that string.

So for your purpose, if you just have one line that you're trying to animate, you just call your line function directly in order to create the path string to set on that node. There is no existing data bound to the node that you're trying to reuse. In your draw function:

.attr("d", line(array.measures.slice(0,k+1)))

Your line function itself needs slight adjustment too, assuming that array.measures contains a simple array of numbers:

  var line = d3.svg.line()
      .interpolate('linear')
      .x(function(d,i) {return x(i);})
      .y(function(d,i) {return y(d);});

BUT, having said all that, I think you would be better served by starting from a simpler example such as http://bl.ocks.org/duopixel/4063326 or one of the other approaches listed in this question or this question. It's hard to separate just the animated line portion of your original example from the rest of the cool stuff it's doing.

查看更多
登录 后发表回答