参考Mike Bostock的this示例,我想将相同的想法应用于切换X和Y的条形图。所以标签在Y轴上上下移动。
在这个小提琴中:http://jsfiddle.net/2eLW6/我只是从Mike的例子中复制wrap函数并将其应用到我的图表中。
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
在Mike的示例中将其应用于x轴时,如果超过某个行长度,则仅将字放在新行上。在我的小提琴中,它将每个单词放在一个新行上。另外,我想知道是否有一种方法可以在创建新行时将y属性稍微移动一点,以便它仍然居中?
有人可以帮我翻译y轴的wrap()函数吗?
wrap()函数在第203行定义,并从那个小提琴中的第135行调用。
答案 0 :(得分:0)
我无法让你的小伙子工作,事情似乎被推向左边,但无论如何我认为我确定了你的问题。
关于你的第一个问题,为什么每个单词都被推到了自己的行。我相信这是因为您发送包装的宽度以确定何时休息是非常小的。在你的jsfiddle中,你对wrap的调用是:
int
.call(wrap, yScale.rangeBand());
是一个非常小的值,在我的分辨率中它是36像素。这意味着一旦你的标签超过36像素,它就会产生一个换行符(添加一个tspan)。您不希望使用rangeBand,而是希望此数字是图表的左边距(y轴左侧有多少空间)。
最后,在进行垂直居中方面,您需要确定标签分解的行数,以便了解每个行的移动量。为此,在包装结束时,您可以添加以下两行:
yScale.rangeBand()
第一段代码获取标签分割成的行数。第二个,选择标签的所有tspans并相应地移动它们以使它们居中。我使用的var breaks = text.selectAll("tspan")[0].length;
text.selectAll("tspan").attr("y", -9 * (breaks-1));
仅适用于默认字体大小。有一种更好的方法来计算这个数字来处理多种字体大小。
答案 1 :(得分:-1)
我一直在寻找这个问题的解决方案,并发现Mike Bostock已经发布了working example。示例显示适用于x轴,但可以很容易地适应y轴。 wrap()
函数不需要修改,而是必须将其应用于y轴,指示可能适用的正确宽度变量。
在原始示例中,垂直图表wrap()
的调用方式如下:
svg.append( “G”) .attr(“class”,“x axis”) .attr(“transform”,“translate(0,”+ height +“)”) .CALL(x-轴) .selectAll(“。tick text”) .call(wrap,x.rangeBand());
水平图表的具体细节可能会有所不同,但保存宽度值的典型变量是margin.left,如下面的代码段所示:
svg.append( “G”) .attr(“class”,“y轴”) .CALL(Y轴) .selectAll(“。tick text”) .call(wrap,margin.left);
OP中要求的其余功能需要修改wrap()
。