2013-06-14 12 views
7

Rysuję wykresy liniowe z d3 i wszystko działa dobrze. Muszę jednak zostawić wystarczająco dużo marginesu po lewej stronie obszaru wykresu, aby dopasować wszystko, co może być najszerszą etykietą tekstową osi Y. Chciałbym dostosować tę przestrzeń dla każdego wykresu, w zależności od najszerszej etykiety.Ustaw oś Y na wykresie d3, aby dopasować najszerszą etykietę?

Początkowo myślałem, że znajdę maksymalną wartość y, utworzę ukryty obiekt tekstowy, ustalę jego szerokość i wykorzystam tę wartość dla lewego marginesu podczas tworzenia wykresu. Trochę nieprzyjemnie, ale daje mi to wartość.

Jednakże, jeśli maksymalna wartość y wynosi, "1598.538", najwyższa etykieta osi Y może wynosić "1500" ... tj. Dużo węższe.

Sądzę więc, że chcę znaleźć szerokość tego, co faktycznie będzie najwyższą etykietą. Ale nie mogę myśleć, jak to zrobić bez rysowania wykresu i osi, mierzenia tej szerokości i ponownego rysowania jej na serio. Co brzmi paskudnie! Czy istnieje nieprzyjemny sposób na zrobienie tego?

UPDATE

Tutaj jest część mojego kodu przy użyciu sugestię Larsa, żeby pokazać gdzie pasuje:

// I did have 
// `.attr("transform", "translate(" + margin.left + "," + margin.top ")")` 
// on the end of this line, but I've now moved that to the bottom. 
var g = svg.select("g"); 

// Add line paths. 
g.selectAll(".line").data(data) 
    .enter() 
    .append("path") 
    .attr("d", line); 

// Update the previously-created axes. 
g.select(".axis-x") 
    .attr("transform", "translate(0," + yScale.range()[0] + ")")) 
    .call(xAxis); 
g.select(".axis-y") 
    .call(yAxis); 

// Lars's suggestion for finding the maximum width of a y-axis label: 
var maxw = 0; 
d3.select(this).select('.axis-y').selectAll('text').each(function(){ 
    if (this.getBBox().width > maxw) maxw = this.getBBox().width; 
}); 

// Now update inner dimensions of the chart. 
g.attr("transform", "translate(" + (maxw + margin.left) + "," + margin.top + ")"); 

Odpowiedz

6

można umieścić wszystko wewnątrz elementu g i zestaw transform na podstawie maksymalna szerokość. Coś na wzór

var maxw = 0; 
yAxisContainer.selectAll("text").each(function() { 
    if(this.getBBox().width > maxw) maxw = this.getBBox().width; 
}); 
graphContainer.attr("transform", "translate(" + maxw + ",0)"); 
+0

Doskonale, jeszcze raz dziękuję Lars! Zaktualizuję moje pytanie, dodając nieco więcej przykładowego kodu, aby pokazać, gdzie umieszczam Twoją sugestię w odniesieniu do innych części kodu rysowania wykresów. –

+0

Powiedziawszy, że ... podczas gdy pozostawia idealną przestrzeń dla lewej osi, robi to przesuwając obszar wykresu w prawo, który spina prawą krawędź wykresu i oś X. Nie jestem pewien, jak to naprawić - czy nie wynika to z zakresu skali osi X, który powinien być ustawiony wcześniej? –

+0

Można również narysować oś y, a następnie zmierzyć, a następnie odpowiednio ustawić zakres osi X i narysować resztę wykresu. Posiadanie elementów osi y może już zakłócać selektory, które masz do rysowania reszty wykresu ('.selectAll ('path')', '.selectAll ('text')'), więc bądź ostrożny. –

Powiązane problemy