How can I position rotated x-axis labels on column chart using nvd3?
Asked Answered
T

6

26

I am building a bar chart using nvd3's multiBarChart and need to adjust the position of rotated x-axis labels:

enter image description here

var chart = nv.models.multiBarChart();
...
chart.rotateLabels(-90);

I would like the column labels to not overlap the chart and be centered under each bar. I could select the labels after plotting the chart and adjust them but is there an easier way?

Tarnetgaronne answered 30/10, 2012 at 10:23 Comment(1)
Must say nice job in asking... did help me solving a similar problem. Thanks!Bore
J
35

The best way I have found to handle this is to perform the rotation of the x-axis tick labels yourself. Why? Because NVD3 is not handling the rotation and associated translations properly. Look at your image, and you'll see that the library allows the rotation to translate the labels out from directly under the columns they represent. It also begins to mishandle the axis.tickPadding() values, and so on.

The first thing that you need to do is to ensure that the chart has enough space for the translated labels, like so:

chart.margin({bottom: 60});

We can then translate and rotate the labels:

var xTicks = d3.select('.nv-x.nv-axis > g').selectAll('g');
xTicks
  .selectAll('text')
  .attr('transform', function(d,i,j) { return 'translate (-10, 25) rotate(-90 0,0)' }) ;

The labels now look like this:

Rotated / translated labels

Jackboot answered 20/11, 2012 at 11:38 Comment(3)
thanks for that. Where are you supposed to do that? I have several charts, and if I do you as you say, it only works for the first chart. Maybe there's some race condition and I need to only rotate the labels when I'm sure that the charts are done drawing. Any idea how to know that?Taxpayer
You would need to either find a way to select all the xTicks at the same time (by changing the '.nv-x.nv-axis >g' selector to something sensible), but that might be difficult. You probably have to do this for each one, selecting their xTicks in turn. Ensure that you give each chart its own class / id so that you can easily select them.Jackboot
was scratching my head for hours for a similar problem... this really did the trick... Thanks!Bore
C
5

For multiple graph, your can add "'#' + containerId + ' svg " in the d3.select like below:

//Rotate x-axis label
var xTicks = d3.select('#' + containerId + ' svg .nv-x.nv-axis > g').selectAll('g');
xTicks
    .selectAll('text')
    .attr('transform', function(d,i,j) { return 'translate (-15, 60) rotate(-90 0,0)' });

Anyways, Thanks for @River answer.

Commutative answered 5/12, 2013 at 6:59 Comment(1)
Just a note to say that you can (and should) do this for any of the other chart types. It's a good idea to specify the specific D3 container you're operating on, especially if there are multiple charts involved.Packard
E
1

This worked for me. The main reason I'm submitting this is that changing the anchor is nicer than translating the position manually.

var xTicks = d3.select('.nv-x.nv-axis > g > g',_this.context.element).selectAll('g').selectAll('text');
xTicks.attr('transform', function() { return 'rotate(' + angle + ' 0,0)' }) ;
xTicks.attr('text-anchor',function() {
    var anchor;
    if(angle > 0){ anchor = 'start'; }
    else if(angle < 0){ anchor = 'end'; }
    else { anchor = 'middle'; }
    return anchor;
});
Elle answered 4/6, 2014 at 18:3 Comment(1)
Slight suggested change xTicks.style({ 'text-anchor': (function() { var anchor; .... })()});Reposit
W
1

The following worked for me:

chart.axislist["xAxis"]["rotateLabels"]= -45
Wrenn answered 26/5, 2016 at 9:4 Comment(0)
C
0

Whatever you text rotation is give start/middle/end

d3.select('.nv-x.nv-axis > g > g').selectAll('g.tick text').style('text-anchor', 'start');  //start/middle/end
Chinn answered 11/12, 2014 at 5:23 Comment(0)
K
0

There is a css alternative.

.nv-x .tick text {
    transform: rotate(-90deg) translateX(-15px) translateY(-7px);
}
Kg answered 7/6, 2018 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.