d3.js nvd3 date on x axis: only some dates are show

心已入冬 提交于 2019-11-28 19:00:29
AmeliaBR

Line chart axes, like all linear axes, use tick marks to show key points on the line, but not every conceivable value. In many cases, if the chart showed every data, the ticks would be so close together that the labels would overlap and become unreadable. People are expected to be able to estimate the position on the line based on the distance to adjacent tick marks.

In contrast, the x-values for the bar chart are assumed to be distinct categories, which might not have a natural order. They could be "apples", "oranges", and "bananas". There's no way to estimate a middle value ("oranges") based on the values of adjacent labels ("apples" and "bananas"), so by default all the labels are shown, even if they end up overlapping and unreadable.

But what about your line chart, where you only have 12 date values, so you have room to fit all the labels without overlap? The regular d3 method to tell the axis how many ticks it should include is axis.ticks(). I see you tried to do something similar, but the axis.tickSize() method controls the length of each tick line, not how many there are. However, axis.ticks() doesn't work with NVD3 -- the internal methods over-write any value you set on the axis.

Don't worry, there is still a way to control it, but it requires some extra code. The axis.tickValues() method supercedes axis.ticks(), so you can use it to over-ride the NVD3 default.

The information you include in axis.tickValues() is an array of explicit values for each tick. Since your x-axis values are dates, and you have one value for each month, you have two ways of creating this array:

Option 1: Get the x values directly from your data.

chart.xAxis.tickValues(ideas.values.map( function(d){return d.x;} ) );

//Array.map(function) creates a new array, where each value is the result of
//calling the function on the corresponding element of the original array.
//Since your data is in ideas.values as an array of {x:date, y:number} objects,
//this method creates an array containing all the dates from your data.

Option 2: Use a d3 time interval method to calculate a sequence of dates.

chart.xAxis.tickValues(d3.time.month.range(
                            new Date("2013 01"),
                            new Date("2014 01"),
                            1)
                        );

//d3.time.month.range(startDate, stopDate, step) creates the sequence of dates
//that are exact month values, starting with the month on or after the startDate 
//and continuing to the last start of month *before* the stop date
//(so it won't include January 2014.  The step value tell it how many months
//to skip at a time; we want every month, so step==1.

//There are similar methods for year, week, day, hour, minute and second, 
//and also versions for weeks starting on specific days of the week;
//Just replace "month" in "d3.time.month.range" with the appropriate interval.
//For plain numbers, use d3.range(start, stop, step).

I hope that all makes sense now.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!