我正在尝试使用d3在svg中垂直显示文本。但是我不想旋转它:我希望字母保持水平,但一个在另一个之上。设置writing-mode=tb
似乎没有做任何事情。这是我试过的:
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");
文本显示在正确的位置,使用正确的字体等,但它是水平的。
答案 0 :(得分:11)
在谈论旋转SVG文本时,有多个不同方面:
浏览器如何根据前一个角色的位置确定下一个角色的位置;
字符相对于基线(rotate
属性)的旋转方式;
如何将整个最终文本块相对于坐标系(transform
属性)旋转。
Full, rather difficult to comprehend, specs here
'write-mode'属性应该改变第一个方面而不影响其他方面,但是当你发现it's not implemented at all in Firefox时,IE会旋转文本但不尊重水平字形规则。
理论上,你应该能够通过组合旋转和变换属性来获得相同的效果:变换整个<text>
元素以将其旋转到垂直位置,然后反向旋转个别角色让他们回到水平。但在实践中,它变得混乱......
对于初学者来说,双重旋转会导致文本在(x,y)点的左边结束,所以如果(x,y)是(0,0),它将被剪切到SVG之外而没有补充转移。由于转换,您需要否定dy
值才能将文本移回锚点的右侧。
其次,有一个事实是旋转应用于每个角色,不调整角色的间距以解释“l”比宽度高得多的事实。因此,除非你使用等宽,否则事情看起来很混乱。您应该能够使用kerning
和letterspacing
属性更改字母间距,但浏览器对这些属性的支持也很差:IE11似乎不承认字距调整值,而Firefox也没有不承认。
最后一个选项是自己控制布局:使用d3的强大功能和字符串.split("")
方法将标题分解为单个字符<tspan>
元素可以一个位于彼此之下,并在<text>
元素内整齐地居中。缺点是,这会添加额外的DOM元素,您仍然可以选择整个文本块,就像在HTML段落中选择一个短语一样,即使每个字母都被设置为单独的<span>
。我不确定屏幕阅读器是否会自动假设字母之间有空格,但是......
这个小提琴尝试了三种在垂直文本标签中获取水平字符的方法(写作模式 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系统上):
Chrome 33
IE 11
<强>火狐强>
我认为这是胜利的d3 ......
答案 1 :(得分:1)
svg中嵌入的html:
<svg
x="0px" y="0px"
width="200px" height="200px"
viewbox="0 0 200 200"
>
<foreignObject
x="20" y="20"
width="160" height="160"
>
<!-- we must set xmlns attribute
for foreignObject.childNode -->
<div
xmlns="http://www.w3.org/1999/xhtml"
style="
/* HTML-CSS vertical text */
writing-mode: vertical-lr;
text-orientation: upright;
line-height: 2em;
font-family: sans-serif;
font-size: 150%;
"
>Hello<br/> World</div>
</foreignObject>
</svg>
答案 2 :(得分:0)
您可以通过将文本绑定到路径元素来控制文本的位置和方向。以下示例使用running version on jsFiddle:
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");
答案 3 :(得分:0)
这应该做你想要的(尽管我不知道如何在d3中表达它):
&lt; text x =“100”y =“100”transform =“rotate(90,100,100)”style =“glyph-orientation-horizontal:270;”&gt;一些未旋转的垂直文本&lt; / text&gt ;
显然将x和y坐标更改为您自己的值。
答案 4 :(得分:0)
对于Firefox,我发现他们在FF 30中实现的唯一内容是textLength。我向AmeliaBR的jsfiddle添加了第四个文本附加内容以进行演示。它仍然看起来像垃圾思想,D3仍然是赢家。 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");