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