2012-06-13 75 views
13

Quiero escribir texto dentro de un rectángulo se crea de la siguiente manera:Ajustar texto en SVG Element (El uso de D3/JS)

body = d3.select('body') 

svg = body.append('svg').attr('height', 600).attr('width', 200) 

     rect = svg.append('rect').transition().duration(500).attr('width', 150) 
         .attr('height', 100) 
         .attr('x', 40) 
         .attr('y', 100) 
         .style('fill', 'white') 
         .attr('stroke', 'black') 

     text = svg.append('text').text('This is some information about whatever') 
         .attr('x', 50) 
         .attr('y', 150) 
         .attr('fill', 'black')​ 

Sin embargo, como se puede ver (http://jsfiddle.net/Tmj7g/3/) el texto se corta. ¿Alguna forma ingeniosa de escribir un párrafo dentro del rectángulo svg creado? Gracias,

Respuesta

16

La respuesta a this question podría ser relevante. SVG no proporciona ninguna forma de ajustar el texto automáticamente, pero puede incrustar HTML dentro de SVG y luego usar un div por ejemplo.

He actualizado el jsfiddle here, pero no funciona tan bien junto con la animación. Si desea que funcione correctamente y se comporte como cualquier otro elemento SVG, deberá precalcular los saltos de línea e insertarlos manualmente.

+0

hace este trabajo en IE9? ¿Si es así, cuáles son las alternativas? Sé que esto fue respondido hace mucho tiempo. – Jose

+0

No he intentado esto en IE9. –

+0

Sí, no funciona en absoluto en IE9 porque no admite objetos extraños. ¿Hay alguna alternativa para envolver texto en D3.js? – Jose

15

Para que funcione con las animaciones solo encierre en un elemento de grupo y anime ese en su lugar. http://jsfiddle.net/MJJEc/

body = d3.select('body') 
svg = body.append('svg') 
        .attr('height', 600) 
        .attr('width', 200); 
    var g = svg.append('g').attr("transform" ,"scale(0)"); 
    rect = g.append('rect') 
        .attr('width', 150) 
        .attr('height', 100) 
        .attr('x', 40) 
        .attr('y', 100) 
        .style('fill', 'none') 
        .attr('stroke', 'black') 
    text = g.append('foreignObject') 
        .attr('x', 50) 
        .attr('y', 130) 
        .attr('width', 150) 
        .attr('height', 100) 
        .append("xhtml:body") 
        .html('<div style="width: 150px;">This is some information about whatever</div>') 

    g.transition().duration(500).attr("transform" ,"scale(1)"); 
3

Esta técnica puede ser útil. Funciona con la especificación SVG actual y sin elemento foreignObject http://bl.ocks.org/mbostock/7555321

+0

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas solo de enlace pueden dejar de ser válidas si la página vinculada cambia – Ian

2

tuve un problema similar y encontré una solución razonable mediante el cálculo de la anchura de mi caja. En segundo lugar, descubrí que, en promedio, el ancho del carácter para mi fuente actual es de aproximadamente 8. A continuación, simplemente hago una subcadena en el texto que se mostrará. Eso parece funcionar perfectamente en la mayoría de los casos.

var rectText = rectangles.append("text") 
    .text(function(d) { 

     TextBoxLength = timeScale(dateFormat.parse(d.endTime)) - timeScale(dateFormat.parse(d.startTime)); 
     return d.task.substring(0, Math.floor(TextBoxLength/8)); 
    }) 
    .attr("x", function(d) { 
     return (timeScale(dateFormat.parse(d.endTime)) - timeScale(dateFormat.parse(d.startTime)))/2 + timeScale(dateFormat.parse(d.startTime)) + theSidePad; 
    }) 
    .attr("y", function(d, i) { 
     return d.position * theGap + 14 + theTopPad; 
    }) 
    .attr("font-size", 12) 
    .attr("text-anchor", "middle") 
    .attr("text-height", theBarHeight) 
    .attr("fill", "#000000"); 
2

Otro enfoque, cuando se trata de ajustar una línea recta de texto en un elemento SVG, podría utilizar la estrategia que se encuentra en http://bl.ocks.org/mbostock/1846692:

node.append("text") 
    .text(function(d) { return d.name; }) 
    .style("font-size", function(d) { return Math.min(2 * d.r, (2 * d.r - 8)/this.getComputedTextLength() * 24) + "px"; }) 
    .attr("dy", ".35em");