wootscootinboogie
wootscootinboogie

Reputation: 8695

d3.js animate line drawing happens in opposite direction as expected

I have a simple line graph in d3.js and that I wish to animate the drawing of the line. Fiddle: here. The animation aspect works, but I'd like the line to be drawn from the left to right, instead of right to left as in the fiddle. Why is the line being drawn from the end to the beginning instead of vice

/*canvas setup*/
var margin = {top: 20, right: 20, bottom: 70, left: 100},
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg").attr("id","chart")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("class","container")
            .attr("transform",translate(margin.left,margin.bottom));
function translate(a,b){
    return "translate(" + a + "," + b + ")";
}
/*data*/

    var data = [{
        "time": "2013-03-12 15:09:04",
        "value": "5"
    }, {
        "time": "2013-03-12 14:59:06",
        "value": "65"
    }, {
        "time": "2013-03-12 14:49:04",
        "value": "15"
    }, {
        "time": "2013-03-12 14:39:06",
        "value": "25"
    },{
        "time": "2013-03-12 14:29:03",
        "value": "5"
    }];
    /*end data*/

    var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
        data.forEach(function(d) {
            d.time = parseDate(d.time);
            d.value = +d.value;
        });
        //create scales
        var xScale = d3.time.scale()
            .range([0,width])
            .domain(d3.extent(data,function(d){ return d.time})),
            yScale = d3.scale.linear()
                .range([height,0])
                .domain([0,d3.max(data,function(d){ return +d.value})]);

        //create axes
        var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient("bottom")
            .tickFormat(d3.time.format("%H:%m"));

        //create line
        var line = d3.svg.line()
                .x(function(d){return xScale(d.time)})
                .y(function(d){ return yScale(d.value)});

        var _line; //path that will be appended to the chart

        var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient("left");

        var _x = svg.append("g")
                        .attr("class","xAxis")
                        .attr("transform",translate(0,height))
                        .call(xAxis);
       var _y = svg.append("g")
                        .attr("class","yAxis")
                        .call(yAxis);
    //draw line
    function drawLine(){
        _line = svg.append("path")
                        .attr("d", line(data))
                        .attr("stroke", "steelblue")
                        .attr("stroke-width", "2")
                        .attr("fill", "none");

        var totalLength = _line.node().getTotalLength();
        _line.attr("stroke-dasharray", totalLength + " " + totalLength)
                            .attr("stroke-dashoffset", totalLength)
                            .transition()
                            .duration(750)
                            .ease("swing")
                            .attr("stroke-dashoffset", 0);

    }
    setTimeout(function(){
        drawLine();
    },500)

Upvotes: 3

Views: 1140

Answers (1)

jhinzmann
jhinzmann

Reputation: 988

The line is animated from the right because you animate from a offset of totalLength to 0. Therefore your animation-startingpoint is: Line starts at the end and your animation end is that the line starts at the actual beginning. You just have to turn around this logic to let it start with a negative offset by setting .attr("stroke-dashoffset", -totalLength)

I updated your fiddle with this minor change.

Upvotes: 6

Related Questions