2012-06-13 3 views
13

Я хочу написать текст внутри прямоугольника создаю следующим образом:Fit Text в SVG элемент (с использованием 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')​ 

Однако, как вы можете видеть (http://jsfiddle.net/Tmj7g/3/) текст становится отрезан. Какие-нибудь отличные способы написать абзац внутри прямоугольника svg? Спасибо,

ответ

16

Ответ на вопрос this question может быть уместным. SVG не позволяет автоматически обертывать текст, но вы можете вставлять HTML в SVG, а затем использовать, например, div.

Я обновил jsfiddle here, но он не работает так хорошо вместе с анимацией. Если вы хотите, чтобы он работал правильно и вел себя как любой другой элемент SVG, вам придется предварительно вычислить разрывы строк и вставить их вручную.

+0

делает эту работу на IE9? Если да, то каковы альтернативы? Я знаю, что об этом давно ответили. – Jose

+0

Я не пробовал это в IE9. –

+0

Да, он вообще не работает в IE9, потому что он не поддерживает внешние объекты. Существуют ли альтернативы обертыванию текста в D3.js? – Jose

15

Чтобы заставить его работать с анимациями, просто вставляйте в элемент группы и анимируйте его. 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

Эта техника может пригодиться. Он работает с текущей спецификации SVG и без foreignObject элемента http://bl.ocks.org/mbostock/7555321

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменяется – Ian

2

У меня был подобный вопрос и нашел разумное решение путем вычисления ширины моего окна. Во-вторых, я понял, что в среднем ширина символа для моего текущего шрифта составляет около 8. Далее я просто подстроку отображаемого текста. В большинстве случаев это отлично работает.

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

Другой подход, при попытке поместить прямую линию текста в элемент SVG, может использовать стратегию найденную в 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"); 
Смежные вопросы