2012-12-07 18 views
8

Próbuję wyrenderować prosty wykres słupkowy z etykietą dla każdego paska jako tyknięcia osi na osi X. Dłuższe etykiety przebiegają jedna nad drugą. Ponieważ elementy tekstowe svg nie obsługują zawijania tekstu, szukałem alternatywnych rozwiązań.Symbole osi multilinii svg tekstu w d3

Zmiana tekstu kategorii umieszczanego na etykietach w celu uwzględnienia odpowiednich elementów nie działa, ponieważ tekst nie jest ustawiony jako innerHtml, a jedynie tekst nieprzetworzony elementu. Rozważyłem także post-processing etykiet, aby usunąć tekst i zastąpić go tspanami, ale nie znalazłem jeszcze eleganckiego sposobu na to.

Niestety nie mogę używać obiektu foreignObject, ponieważ potrzebuję wsparcia dla IE9, ale i tak wiele z tych samych problemów z zastępowaniem znaczników dotyczyłoby tego rozwiązania.

Czy ktoś rozwiązał ten problem w przeszłości lub miał jakieś sugestie?

+0

Bardzo podobny http://stackoverflow.com/questions/12677878/change-svg-text-to-css-word-wrapping –

+1

Dwie kluczowe różnice: 1. Ponieważ d3 generuje etykiety znaczników, nie mogę łatwo zastąpić ich znaczników (jak podano w pytaniu). 2. Nie mogę używać obcego obiektu z powodu braku wsparcia IE9 (doda do pytania). –

+0

Czy możesz podać przykład tego, jak wygasasz w tekście? – Duopixel

Odpowiedz

5

Można to zrobić ręcznie, jak owijanie w this example Mike Bostock:

function wrap(text, width) { 
    text.each(function() { 
    var text = d3.select(this), 
     words = text.text().split(/\s+/).reverse(), 
     word, 
     line = [], 
     lineNumber = 0, 
     lineHeight = 1.1, // ems 
     y = text.attr("y"), 
     dy = parseFloat(text.attr("dy")), 
     tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); 
    while (word = words.pop()) { 
     line.push(word); 
     tspan.text(line.join(" ")); 
     if (tspan.node().getComputedTextLength() > width) { 
     line.pop(); 
     tspan.text(line.join(" ")); 
     line = [word]; 
     tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); 
     } 
    } 
    }); 
} 

vis.selectAll(".tick text") 
    .call(wrap, 100);