NVD3 Line Chart X Axis Ticks Are Missing
Asked Answered
A

2

8

I am using NVD3 to display line chart here: http://jsbin.com/xodaxafiti/2/edit?js,output

But it seems like NVD3 auto-hide some tickLabels on XAxis, but only those ticks near the edge, i.e. 2-3Oct and 27-28Oct (except the first and last tick). I know that this is an auto-reduce because when I increase the width of chart, the ticks start to show up. However I find that this reducing behaviour weird, and the lineChart does not have reduceXTicks option like multiBarChart.

I want to be able to control the reducing behaviour myself like this:

var chart = nv.models.lineChart()       
   .useInteractiveGuideline(true)
   .margin({left: 80,top: 20,bottom: 120,right: 20});  

chart.xAxis.ticks(function() {
   return data[0].map(chart.x()).filter(function(d,i) {
      i % Math.ceil(data[0].values.length / (availableWidth / 100)) === 0;
   })
})

But it didn't work. Anyone has any idea how to control this?

missing tickLabels

Amling answered 29/10, 2014 at 7:1 Comment(3)
Use .tickValues() instead of .ticks().Intraatomic
I've tried using .tickFormat() before, but it gave me a filter on top of the above missing tickLabels. Besides, when using this trick, the hidden label will not even show up in tooltip. I believe tickValues() will have the same result.Amling
Hmm, I would use a time scale for the x axis -- this should allow you to control better what's shown. This question should be helpful for that.Intraatomic
C
19

The reducing behavior works because the showMaxMin set to true by default. Adding .showMaxMin(false) fixes the problem:

chart.xAxis.axisLabel("XAxisLabel")
    .showMaxMin(false)    
    .tickValues(tickvalues)        
    .tickFormat(function (d) {
      return tickformat[d];
      })
;

enter image description here

Candlefish answered 30/10, 2014 at 10:2 Comment(2)
watch out that you don't have any tickvalues that are out of range or they'll appear to the left of the yaxis. you can also use xDomain to set the extent of the xAxisPelargonium
This one was messing my mind, thank you for the solution!Down
D
0

In case you want to have both the boundary ticks and the ticks close to the boundary(MaxMin) values, you can modify the source.

In the nv.models.axis(), there is a buffer given when showMaxMin is true for a bottom/top orientation:

if (showMaxMin && (axis.orient() === 'top' || axis.orient() === 'bottom')) {
            var maxMinRange = [];
            wrap.selectAll('g.nv-axisMaxMin')
                .each(function(d,i) {
                   try {
                        if (i) // i== 1, max position
                            maxMinRange.push(scale(d) - this.getBoundingClientRect().width - 4);  //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)
                        else // i==0, min position
                            maxMinRange.push(scale(d) + this.getBoundingClientRect().width + 4)
                    }catch (err) {
                        if (i) // i== 1, max position
                            maxMinRange.push(scale(d) - 4);  //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)
                        else // i==0, min position
                            maxMinRange.push(scale(d) + 4);
                    }
                });
            // the g's wrapping each tick
            g.selectAll('g').each(function(d, i) {
                if (scale(d) < maxMinRange[0] || scale(d) > maxMinRange[1]) {
                    if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL
                        d3.select(this).remove();
                    else
                        d3.select(this).select('text').remove(); // Don't remove the ZERO line!!
                }
            });
}

I just removed these buffers:

try {
        if (i) // i== 1, max position
            maxMinRange.push(scale(d));
        else // i==0, min position
            maxMinRange.push(scale(d))
 }catch (err) {
         if (i) // i== 1, max position
              maxMinRange.push(scale(d));
         else // i==0, min position
              maxMinRange.push(scale(d));
 }
Decorous answered 22/7, 2015 at 18:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.