在玩了一段时间 d3.js 并查看了很多示例之后,我能够绘制多条弧线。每一个都以特定的度数和给定的半径开始和结束。
var dataset = {
"2":[{"degree1":0, "degree2":1.5707963267949,
"label":"Sample Text Test"},
{"degree1":1.5707963267949, "degree2":3.1415926535898,
"label":"Lorem ipsum sample text"},
{"degree1":3.1415926535898, "degree2":4.7123889803847,
"label":"Sample Text Text"},
{"degree1":4.7123889803847, "degree2":6.2831853071796,
"label":"Lorem ipsum"}],
"1":[{"degree1":0, "degree2":3.1415926535898,
"label":"Sample"},
{"degree1":3.1415926535898, "degree2":6.2831853071796,
"label":"Text"}],
"0":[{"degree1":0, "degree2":6.2831853071796,
"label":""}]
},
width = 450,
height = 450,
radius = 75;
// Helper methods
var innerRadius = function(d, i, j) {
return 1 + radius * j;
};
var outerRadius = function(d, i, j) {
return radius * (j + 1);
};
var startAngle = function(d, i, j) {
return d.data.degree1;
};
var endAngle = function(d, i, j) {
return d.data.degree2;
};
var pie = d3.layout.pie()
.sort(null);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(startAngle)
.endAngle(endAngle);
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + (width >> 1) + ',' + (height >> 1) + ')');
var level = svg.selectAll('g')
.data(function(d) {
return d3.values(dataset);
})
.enter()
.append('g');
var entry = level.selectAll('g')
.data(function(d, i) {
return pie(d);
})
.enter()
.append('g');
entry.append('path')
.attr('fill', '#aaa')
.attr('d', arc)
.attr('id', function(d, i, j) {
return 'arc' + i + '-' + j;
});
var label = entry.append('text')
.style('font-size', '20px')
.attr('dx', function(d, i, j) {
return Math.round((d.data.degree2 - d.data.degree1) * 180 / Math.PI);
})
.attr('dy', function(d, i, j) {
return ((radius * (j + 1)) - (1 + radius * j)) >> 1;
});
label.append('textPath')
.attr('xlink:href', function(d, i, j) {
return '#arc' + i + '-' + j;
})
.style('fill', '#000')
.text(function(d) {
return d.data.label;
});
参见 http://jsfiddle.net/3FP6P/2/ :
但还是存在一些问题:
- 如何在由 innerRadius、outerRadius、startAngle 和 endAngle 描述的弧内沿任意长度的文本路径居中(水平和垂直)文本?
- 文本有时会出现粗体,有时不会。为什么?
- 字符间距与写在 .有些字母比其他字母更容易粘在一起。为什么?
- 字母不直接位于路径上。有些似乎有点上下滑动。为什么?
最佳答案
垂直对齐
您可以使用另一个半径为 (innerRadius + outerRadius)/2
的圆弧,并将其用作标签的 textPath
。
请注意,即使您设置了 innerRadius == outerRadius
,D3 也会绘制一条路径,该路径先顺时针移动,然后逆时针移动,使其自身翻倍。这在尝试找出路径的水平中心时变得很重要:它位于 25%
和 75%
点,而 0%
和 50%
点位于圆弧的两个尖端。
水平对齐
在文本元素上使用 text-anchor: middle
并将 startOffset
设置为 25%
(或 75%
) 在 textPath
上。
Demo .
这是一种比手动计算 dx
和 dy
更可靠的方法。
您应该尝试 Lars 的建议以进一步提高文本的质量和居中,例如您可能希望将 text-rendering
设置为 optimizeLegibility
并稍微调整一下基线。
关于javascript - 如何使用 d3.js 沿着弧内的 textPath 居中(水平和垂直)文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20447106/