Search code examples
d3.jstransitionaxis-labels

transitioning rotated axis labels with D3


I'm trying to create a graph that updates as new values are coming in. In order for the labels on the X axis to be readable I decided to rotate them slightly, so they don't overlap.

When there's a new value, it's being drawn in the graph, then the path (actually the container ) is translated to the left in a transition.

This is how i create the rotated axis labels:

    svg.select(".x.axis")
        .call(this.xAxis)
        .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", ".15em")
            .attr("transform", this.axislabelrotation);

this.axislabelrotation is:

function(d) {
    return "rotate(-35)" 
}

And this is how i transition the X axis:

    svg = svg.transition().duration(750);
    svg.select(".x.axis") // change the x axis
        .call(this.xAxis)
        .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", ".15em")
            .attr("transform", this.axislabelrotation);

Though now I have two issues:

  1. At the beginning of the transition the X axis labels jump down a few pixels, during the transition they go back up.
  2. Newly entered labels ("2015" in the example) are not rotated at the beginning of the transition, though rotate to the desired state during the transition.

Example: http://jsfiddle.net/esy6wk8n/2/


Solution

  • I'd suggest that you remove the transition on the dy and transform attribute.

    This updated fiddle may help you with that: http://jsfiddle.net/esy6wk8n/4/

    The changes are all in your update function.

        var no_trans = svg;
        svg = svg.transition().duration(750);
    
        lp.transition()
            .duration(750)
            .attr("transform", "translate(" + this.x(data[0].jdate) + ")");
    
        lu.transition()
            .duration(750)
            .attr("transform", "translate(" + this.x(data[0].jdate) + ")");
    
        svg.select(".x.axis") // change the x axis
            .call(this.xAxis)
            .selectAll("text")
                .style("text-anchor", "end")
                .attr("dx", "-.8em");
                //.attr("dy", ".15em")
                //.attr("transform", this.axislabelrotation);
    
        no_trans.select(".x.axis")
            .selectAll("text")
                .attr("dy", ".15em")
                .attr("transform", this.axislabelrotation);
    

    Basically, I have moved the update of the dy and transform attributes out of the transition, so therefore these values will be set straight away and not be changed as part of the transition, keeping the dy and the transform stable throughout the transition.