如何在JavaScript内换行svg文本?

所以这里是我所拥有的:

<path class="..." onmousemove="show_tooltip(event,'very long text \\\n I would like to linebreak')" onmouseout="hide_tooltip()" d="..."/> <rect class="tooltip_bg" id="tooltip_bg" ... /> <text class="tooltip" id="tooltip" ...>Tooltip</text> <script> <![CDATA[ function show_tooltip(e,text) { var tt = document.getElementById('tooltip'); var bg = document.getElementById('tooltip_bg'); // set position ... tt.textContent=text; bg.setAttribute('width',tt.getBBox().width+10); bg.setAttribute('height',tt.getBBox().height+6); // set visibility ... } ... 

现在我很长的工具提示文本没有linebreak,即使如果我使用alert(); 它显示了文本实际上有两行。 (它包含一个“\”,但是我怎样才能删除那个呢?)
我无法让CDATA在任何地方工作。

这不是SVG 1.1支持的。 SVG 1.2确实有textArea元素,自动换行,但没有在所有浏览器中实现。 SVG 2 没有计划实现textArea ,但它确实有自动包装的文本 。

然而,考虑到你已经知道你的换行符应该发生在哪里,你可以将你的文本分成多个<tspan> ,每个都有x="0"dy="1.4em"来模拟实际的文本行。 例如:

 <g transform="translate(123 456)"><!-- replace with your target upper left corner coordinates --> <text x="0" y="0"> <tspan x="0" dy="1.2em">very long text</tspan> <tspan x="0" dy="1.2em">I would like to linebreak</tspan> </text> </g> 

当然,既然你想从JavaScript做到这一点,你将不得不手动创build并将每个元素插入到DOM中。

我认为你已经设法解决它,但是如果有人正在寻找类似的解决scheme,那么这对我有效:

  g.append('svg:text') .attr('x', 0) .attr('y', 30) .attr('class', 'id') .append('svg:tspan') .attr('x', 0) .attr('dy', 5) .text(function(d) { return d.name; }) .append('svg:tspan') .attr('x', 0) .attr('dy', 20) .text(function(d) { return d.sname; }) .append('svg:tspan') .attr('x', 0) .attr('dy', 20) .text(function(d) { return d.idcode; }) 

有三行用换行符分隔。

我认为这是你想要的:

 function ShowTooltip(evt, mouseovertext){ // Make tooltip text var tooltip_text = tt.childNodes.item(1); var words = mouseovertext.split("\\\n"); var max_length = 0; for (var i=0; i<3; i++){ tooltip_text.childNodes.item(i).firstChild.data = i<words.length ? words[i] : " "; length = tooltip_text.childNodes.item(i).getComputedTextLength(); if (length > max_length) {max_length = length;} } var x = evt.clientX + 14 + max_length/2; var y = evt.clientY + 29; tt.setAttributeNS(null,"transform", "translate(" + x + " " + y + ")") // Make tooltip background bg.setAttributeNS(null,"width", max_length+15); bg.setAttributeNS(null,"height", words.length*15+6); bg.setAttributeNS(null,"x",evt.clientX+8); bg.setAttributeNS(null,"y",evt.clientY+14); // Show everything tt.setAttributeNS(null,"visibility","visible"); bg.setAttributeNS(null,"visibility","visible"); } 

它将文本分割为\\\n ,并将每个片段放在一个tspan中。 然后根据文本的最长长度和行数来计算所需的框的大小。 您还需要更改工具提示文本元素以包含三个tspans:

 <g id="tooltip" visibility="hidden"> <text><tspan>x</tspan><tspan x="0" dy="15">x</tspan><tspan x="0" dy="15">x</tspan></text> </g> 

这假定你从来没有超过三行。 如果你想要多于三行,你可以添加更多的tspans并增加for循环的长度。

用tspan解决scheme,假设你不知道在哪里放置换行符:你可以使用这个很好的函数,我在这里find了: http : //bl.ocks.org/mbostock/7555321

对于给定的像素宽度,这会自动为长文本svg换行。

 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); } } }); } 

使用replace,它会删除换行符,如果你问它:)这将取代一个换行符:

 text.replace("\n",""); 

这将取代多个:

 //This javascript code removes all 3 types of line breaks text = text.replace(/(\r\n|\n|\r)/gm,""); 

https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/replace