2013-02-10 7 views
10

Oś x lubi powtarzać daty, gdy jest ograniczona liczba dat. Proszę zobaczyć ten skrzypce:Jak mogę zachować powtarzanie znaczników, gdy mam małą liczbę dat na wykresie nvd3

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' 
    } 
    ]; 
}` 

Jeśli ekran jest na tyle szeroki, widać dat powtarzanych. Jeśli przeczytasz okno, problem zniknie.

Odpowiedz

5

Problem nie jest związany z rozmiarem ekranu, ponieważ może się wydawać również w takich przypadkach: masz tylko 3 dni na wyświetlenie, a zamiast 3 tyknięć otrzymasz 6 lub 10 lub cokolwiek (w rzeczywistości tak właśnie jest " wejdź ponownie, jeśli spojrzę na twoje jsfiddle). Prawdą jest, że nvd3 używa mniej więcej tak, aby ustawić wymiary kleszczy (przyjrzeć 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); 

Istnieje kilka rozwiązań tego problemu:

  • ciebie albo zaimplementować własną składową osi i wymienić nvd3 za oś

  • trzeba albo zmodyfikować składnik osi nvd3 bezpośrednio i dodać kilka ustawienia, które będą następnie wykorzystywane specjalnie do tego scenariusza są opisujące (zauważysz, że jak to jest nvd3 jest wysoce konfigurowalny).

  • Hack: użyć D3 własne tickValues ​​() i przekazać tablicę z datami chcesz mieć na ekranie (przykład: najpierw data, ostatni dzień i kilku dat w między oblicza twój algorytm). Zobacz dokumentację d3: https://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickValues. W zależności od przypadku (która oś ma zostać zmodyfikowana i który wykres) nie tylko trzeba skomentować kod, który wkleiłem i dodać algorytm do ustawiania wartości tick dla składnika wykresu (na przykład lineChart), ale także trzeba dodać setter dla tickValues ​​i zastąpić wartości swoimi wartościami.

2

Późna odpowiedź, ale może być przydatna dla innych. Używam obejścia, aby wyeliminować duplikaty tyknięć, utrzymując tablicę już zastosowanych tyknięć. Wielokrotny specyfikator formatu 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); 

Ta sztuczka może zostać zmodyfikowana dla każdego innego rodzaju formatu zaznaczenia.