2015-06-21 68 views
0

这是相当简单的,以创建在D3一些文本,并让它换行:D3自动换行与数据驱动宽度限制

var textElement = svg.selectAll('text') 
        .data(myData) 
        .enter() 
        .append('text') 
        .text(someVeryLongText) 
        .call(wrapText, allowedWidth); 

的wrapText()函数是使用的相当标准的实施例在那里一个实现(例如http://bl.ocks.org/mbostock/7555321)。

我的问题是,当我想为每个文本字段依赖于数据的允许宽度,这样的:

    ... 
        .text(someVeryLongText) 
        .call(wrapText, function(d) { 
        return d.someCondition ? 100 : 200; 
        }); 

是这样的可能吗?

回答

0

调整您链接的示例中的包装功能,如下所示,并在您的帖子中使用所需的呼叫签名。工作示例here

function wrap(text, width) { 
    text.each(function(d, i/*[edit]*/) { 
     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"), 
      //[edit]add dWidth 
      dWidth = typeof width === "function" ? width(d, i) : width; 
     while (word = words.pop()) { 
      line.push(word); 
      tspan.text(line.join(" ")); 
      if (tspan.node().getComputedTextLength() > dWidth/*[edit]*/) { 
       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); 
      } 
     } 
    }); 
} 
+0

棒极了!谢谢:-) – ThisRestlessPilgrim

+0

只要记住,在目前的形式下,如果已经存在tspan元素,它将会中断。但如果你稍微调整一下,很容易修复。 –