在与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/:
但是仍然存在一些问题:
答案 0 :(得分:9)
垂直对齐
您可以使用另一个半径为(innerRadius + outerRadius) / 2
的圆弧,并将其用作标签的textPath
。
请注意,即使您设置了innerRadius == outerRadius
,D3也会绘制一条顺时针方向移动的路径,然后逆时针方向移动一倍。这在尝试找出路径的水平中心时变得很重要:它位于25%
和75%
点,0%
和50%
点位于弧的两个尖端。
水平对齐
在文本元素上使用text-anchor: middle
,并在startOffset
上将25%
设置为75%
(或textPath
)。
这比手动计算dx
和dy
更为健全。
您应该尝试Lars的建议,以进一步提高文本的质量和中心性,例如:您可能希望将text-rendering
设置为optimizeLegibility
并稍微使用基线。
答案 1 :(得分:4)
问题2-4是因为字体渲染。在我的浏览器中,间距和字符大小等是一致的。您可以尝试使用text-rendering
attribute进行改进。
要使文字居中,您需要设置alignment-baseline
和/或dominant-baseline
属性。
如果这仍然无法提供您正在寻找的结果,请尝试减小字体大小。这可能有所帮助,因为角色的轻微旋转将不那么明显。