如何使用d3.js在弧内的textPath上右/末对齐文本?

Dev*_*wen 5 svg d3.js

这是小提琴: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");
Run Code Online (Sandbox Code Playgroud)

我尝试过很多不同的东西都无济于事.左对齐是简单的部分.但是,如果你做了一个中间,你只看到"文本"而不​​是"某些文本",暗示"某些"只是被隐藏,因为它对于给定的弧线"超出范围".

但是,如果我补充说:

        .attr("startOffset","39%")
Run Code Online (Sandbox Code Playgroud)

(如下所示:http://jsfiddle.net/DevChefOwen/2H99c/)

它看起来是正确的对齐,但在编程之外尝试获取文本元素的宽度/高度并寻找宽度/高度的急剧变化(这似乎是错误的并且可能容易出错),我似乎无法找到方法右对齐文本.

我也尝试过使用SVG路径(本质上是曲线弧线),当"text-anchor"设置为"left"时,文本也会发生相同的消失行为.

谢谢你的时间!

Ame*_*aBR 9

问题有些令人困惑.问题是没有在路径的末尾对齐文本 - 这很容易做到"text-anchor"="end""startOffset"="100%".

但是,将这些设置与d3 arc函数创建的路径一起使用时,最终会在内部曲线末端和左侧直边附近进行文本转弯,直到由arc函数定义的路径末尾: http: //jsfiddle.net/CZ6Dp/8/

真正的问题是您希望文本对齐的路径(形状的外部圆弧)只是定义形状的路径的一个部分.

(顺便说一句,"left"和"right"不是"text-anchor"属性的有效值,只会被忽略).

@ defghi1977的答案通过计算您想要使用的路径段的长度并相应地调整起始偏移量,提供了一种解决问题的方法.

解决此问题的另一种方法是创建一个单独的路径(未在屏幕上绘制),该路径仅表示您要用于定位文本的路径部分.

有许多可能的方法来创建仅表示外部弧的路径(此处为一些示例代码).@ 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");
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/CZ6Dp/9/

同样,考虑额外的DOM负载@ defghi1977的方法可能稍微偏爱一点,尽管这个版本的好处是不依赖于浏览器支持getTotalLength.但据我所知,该方法实施得相当好.

因此,为了完整性,请考虑这种替代方法.