我正在多行中为我的svg绘制文字标签。我的解决方案是工作正常,但它有一个限制,它不会绘制比我硬编码更多的行,并且还有一些低效的处理。有没有更好的方法来实现这一点,而不必每次都重新解析名称字符串,并将tspan附加恰当的次数?
node.append("text")
.attr("id", function(d){ return "contact-node-label-"+d.id })
.style("text-anchor", "middle")
.attr("dy", function(d)
{
// split name by space and -
var n = d.name.replace("-","- ").split(" ") // this expression is repeated
return n.length/3-(n.length-1)*0.9+'em'
})
.text(function(d)
{
var n = d.name.replace("-","- ").split(" ")
// return first part of name
return n[0]
})
// some kind of loop would start here
.append("tspan").attr('x',0).attr('dy','1em').text(function(d)
{
var n = d.name.replace("-","- ").split(" ");
if (n.length > 1) return n[1];
})
// second round of loop would be this
.append("tspan").attr('x',0).attr('dy','1em').text(function(d)
{
var n = d.name.replace("-","- ").split(" ");
if (n.length > 2) return n[2];
})
也许我可以使用以下代码。问题是在方法内部创建(并重新创建)n,如果我将其保存在外部,则会引用错误的数据。解决方案是能够将此代码放在其中一个方法中,但我无法使其工作(无论是在text方法中,还是在tspan append方法中):
d3.select(this).append("tspan").attr('x',0).attr('dy','1em').text( n[i] )
答案 0 :(得分:6)
看起来像.each
的作业:
node.append("text")
.each(function(d) {
// split name by space and -
var n = d.name.replace("-","- ").split(" ");
// get the current element
var text = d3.select(this)
.attr("dy", n.length / 3 - (n.length-1) * 0.9 + 'em')
.text(n[0]);
// now loop
for (var i = 1; i < n.length; i++) {
text.append("tspan")
.attr('x', 0)
.attr('dy', '1em')
.text(n[i])
}
});
如此处所示,.each
的一大优势在于它为您提供了每个元素的工作范围,从而可以轻松避免重复计算。