【问题标题】:d3.js wrapping long labels for Y axisd3.js 为 Y 轴包装长标签
【发布时间】:2014-02-02 20:46:41
【问题描述】:

参考 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 属性向上移动一点,如果已创建新行使其仍居中?

谁能帮我把 wrap() 函数翻译成 y 轴?

wrap() 函数在第 203 行定义,并从该小提琴的第 135 行调用。

【问题讨论】:

标签: javascript d3.js


【解决方案1】:

我真的不能让你的 jsfiddle 工作,事情似乎被推到了左边,但无论如何我想我发现了你的问题。

关于您的第一个问题,为什么每个单词都被推到自己的行中。我相信这是因为您发送来换行以确定何时休息的宽度非常小。在您的 jsfiddle 中,您对 wrap 的调用是:

.call(wrap, yScale.rangeBand());

yScale.rangeBand() 是一个很小的值,在我的分辨率中它是 36 像素。这意味着一旦你的标签超过 36 像素,它就会换行(添加一个 tspan)。您不希望使用 rangeBand,而是希望这个数字成为图表的左边距(y 轴左侧有多少空间)。

最后,就垂直居中而言,您需要确定您的标签被分解为多少行,以便知道每行向上移动多少。为此,您可以在 wrap 的末尾添加以下两行:

var breaks = text.selectAll("tspan")[0].length; text.selectAll("tspan").attr("y", -9 * (breaks-1));

第一段代码获取标签被分成的行数。第二,选择标签的所有 tspan 并将它们相应地向上移动以使它们居中。我使用的-9 仅适用于默认字体大小。可能有一种更好的方法来计算该数字以处理多种字体大小。


【讨论】:

    【解决方案2】:

    我一直在寻找解决此问题的方法,发现 Mike Bostock 发布了 working example。该示例显示为适用于 x 轴,但可以很容易地适用于 y 轴。 wrap() 函数不需要修改,而是您必须将其应用于 y 轴,指示可能适用的正确宽度变量。

    在原始示例中,垂直图表wrap() 调用如下:

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
    .selectAll(".tick text")
      .call(wrap, x.rangeBand());
    

    水平图表的具体细节可能会有所不同,但保存宽度值的典型变量是margin.left,如下面的sn-p:

    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .selectAll(".tick text")
      .call(wrap, margin.left);
    

    OP 中要求的其余功能需要修改 wrap()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多