online font family examples example code javascript svg newline line-breaks

font - svg y javascript



Cómo linebreak un svg texto dentro de javascript? (5)

Con la solución tspan, digamos que no sabes de antemano dónde ubicar tus saltos de línea: puedes usar esta bonita función que encontré aquí: http://bl.ocks.org/mbostock/7555321

Eso automáticamente hace saltos de línea para svg largo de texto para un ancho determinado en píxeles.

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

Entonces aquí está lo que tengo:

<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 ... } ...

Ahora mi texto de información muy larga no tiene un salto de línea, aunque si uso alert (); me muestra que el texto realmente TIENE dos líneas. (Sin embargo, contiene una "/", ¿cómo elimino esa?)
No puedo hacer que CDATA funcione en ninguna parte.


Creo que esto hace lo que quieres:

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

Divide el texto en ///n y para cada uno coloca cada fragmento en un tspan. Luego calcula el tamaño de la caja requerida en función de la longitud de texto más larga y el número de líneas. También necesitará cambiar el elemento de texto de información sobre herramientas para que contenga tres 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>

Esto supone que nunca tienes más de tres líneas. Si desea más de tres líneas, puede agregar más tspans y aumentar la longitud del bucle for.


Esto no es algo que SVG 1.1 admite. SVG 1.2 tiene el elemento textArea , con textArea palabra automático, pero no está implementado en todos los navegadores. SVG 2 no planea implementar textArea , pero sí tiene texto envuelto automáticamente .

Sin embargo, dado que ya sabe dónde deberían ocurrir los saltos de línea, puede dividir su texto en múltiples <tspan> s, cada uno con x="0" y dy="1.4em" para simular líneas reales de texto. Por ejemplo:

<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>

Por supuesto, como quiera hacer eso desde JavaScript, deberá crear e insertar manualmente cada elemento en el DOM.


He adaptado un poco la solución mediante @steco, eliminando la dependencia de d3 y agregando la height del elemento de texto como parámetro

function wrap(text, width, height) { text.each(function(idx,elem) { var text = $(elem); text.attr("dy",height); var 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 (elem.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); } } }); }


Supongo que ya se las arregló para resolverlo, pero si alguien está buscando una solución similar, esto funcionó para mí:

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

Hay 3 líneas separadas con linebreak.