score:5

Accepted answer

The problem is not related to screen size as it might appear also for cases like this: you have just 3 days to display and instead of 3 ticks you will get 6 or 10 or whatever (actually that's precisely the case you're in if I look at your jsfiddle). It is true that nvd3 uses something like this to set the dimensions of the ticks (take a look at axis.js):

if (ticks !== null)
    axis.ticks(ticks);
 else if (axis.orient() == 'top' || axis.orient() == 'bottom')
    axis.ticks(Math.abs(scale.range()[1] - scale.range()[0]) / 100);

There are several solutions to this problem:

  • you either implement your own axis component and replace the nvd3's axis

  • you either modify the nvd3's axis component directly and add some settings that would then be used specifically for this scenario you are describing (you will notice that as it is nvd3 is highly customizable).

  • Hack: you use d3's own tickValues() and pass it an array with the dates you want to have on the screen (example: first date, last date and several dates in between calculated by your algorithm). See d3's documentation: https://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickValues. Depending on the case (which axis you want to modify and which chart) you not only need to comment the code I pasted you and add your algorithm for setting the tickValues to the chart component (lineChart for example) but also you will need to add a setter for tickValues and overwrite the values with your values.

score:2

A late reply , but might be useful to others. I use a workaround to eliminate duplicate ticks, by maintaining an array of already applied ticks & d3's multi format specifier.

    uniqueTicks = [];
    xTickFormat = d3.time.format.multi([
                                        ["%Y", function (d) {
                                        // If tick not applied yet                                            
                                        if (uniqueTicks.indexOf(d.getFullYear()) === -1) {
                                                uniqueTicks.push(d.getFullYear());
                                                return true;
                                            } else {
                                                return false;
                                            }                                        
                                        }],
                                        ["", function () {
                                            return true;
                                        }]
                                    ]);

    d3.svg.axis().tickFormat(xTickFormat );

This trick can be tweaked for any other type of tick format.


Related Query