d3.js包裹Y轴的长标签

时间:2014-01-14 17:08:23

标签: javascript d3.js

参考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行调用。

2 个答案:

答案 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()