Come allineare un testo svg in javascript?

Quindi ecco quello che ho:

  Tooltip  <![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 ... } ... 

Ora il mio lunghissimo testo del tooltip non ha un’interruzione di riga, anche se uso alert (); mi mostra che il testo in realtà ha due righe. (Contiene comunque una “\”, come posso rimuoverlo?)
Non riesco a far funzionare CDATA ovunque.

Questo non è qualcosa che supporta SVG 1.1. SVG 1.2 ha l’elemento textArea , con il word wrapping automatico, ma non è implementato in tutti i browser. SVG 2 non pianifica l’implementazione di textArea , ma ha un testo con wrapping automatico .

Tuttavia, dato che sai già dove si verificano gli interruzioni di , puoi spezzare il tuo testo in più s, ognuno con x="0" e dy="1.4em" per simulare linee di testo reali. Per esempio:

   very long text I would like to linebreak   

Naturalmente, dal momento che vuoi farlo da JavaScript, dovrai creare e inserire manualmente ogni elemento nel DOM.

Suppongo che tu sia riuscito a risolverlo, ma se qualcuno sta cercando una soluzione simile, allora ha funzionato per me:

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

Ci sono 3 linee separate con interruzione di riga.

Con la soluzione tspan, diciamo che non sai in anticipo dove mettere le interruzioni di linea: puoi usare questa bella funzione, che ho trovato qui: http://bl.ocks.org/mbostock/7555321

Questo fa automaticamente le interruzioni di riga per il testo lungo svg per una data larghezza in pixel.

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

Penso che questo faccia ciò che vuoi:

 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 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 il testo su \\\n e per ognuno inserisce ciascun frammento in un tspan. Quindi calcola la dimensione della casella richiesta in base alla lunghezza massima del testo e al numero di righe. Dovrai anche modificare l’elemento di testo del tooltip per contenere tre tsp:

  xxx  

Questo presuppone che tu non abbia mai più di tre linee. Se vuoi più di tre linee puoi aggiungere più tsp e aumentare la lunghezza del ciclo for.

Ho adattato un po ‘la soluzione con @steco, rimuovendo la dipendenza da d3 e aggiungendo l’ height dell’elemento di testo come parametro

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