obróć tekst osi X w d3

81

Jestem nowy w kodowaniu D3 i SVG i szukam sposobu na obracanie tekstu na osi x wykresu. Mój problem polega na tym, że zazwyczaj tytuły xAxis są dłuższe niż paski na wykresie słupkowym są szerokie. Więc szukam obrócenia tekstu tak, aby działał pionowo (a nie poziomo) pod xAxis.

Próbowałem dodać atrybut transformacji: .attr ("transform", "rotate (180)")

Ale kiedy to robię, tekst całkowicie znika. Próbowałem zwiększyć wysokość płótna SVG, ale nadal nie byłem w stanie wyświetlić tekstu.

Wszelkie przemyślenia na temat tego, co robię źle, byłyby świetne. Czy muszę również dostosować pozycje X i Y? A jeśli tak, to o ile (trudne do rozwiązania, gdy widzę to w Firebug).

jschlereth
źródło

Odpowiedzi:

166

Jeśli ustawisz transformację obracania (180), obraca element względem początku , a nie względem zakotwiczenia tekstu. Tak więc, jeśli twoje elementy tekstowe mają również ustawione atrybuty x i y, aby je pozycjonować, jest całkiem prawdopodobne, że obróciłeś tekst poza ekran. Na przykład, jeśli próbowałeś,

<text x="200" y="100" transform="rotate(180)">Hello!</text>

zakotwiczenie tekstu będzie wynosić ⟨-200,100⟩. Jeśli chcesz, aby zakotwiczenie tekstu pozostało na ⟨200,100⟩, możesz użyć przekształcenia, aby ustawić tekst przed obróceniem, zmieniając w ten sposób początek.

<text transform="translate(200,100)rotate(180)">Hello!</text>

Inną opcją jest użycie opcjonalnych argumentów cx i cy do transformacji rotacji SVG , aby można było określić początek obrotu. W końcu jest to trochę zbędne, ale dla kompletności wygląda to tak:

<text x="200" y="100" transform="rotate(180,200,100)">Hello World!</text>
mbostock
źródło
OK, więc to jest idealne. Dzięki, Mike. To robi (prawie) wszystko, co muszę zrobić. Ale teraz pytanie brzmi, jak automatycznie zmienić pozycję y na podstawie długości zmiennej? JEŚLI ustawię linię bazową jako: <text font-size = "12px" transform = "translate (20,170) rotate (-90)"> title 1 </text>. w porządku. ale powiedzmy, że następny tytuł jest dłuższy Nie chcę, aby nakładał się na wykres, a także chciałbym zminimalizować odstęp między osią x a samym wykresem.
jschlereth
1
Jeśli odpowiedziałem na Twoje pytanie, dodaj pole wyboru, aby zaznaczyć pytanie jako odpowiedź. Jeśli masz dodatkowe pytanie, utwórz nowe pytanie! Myślę, że możesz pytać o atrybut zakotwiczenia tekstu, aby ustawić wyrównanie tekstu, lub być może atrybut dy, aby ustawić linię bazową tekstu.
mbostock
3
Rozumiem ... text-anchor = 'end' <text text-anchor = "end" transform = "translate (20,130) rotate (-90)"> title1 </text> Jeszcze raz dziękuję za pomoc, Mike. Rządzisz!
jschlereth
44

Bezwstydnie wyrwany skądinąd , cała zasługa autora.

uwzględniony margines tylko w celu pokazania dolnego marginesu powinien zostać zwiększony.

var margin = {top: 30, right: 40, bottom: 50, left: 50},

svg.append("g")
   .attr("class", "x axis")
   .attr("transform", "translate(0," + height + ")")
   .call(xAxis)
     .selectAll("text")  
     .style("text-anchor", "end")
     .attr("dx", "-.8em")
     .attr("dy", ".15em")
     .attr("transform", "rotate(-65)");
20man
źródło
2

Jednym z problemów związanych z obrotowymi etykietami osi D3 jest to, że za każdym razem, gdy renderujesz oś, musisz ponownie zastosować tę logikę. Dzieje się tak, ponieważ nie masz dostępu do opcji enter-update-exit, których oś używa do renderowania znaczników i etykiet.

d3fc to biblioteka komponentów ze wzorem dekoracyjnym umożliwiającym uzyskanie dostępu do łączenia danych pod spodem używanego przez komponenty.

Ma drop-in zamiennik dla osi D3, w którym obrót etykiety osi jest wykonywany w następujący sposób:

var axis = fc.axisBottom()
  .scale(scaleBand)
  .decorate(function(s) {
    s.enter()
        .select('text')
        .style('text-anchor', 'start')
        .attr('transform', 'rotate(45 -10 10)');
  });

Zwróć uwagę, że obrót jest stosowany tylko przy wprowadzaniu wyboru.

wprowadź opis obrazu tutaj

Możesz zobaczyć inne możliwe zastosowania tego wzorca na stronie dokumentacji osi .

ColinE
źródło