这是小提琴:http://jsfiddle.net/DevChefOwen/CZ6Dp/
var text = g.append("text")
.style("font-size",30)
.style("fill","#000")
.attr("dy",0)
.append("textPath")
.attr("xlink:href","#yyy")
.style("text-anchor","left") // using "end", the entire text disappears
.text("some text");
我尝试了许多不同的事情但无济于事。左对齐是简单的部分。但是,如果你做了一个中间,你只看到“文本”而不是“某些文本”,暗示“某些”只是被隐藏,因为它对于给定的弧“超出了范围”。
但是,如果我添加:
.attr("startOffset","39%")
(如此处:http://jsfiddle.net/DevChefOwen/2H99c/)
它看起来是正确的对齐,但在编程之外尝试获取文本元素的宽度/高度并寻找宽度/高度的急剧变化(这似乎是错误的并且可能容易出错),我似乎无法找到一种正确对齐文本的方法。
我也尝试过使用SVG路径(本质上是一条曲线弧线),当“text-anchor”设置为“left”时,文本也会发生相同的消失行为。
感谢你的时间!
答案 0 :(得分:9)
这个问题有些令人困惑。问题是没有在路径末尾对齐文本 - 这对于"text-anchor"="end"
和"startOffset"="100%"
很容易。
但是,将这些设置与d3弧函数创建的路径一起使用时,最终会在内部曲线末端和左侧直边附近进行文本转弯,直到由弧函数定义的路径末尾: http://jsfiddle.net/CZ6Dp/8/
真正的问题是您希望文本对齐的路径(形状的外部圆弧)只是定义形状的路径的一个部分。
(顺便说一下,“left”和“right”不是“text-anchor”属性的有效值,只会被忽略)。
@ defghi1977的答案提供了一种解决问题的方法,通过计算你想要使用的路径段的长度并相应地调整起始偏移量。
解决此问题的另一种方法是创建一个单独的路径(未在屏幕上绘制),该路径仅表示您希望用于定位文本的路径部分。
有许多方法可以创建仅表示外部弧(some example code here)的路径。 @ defghi1977用正则表达式从现有路径中获取它的方法可能对你的情况最有效。但是,实际上我不得不创建一个临时元素来计算长度,而是必须将新路径添加到DOM,以便它可以用作<textPath>
元素的引用路径。 (我认为这种方法的缺点是DOM元素的两倍!)
var path = g.append("svg:path")
.attr("d", arct)
.style("fill","#ccc")
.attr("transform", "translate("+cfg.w/2+","+cfg.h/2+")")
.each(function(d,i) {
var justArc = /(^.+?)L/;
//grab everything up to the first Line statement
var thisSelected = d3.select(this);
var arcD = justArc.exec( thisSelected.attr("d") )[1];
defs.append("path")
.attr("id", "yyy") //normally the id would be based on the data or index
.attr("d", arcD)
.attr("transform", thisSelected.attr("transform") );
//if you can avoid using transforms directly on the path element,
//you'll save yourself having to repeat them for the text paths...
});
var text = g.append("text")
.style("font-size",30)
.style("fill","#000")
.attr("dy",0)
.append("textPath")
.attr("xlink:href","#yyy")
.style("text-anchor","end")
.attr("startOffset","100%")
.text("some text");
同样,考虑额外的DOM加载@ defghi1977的方法可能稍微偏爱一点,尽管这个版本的好处是不依赖浏览器对getTotalLength
的支持。但据我所知,该方法实施得相当好。
因此,为了完整起见,请考虑这种替代方法。
答案 1 :(得分:3)
此路径由4(或5)个路径段构成 因此,这个问题将被解决以获得第一个弧长路径 但我不知道如何通过使用d3.js获得子路径长度,因此我直接使用svgdom 我试图修复你的代码。如果这个代码不是您所希望的,我很抱歉。
var path = g.append("svg:path")
.attr("id","yyy")
.attr("d", arct)
.style("fill","#ccc")
.attr("transform", "translate("+cfg.w/2+","+cfg.h/2+")");
var text = g.append("text")
.style("font-size",30)
.style("fill","#000")
.attr("dy",0)
.append("textPath")
.attr("xlink:href","#yyy")
//.style("text-anchor","left") // using "end", the entire text disappears
.attr("text-anchor", "end")
.text("some text")
.attr("startOffset",function(){
var d = document.getElementById("yyy").getAttribute("d");
var tmp = document.createElementNS("http://www.w3.org/2000/svg" ,"path");
//get the arc segment of path
var arc = d.match(/(^.+?)L/)[1];
tmp.setAttribute("d", arc);
//return offset position
return tmp.getTotalLength();
});
答案 2 :(得分:1)
我认为混淆来自于text-anchor
的含义 - 它不是“相对于父母的位置我会证明”,而是“我应该将哪一部分与开始对齐”。
您尝试使用startOffset
移动原点是正确的。由于路径的外半径长于内半径,因此正确的起始偏移量略大于路径的一半(约53%)。
再多一点你的设置,你应该拥有它。 Here's a fiddle我对你要找的东西的解释。