2014-01-23 150 views
7

我在xAxis上显示日期时遇到一个奇怪的问题。 我生成的数据是这样的:d3.js nvd3在x轴上的日期:只显示一些日期

for (i=0;i<12;i++){ 
    date=new Date(2013,i,1); 

    ideas.values[i] = {"y" : Math.round(2*i*getRandom(1,2)), "x": date}; 
} 

在我的线型图,我想创建x轴这样的:

chart.xAxis.tickSize(12)    
      .tickFormat(function(d) {   
      var date = new Date(d); 
      testarr.push(date); 
      return d3.time.format('%b %y')(date); 
      }); 

现在,如果我看看表,只有少数日期可见。这就是为什么我创建阵列“testarr”来解决问题的原因。 testarr的内容是 8日期而不是12(我生成12)

现在更奇怪的事情:把完全相同的数据放在MultiBarChart中,并使用EXACT相同的chart.xAxis ....函数,测试阵列的内容有12个值

我很无语,希望有人能帮助我。

谢谢你们!

完成以下代码:

为线型图:lineChart Result

<script> 
var chart; 
nv.addGraph(function() { 
    chart = nv.models.lineChart() 
    .options({ 
    margin: {left: 100, bottom: 100}, 
    //x: function(d,i) { return i}, 
    showXAxis: true, 
    showYAxis: true, 
    transitionDuration: 250 
    }) 
    ; 
    chart.xAxis.tickSize(12)    
        .tickFormat(function(d) {   
     var date = new Date(d); 
      return d3.time.format('%b %y')(date); 
       }); 

    chart.yAxis 
     .axisLabel('y axis') 
     .tickFormat(d3.format('')) 
     .axisLabelDistance(50); 

    d3.select('#chart1 svg') 
    .datum(dataForChart) 
    .call(chart); 

    //TODO: Figure out a good way to do this automatically 
    nv.utils.windowResize(chart.update); 
    //nv.utils.windowResize(function() { d3.select('#chart1 svg').call(chart) }); 

    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); }); 

    return chart; 
}); 

var dataForChart=function(){ 

     var section1 = new Array(); 
     section1.key="Section 1"; 
     section1.values = new Array(); 
     section1.color="#1F77B4"; 

     var section2 = new Array(); 
     section2.key="Section2"; 
     section2.values = new Array(); 
     section2.color="#2CA02C"; 

     for (i=0;i<12;i++){ 
      date=new Date(2013,i,1); 

      section1.values[i] = {"y" : Math.round(2*i*getRandom(1,2)), "x": date}; 
      section2.values[i] = {"y" : Math.round(6*i+2*getRandom(1,2)), "x": date}; 
     } 

     function getRandom(min, max) 
     { 
      return Math.random() * (max - min + 1) + min; 
     } 

     var dataArray=new Array(); 
     dataArray.push(section1); 
     dataArray.push(section2); 

     return dataArray; 
};  

</script> 

如果我不注释掉

//x: function(d,i) { return i}, 

部分,轴处处展示Jan70。

对于低于MultiBarChart代码:​​

<script> 
var chart; 
nv.addGraph(function() { 
    chart = nv.models.multiBarChart() 
     .margin({bottom: 30, top:25}) 
     .transitionDuration(300) 
     .delay(0) 
     .groupSpacing(0.2) 
     .reduceXTicks(false) 
     .showControls(true) 
     .showLegend(true) 
     .staggerLabels(false) 

     ; 
    chart.xAxis.tickSize(12)    
      .tickFormat(function(d) { 
     console.log(d,arguments); 
     var date = new Date(d); 
       return d3.time.format('%b %y')(date); 
      }); 

    chart.yAxis 
     .axisLabel(dataForChart.ylabel) 
     .tickFormat(d3.format('')) 
     .axisLabelDistance(50); 

    d3.select('#chart1 svg') 
     .datum(dataForChart) 
     .call(chart); 

    nv.utils.windowResize(chart.update); 


    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); }); 

    return chart; 
}); 


var dataForChart=function(){ 

     var section1 = new Array(); 
     section1.key="Section 1"; 
     section1.values = new Array(); 
     section1.color="#1F77B4"; 

     var section2 = new Array(); 
     section2.key="Section2"; 
     section2.values = new Array(); 
     section2.color="#2CA02C"; 

     for (i=0;i<12;i++){ 
      date=new Date(2013,i,1); 

      section1.values[i] = {"y" : Math.round(2*i*getRandom(1,2)), "x": date}; 
      section2.values[i] = {"y" : Math.round(6*i+2*getRandom(1,2)), "x": date}; 
     } 

     function getRandom(min, max) 
     { 
      return Math.random() * (max - min + 1) + min; 
     } 

     var dataArray=new Array(); 
     dataArray.push(section1); 
     dataArray.push(section2); 

     return dataArray; 
};  

</script> 
+0

除非您向我们展示如何创建和使用此阵列的完整代码,否则我们无法真正帮助您。 –

+0

感谢您的回复。我现在粘贴了整个代码。 –

+0

我仍然不完全确定你在问什么。是@ AmeliaBR的回复假设是关于蜱吗? –

回答

23

线图表轴,像所有的线性轴,使用刻度来显示上线关键点,但不是每一个可以想到的值。在很多情况下,如果图表显示了每个数据,那么标记会非常接近,以致标签会重叠并变得不可读。预计人们可以根据与相邻刻度线的距离来估计线上的位置。

相反,对于条形图的x值被假定为不同的类别,这可能会不具有自然顺序。他们可能是“苹果”,“橙子”和“香蕉”。无法根据相邻标签(“苹果”和“香蕉”)的值估算中间值(“橙子”),因此默认情况下会显示所有标签,即使它们最终重叠且无法读取。

但对于你的线图,在你只有12个日期值,所以你有空间,以适应不重叠的所有的标签?通常的d3方法告诉轴它应该包括多少个剔号是axis.ticks()。我看到你试图做类似的事情,但axis.tickSize()方法控制着每个刻度线的长度,而不是有多少。但是,axis.ticks()不适用于NVD3 - 内部方法会覆盖您在轴上设置的任何值。

不要担心,仍然有办法控制它,但它需要一些额外的代码。 axis.tickValues()方法取代axis.ticks(),因此您可以使用它来取代NVD3默认设置。

您在axis.tickValues()中包含的信息是数组的每个滴答的显式值。由于您的x轴值是日期,并且每个月有一个值,所以您可以通过两种方法创建此数组:

选项1:直接从数据中获取x值。

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. 

选项2:使用D3 time interval方法来计算日期的序列。

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

我希望现在一切都有意义。

+0

我发布此消息后,我看到了您的更新;基于更复杂的代码(包含两个数据系列),您必须选择其中一个数据系列(哪一个数据系列没有关系,因为它们都具有相同的日期),从中获取values数组,并使用它为地图功能。 “选项2”方法不会改变,所以使用它可能更容易和更一致。 – AmeliaBR

+0

.tickValues(...)对我来说工作得很好。但我仍然没有弄清楚为什么它对BarChart没有任何问题之前工作.. –

+0

它是一种不同类型的规模 - 类别(“序数”)规模,恰巧有日期或数字作为类别名称,而不是连续的(“线性”)规模。所以有不同的默认行为。 – AmeliaBR