D3文本中的动态粗体字



在我的数据中,我得到了一个可以有1到2个单词("一"或"一两"(的字符串。如果一个单词的字体重量需要是700,如果两个单词,第一个单词需要有400,第二个单词需要700。我的方法是将文本单独附加,这在大多数情况下都有效,但要确保它们总是紧挨着放在完全相同的位置,这很有挑战性。在文本路径上有更好的方法吗?

function drawArcLabels(svg, arcs, groupId) {
const text = svg
.selectAll(".donutText")
.data(arcs)
.enter()
text
.append("text")
.attr("class", d => {
const classes = `${groupId}Text color-${d.data.name}`;
return classes;
})
// Move the labels below the arcs for those slices with an end angle greater than 90 degrees
.attr("dy", (d, i) =>
d.startAngle > 4.4 ? 17 : d.endAngle > (90 * Math.PI) / 180 ? -8 : 17
)
.append("textPath")
.style("text-anchor", "middle")
.attr("startOffset", function(d) {
const secondWord = d.data.name.split(' ')[1]
const firstWord = d.data.name.split(' ')[0]
if (secondWord) {
return `${50 - (firstWord.length) / 0.47}%`
}
return '50%'
})
.attr("fill", "#fff")
.attr("href", (d, i) => `#${groupId + i}`)
.text(d => d.data.name.toUpperCase().split(' ')[0])
.attr("font-size", 11)
.attr("font-weight", function(d) {
return d.data.name.split(' ')[1] ? 400 : 900
})
text
.append("text")
.attr("class", d => {
const classes = `${groupId}Text color-${d.data.name}`;
return classes;
})
// Move the labels below the arcs for those slices with an end angle greater than 90 degrees
.attr("dy", (d, i) =>
d.startAngle > 4.4 ? 17 : d.endAngle > (90 * Math.PI) / 180 ? -8 : 17
)
.append("textPath")
.style("text-anchor", "middle")
.attr("startOffset", function(d) {
const firstWord = d.data.name.split(' ')[0]
const secondWord = d.data.name.split(' ')[1]
if (secondWord) {
return '60%'
//return (50 + (Math.floor((secondWord.length / 2) * 3))) + "%"
}
})
.attr("fill", "#fff")
.attr("href", (d, i) => `#${groupId + i}`)
.text(d => d.data.name.toUpperCase().split(' ')[1])
.attr("font-size", 11)
.attr("font-weight", 900);
}

感谢@RobertLongson建议使用tspan。我的解决方案是简单地在末尾附加tspan,并将其视为文本字符串。

function drawArcLabels(svg, arcs, groupId) {
const text = svg
.selectAll(".donutText")
.data(arcs)
.enter()
text
.append("text")
.attr("class", d => {
const classes = `${groupId}Text color-${d.data.name}`;
return classes;
})
// Move the labels below the arcs for those slices with an end angle greater than 90 degrees
.attr("dy", (d, i) =>
d.startAngle > 4.4 ? 17 : d.endAngle > (90 * Math.PI) / 180 ? -8 : 17
)
.append("textPath")
.style("text-anchor", 'middle')
.attr("startOffset", '50%')
.attr("fill", "#fff")
.attr("href", (d, i) => `#${groupId + i}`)
.text(d => d.data.name.toUpperCase().split(' ')[0])
.attr("font-size", 11)
.attr("font-weight", function(d) {
return d.data.name.split(' ')[1] ? 400 : 900
})
.append('tspan')
.text(d =>{ 
const secondWord = d.data.name.toUpperCase().split(' ')[1]
return secondWord ? ` ${secondWord}` : ''
})

最新更新