10

当日期数量有限时,x 轴喜欢重复日期。请看这个小提琴:

http://jsfiddle.net/skilesare/bFfJ2/1/

nv.addGraph(function() {  

    var data = fakeActivityByDate();

    var chart = nv.models.lineChart();




chart.xAxis
       .axisLabel('Date')
       .rotateLabels(-45)
       .tickFormat(function(d) { return d3.time.format('%b %d')(new Date(d)); });

   chart.yAxis
       .axisLabel('Activity')
       .tickFormat(d3.format('d'));

   d3.select('#chart svg')
       .datum(data)
     .transition().duration(500)
       .call(chart);

   nv.utils.windowResize(function() { d3.select('#chart svg').call(chart) });

   return chart;
 });

function days(num) {
  return num*60*60*1000*24
}
 /**************************************
  * Simple test data generator
  */

function fakeActivityByDate() {
   var lineData = [];
   var y=0;
   var start_date = new Date() - days(365); // one year ago

   for (var i = 0; i < 4; i++) {
     lineData.push({x: new Date(start_date + days(i)), y: y});
     y=y+Math.floor((Math.random()*10)-3);
   }

   return [
     {
       values: lineData,
       key: 'Activity',
       color: '#ff7f0e'
     }
   ];
 }`

如果您的屏幕足够宽,您会看到重复的日期。如果你挤压窗户,问题就会消失。

4

2 回答 2

5

这个问题与屏幕尺寸无关,因为它也可能出现在这样的情况下:你只有 3 天的时间来显示,而不是 3 个刻度,你会得到 6 或 10 或其他任何东西(实际上,如果我看看你的jsfiddle)。确实,nvd3 使用类似这样的东西来设置刻度的尺寸(看看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);

这个问题有几种解决方案:

  • 您要么实现自己的轴组件并替换 nvd3 的轴

  • 您可以直接修改 nvd3 的轴组件并添加一些设置,然后专门用于您所描述的这种情况(您会注意到 nvd3 是高度可定制的)。

  • 技巧:您使用d3自己的tickValues()并向其传递一个数组,其中包含您希望在屏幕上显示的日期(例如:第一个日期、最后一个日期以及由您的算法计算出的几个日期)。请参阅 d3 的文档:https ://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickValues 。根据具体情况(您要修改哪个轴和哪个图表),您不仅需要注释我粘贴的代码并将您的算法设置为图表组件(例如 lineChart),还需要添加tickValues 的设置器并用您的值覆盖这些值。

于 2013-02-10T19:20:06.813 回答
2

迟到的回复,但可能对其他人有用。我使用一种解决方法来消除重复的记号,方法是维护一组已应用的记号和 d3 的多格式说明符。

    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 );

这个技巧可以针对任何其他类型的刻度格式进行调整。

于 2015-06-09T07:42:10.453 回答