Подтвердить что ты не робот

Подгонка текста в элемент 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? Спасибо,

4b9b3361

Ответ 1

Ответ на этот вопрос может иметь значение. SVG не предоставляет возможности автоматического переноса текста, но вы можете вставлять HTML в SVG, а затем использовать div, например.

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

Ответ 2

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

Ответ 4

У меня была аналогичная проблема, и я нашел разумное решение, вычислив ширину моего окна. Во-вторых, я понял, что в среднем ширина символа для моего текущего шрифта составляет около 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");

Ответ 5

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