2013-03-15 155 views
3

我想讓文本在使用d3的svg中垂直顯示。然而,我不想旋轉它:我希望字母保持水平,但是一個在另一個之上。設置writing-mode=tb似乎沒有做任何事情。這是我嘗試的:d3中的垂直文本(不旋轉)

svg.append("text") 
    .attr("x", 1000) 
    .attr("y", 400) 
    .attr("id", "title") 
    .attr("font-size", 50) 
    .attr("style", "font-family: arial; fill: lightgreen; writing-mode: tb") 
    .text("Top 100 Mentions"); 

文本顯示在正確的位置,與正確的字體等,但它是水平的。

+1

工作對我來說:http://jsfiddle.net/hx5Th/ – Duopixel 2013-03-15 17:08:25

+0

Firefox不支持TB書寫模式呢。 – 2013-03-15 17:11:05

+1

謝謝,那是問題所在。我在Chrome中嘗試過它,但它工作正常,但我需要在樣式中添加'glyph-orientation-vertical:0'來防止旋轉文本。 – Samarth 2013-03-16 01:04:07

回答

11

在談到旋轉SVG的文本,有多個不同的方面:

  • 瀏覽器如何確定在何處基於前一個字符的位置下一個字符位置;

  • 字符如何相對於基線旋轉(rotate屬性);

  • 最終文本塊作爲整體如何相對於座標系旋轉(transform屬性)。

Full, rather difficult to comprehend, specs here

的寫作模式「屬性應該改變第一個方面,而不會影響其他人,但你發現it's not implemented at all in Firefox,而IE旋轉文本,但不尊重水平字形規則。

理論上,你應該能夠通過組合旋轉,以獲得相同的效果和變換屬性:改變整個<text>元素將其旋轉到垂直位置,然後反向 - 旋轉單個字符,讓他們回水平。但在實踐中,它會變得混亂...

對於初學者來說,雙旋轉會導致文本最終在左(x,y)點,所以如果(x,y)是(0, 0)它將被剪切到SVG外部而無需補充輪班。由於進行了轉換,因此需要使用負數dy將文本移回到定位點的右側。

其次,有一個事實是,旋轉應用於每個角色到位,角色的間距不會被調整,以解釋「l」比寬度高很多的事實。所以除非你使用等寬空間,否則看起來很混亂。您應該可以使用kerningletterspacing屬性更改字母間距,但對這些屬性的瀏覽器支持也很差:IE11似乎沒有承認字距值,Firefox也不承認。

最後一個選擇是採取佈局自己的控制:使用D3的功率和字符串.split("")方法打破你標題分成單字符<tspan>元件可以定位一個下面彼此和內整齊地居中<text>元素。缺點是,這會增加額外的DOM元素,您仍然可以選擇整個文本塊,就像您可以在HTML段落中選擇一個短語一樣,即使每個字母的樣式都是獨立的<span>。我不知道,如果屏幕閱讀器會自動假設有字母之間的空間,但...

比較

這撥弄試行三種方式來獲得在垂直文本標籤水平字符(寫作-mode VS雙旋轉VS分裂成<tspan> S):
http://jsfiddle.net/hx5Th/11/

代碼:

var svg = d3.select("body").append("svg"); 

//Green text, uses writing-mode property // 
svg.append("text") 
    .attr("x", 40) 
    .attr("y", 40) 
    .attr("id", "title") 
    .attr("font-size", 50) 
    .attr("style", "fill: lightgreen; writing-mode: tb; glyph-orientation-vertical: 0") 
    .text("Top 100 Mentions"); 

//Black text, uses a double rotate // 
svg.append("text") 
    .attr("x", 40) 
    .attr("y", 40) 
    .attr("id", "title") 
    .attr("font-size", 50) 
    .attr("rotate", -90) 
    .attr("dx", "1em") 
    .attr("dy", "-1em") 
    .attr("kerning", 0) 
    .attr("letter-spacing", "0.5em") 
    .attr("transform", "translate(150,0) rotate(90)") 
    .text("Top 100 Mentions"); 

//Blue text, uses d3 to create a series of tspans// 
svg.append("text") 
    .attr("x", 40) 
    .attr("y", 40) 
    .attr("font-size", 50) 
    .attr("id", "title") 
    .style("fill", "blue") 
    .attr("transform", "translate(300,0)") 
    .attr("text-anchor", "middle") 
    .selectAll("tspan") 
     .data("Top 100 Mentions".split("")) 
    .enter().append("tspan") 
     .attr("x", 0) 
     .attr("dy", "0.8em") 
     .text(function(d){return d;}); 

結果(所有Windows 7的系統上):

鉻33 enter image description here

IE 11 enter image description here

火狐 enter image description here

我覺得這是D3的贏...

+0

我認爲這是AmeliaBR的勝利:-)不錯的工作。 – Samarth 2014-02-28 14:23:32

+0

對你來說晚了一年,但希望能在未來幫助其他人... – AmeliaBR 2014-02-28 18:08:40

+0

沒有開玩笑... @AmeliaBR的一個更多的解釋!你的粉絲羣正在增加:-) – FernOfTheAndes 2014-03-01 13:35:49

0

可以通過將文本綁定到路徑元素來控制文本的位置和方向。

var svg = d3.select("body").append("svg"), 
    pi = Math.PI; 

var arc = d3.svg.arc() 
    .innerRadius(150) 
    .outerRadius(180) 
    .startAngle(0) 
    .endAngle(-pi/2) 

var path = svg.append("path") 
    .attr("id","path1") 
    .attr("d","M150 150 L150 20 Z") 
    .attr("style","stroke:rgb(255,0,0);stroke-width:2") 

// Add a text label. 
var text = svg.append("text") 
    .attr("x", 6) 
    .attr("dy", 15); 

text.append("textPath") 
    .attr("stroke","black") 
    .attr("xlink:href","#path1") 
    .text("abc"); 
+0

感謝您的回覆,但是會旋轉文字。我早些時候嘗試過,並且嘗試過使用標準的'.attr(「transform」,「translate(1000,250)rotate(90)」',這可以達到相同的效果。我希望文本是垂直的而不是 – Samarth 2013-03-15 18:44:19

0

這應該做你想做的(雖然我不知道該如何表達它在D3):下面有running version on jsFiddle

<文字X = 「100」 Y = 「100」 transform =「rotate(90,100,100)」style =「glyph-orientation-horizo​​ntal:270;」 >部分垂直文字不旋轉< /文字>

顯然將x和y座標改爲您自己的值。

+0

適用於Chrome瀏覽器,但不適用於IE或Firefox。雖然它有利(與使用「寫模式」相比),至少標籤作爲整體位於每個瀏覽器的相同位置,所以它看起來並不可怕「破」 – AmeliaBR 2014-02-28 04:12:10

0

對於Firefox,我可以發現他們已經實現的唯一的FF 30是textLength。我向AmeliaBR的jsfiddle添加了第四個附加文本來演示。它仍然看起來像垃圾想法和D3仍然是贏家。在Chrome,但在Firefox中沒有http://jsfiddle.net/hx5Th/11/

//Black text, uses a double rotate // 
svg.append("text") 
    .attr("x", 40) 
    .attr("y", 40) 
    .attr("id", "title") 
    .attr("font-size", 50) 
    .attr("rotate", -90) 
    .attr("dx", "1em") 
    .attr("dy", "-1em") 
    .attr("textLength", "12.8em") 
    .attr("transform", "translate(450,0) rotate(90)") 
    .text("Top 100 Mentions");