2013-07-09 14 views

Odpowiedz

41

skończyło się z jednym z Lars Kotthoff's advices.

Za każdym razem, gdy I call(axis) również dostosowuję etykiety tekstowe.
Tutaj jest uproszczony kod:

function renderAxis() { 
    axisContainer 
     .transition().duration(300) 
     .call(axis)     // draw the standart d3 axis 
     .call(adjustTextLabels);  // adjusts text labels on the axis 
} 

function adjustTextLabels(selection) { 
    selection.selectAll('.major text') 
     .attr('transform', 'translate(' + daysToPixels(1)/2 + ',0)'); 
} 

// calculate the width of the days in the timeScale 
function daysToPixels(days, timeScale) { 
    var d1 = new Date(); 
    timeScale || (timeScale = Global.timeScale); 
    return timeScale(d3.time.day.offset(d1, days)) - timeScale(d1); 
} 

Aktualizacja:
BTW, tutaj jest demo kalendarz które skończyło się: http://bl.ocks.org/oluckyman/6199145

enter image description here

5

Nie ma prostego (czyli wbudowane) sposób robienia tego, ale nadal możesz to osiągnąć. Istnieje kilka opcji. Najprostszym jest użycie tickFormat function do określenia formatu z odpowiednią liczbą spacji przed/po liczbach. Musiałoby to jednak zostać dostrojone ręcznie dla każdej aplikacji.

Można również wybrać elementy etykiety po ich narysowaniu i dodać odpowiedni atrybut transform, który odpowiednio je przesuwa. Ponownie, to musiałoby być ręcznie dostrojone.

Twoja trzecia opcja to dwie różne osie, jedna dla kleszczy i jedna dla etykiet. Chodzi o to, że oś, która dostarcza kleszcze, nie ma etykiet, a druga nie ma kleszczy. Musiałbyś odpowiednio ustawić wartości znaczników, ale przynajmniej nie musiałbyś zgadywać właściwego przesunięcia.

+0

pierwszy nie pomoże w moim przypadku, ponieważ oś jest zoomable. – oluckyman

+0

We wszystkich tych przypadkach konieczne jest zresetowanie odpowiednich parametrów po powiększeniu. –

2

Możesz to zrobić, używając axis.tickSize(major[[,minor],end]) i .tickSubdivide(). Twoje tyknięcia ustawiają się w linii z większymi kleszczami, ale jeśli ustawisz wysokość tych tyknięć na 0 i ustawisz wysokość dla mniejszych tyknięć i określisz, że istnieje jeden mniejszy tyk między każdą parą dużych tyknięć, to skończysz wraz z etykietami zaznaczającymi między kleszczami. Twój kod będzie wyglądał następująco:

var myAxis = d3.svg.axis() 
    .ticks(15) 
    .tickSubdivide(1) 
    .tickSize(0, 6, 0); 

Pamiętaj, że musisz wyraźnie ustawić rozmiar końcowy. Jeśli tylko zapewniają dwie liczby, będą interpretowane jako major i end i minor domyślnie 0.

Oto fiddle.

+0

Fajny hack! Ale z powodu tego włamania dane zostaną przesunięte, a zamiast "3" dostaniesz "3.5". Zobacz obrazek: http://i.stack.imgur.com/OmfDN.png – oluckyman

+0

Ostrzegam przed umieszczaniem etykiety w innym miejscu niż tyknięcie reprezentujące tę wartość. Jako użytkownik, założyłbym, że zaznaczenie między dwiema etykietami reprezentuje wartość między etykietami. Posiadanie go reprezentuje numer po jednej stronie lub po drugiej tworzy niejednoznaczność. Ponadto, d3 nie ma sposobu, aby to zrobić. – ckersch

+5

Istnieje specjalny przypadek: kalendarz. W terminach kalendarzowych i dniach roboczych są umieszczane między kleszczami. – oluckyman

0

I często to zrobić poprzez układanie wiele osi, każda z niestandardowym .tickFormat().

Jeśli mam umieszczania etykiet między datami, ja często zrobić coś takiego:

@timeDaysAxisLabels = d3.svg.axis() 
    .scale(@timescale) 
    .orient('bottom') 
    .ticks(d3.time.hour.utc, 12) # I want ticks at noon, easiest to just get them ever 12 hours 
    .tickFormat((d) => 
     # only draw labels at noon, between the date boundaries 
     if d.getUTCHours() == 12 
      # draw the label! 
      formatter = d3.time.format.utc('%a %d %b') # "Mon 12 Apr" 
      return formatter(d) 
     else 
      # not noon, don't draw anything 
      return null) 
    .tickSize(0) 
    .tickPadding(30) 

będę też utworzyć osobną oś bez etykiet w ogóle, a niezerowe .tickSize() faktycznie rysować tyknięcia, ale ten blok powyżej pozycji etykiety daty w środku "kolumny".

+0

Wow, dlaczego cała nienawiść do tej odpowiedzi? To solidna technika. –

1

Już kilka dobrych odpowiedzi, ale po prostu dodać jeszcze jeden. Zwróć uwagę na użycie text-anchor.

Taki sam pomysł: Po zakończeniu rozmowy wybierz tekst, zmień pozycję.

.call(xAxis)     
.selectAll(".tick text") 
.style("text-anchor", "start") 
.attr("x", axisTextAdjust) 
+1

Dokładnie to, czego potrzebowałem, dzięki – James

0
 svg.append("g") 
      .attr("class", "axis axis-years") 
      .attr("transform", "translate(0," + (height + 1) + ")") 
      .call(xAxis) 
     .selectAll("text") 

    .attr("x", "-1.8em") 
    .attr("y", ".00em") 
    .attr("transform", function (d) { 
     return "rotate(-90)"}); 
Powiązane problemy