注意(因为我正在回答我的问题):如果您已经花时间解决了这个问题并找到了另一种解决方案,请发布它,我将接受您的答案。感谢@FernOfTheAndes参与找到这个解决方案的过程,因为这个过程充满了使用svg弧线的痛苦和煎熬。
这是解决方案的jsfiddle:
![enter image description here](https://istack.dev59.com/5l3WY.webp)
正如评论中提到的,关键部分是将弧形生成为普通的svg弧形,而不是通过d3.svg.arc()。
SVG定义弧线的规则很清晰,但有点难以管理。这里有一个用于交互式探索svg弧形语法的工具。
此外,在定义正确的弧线过程中,这两个函数对我很有帮助:
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
function describeArc(x, y, radius, startAngle, endAngle){
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, 1, 1, end.x, end.y
].join(" ");
return d;
}
这是实际直接生成曲线标签的代码:
var arcPaths = vis.append("g")
.style("fill","navy");
var labels = arcPaths.append("text")
.style("opacity", function(d) {
if (d.depth == 0) {
return 0.0;
}
if (!d.children) {
return 0.0;
}
var sumOfChildrenSizes = 0;
d.children.forEach(function(child){sumOfChildrenSizes += child.size;});
if (sumOfChildrenSizes <= 5) {
return 0.0;
}
return 0.8;
})
.attr("font-size",10)
.style("text-anchor","middle")
.append("textPath")
.attr("xlink:href",function(d,i){return "#s"+i;})
.attr("startOffset",function(d,i){return "50%";})
.text(function(d){return d.name.toUpperCase();})
幸运的是,在弧线上居中文本只需要设置正确的属性。
startOffset = "<length>"
,文档中提到:如果给出的是一个除百分比以外的 <length>(这就是你所给出的),那么startOffset
表示在当前用户坐标系中沿路径测量的距离。按照文档,我们可以找到 路径上的距离。目前看来,这似乎是 textPath 元素和指定 x、y 坐标之间唯一的联系。希望这不是一条兔子洞。 - FernOfTheAndes