我正在使用d3绘制UML图,并希望将文本包装在用d3绘制的形状中。我已经得到了下面的代码,无法找到解决方案,使文本“适合”我的形状(见下图)。
var svg = d3.select('#svg')
.append('svg')
.attr('width', 500)
.attr('height', 200);
var global = svg.append('g');
global.append('circle')
.attr('cx', 150)
.attr('cy', 100)
.attr('r', 50);
global.append('text')
.attr('x', 150)
.attr('y', 100)
.attr('height', 'auto')
.attr('text-anchor', 'middle')
.text('Text meant to fit within circle')
.attr('fill', 'red');
答案 0 :(得分:7)
SVG不提供文本换行,但使用foreignObject
可以实现类似的效果。假设radius
是圆的半径,我们可以计算适合圆圈的框的尺寸:
var side = 2 * radius * Math.cos(Math.PI / 4),
dx = radius - side / 2;
var g = svg.append('g')
.attr('transform', 'translate(' + [dx, dx] + ')');
g.append("foreignObject")
.attr("width", side)
.attr("height", side)
.append("xhtml:body")
.html("Lorem ipsum dolor sit amet, ...");
小组应该少量移位以使文本居中。我知道这不是所要求的,但它可能会有所帮助。我写了一个小fiddle。结果将如下所示:
答案 1 :(得分:4)
这是我能做的最好的事情。
我希望居中并将文本放在SVG中的圆圈或矩形内。 无论文本长度如何,文本都应保持居中(水平/垂直)。
svg {
width: 600px;
height: 200px;
background-color: yellow;
}
.circle {
background-color: blue;
height: 100%;
border-radius: 100%;
text-align: center;
line-height: 200px;
font-size: 30px;
}
.circle span {
line-height: normal;
display:inline-block;
vertical-align: middle;
color: white;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
}

<svg>
<foreignObject width="200" height="200" x="100" y="100" transform="translate(-100,-100)">
<div class="circle">
<span>Here is a</span>
</div>
</foreignObject>
<foreignObject width="200" height="200" x="300" y="100" transform="translate(-100,-100)">
<div class="circle">
<span>Here is a paragraph</span>
</div>
</foreignObject>
<foreignObject width="200" height="200" x="500" y="100" transform="translate(-100,-100)">
<div class="circle">
<span>Here is a paragraph that requires word wrap</span>
</div>
</foreignObject>
</svg>
&#13;
transform属性不是必需的,我使用translate(-r,-r),以便foreignObject的(x,y)类似于SVG圈的(cx,cy),并且宽度,高度= 2 * r,r为半径。
我这样做是用作D3力布局中的节点。我将这个片段翻译成javascript D3的风格。
答案 2 :(得分:4)
如果您将内容添加到SVG形状正下方的<text>
元素内,则可以使用D3plus&#39; .textwrap()
功能就是这样做的。我引用了documentation:
使用
d3plus.textwrap
,SVG<text>
元素可以分开<tspan>
行,就像HTML与<div>
元素一样.... D3plus会自动检测是否有<rect>
或<circle>
元素 直接放在DOM中的<text>
容器元素之前,并使用 用于包装文本的元素的形状和尺寸。如果它找不到 一个,或者该行为需要被覆盖,他们可以手动 使用.shape( )
,.width( )
和.height( )
指定。
我已经创建了一个codepen来更好地说明这一点,因为文档中的示例可能有点令人困惑:http://codepen.io/thdoan/pen/rOPYxE
答案 3 :(得分:1)
这不太理想,但是@ Pablo.Navarro的回答让我得到了以下结论。
var svg = d3.select('#svg')
.append('svg')
.attr('width', 500)
.attr('height', 200);
var radius = 60,
x = 150,
y = 100,
side = 2 * radius * Math.cos(Math.PI / 4),
dx = radius - side / 2;
var global = svg.append('g')
.attr('transform', 'translate(' + [ dx, dx ] + ')');
global.append('circle')
.attr('cx', x)
.attr('cy', y)
.attr('r', radius);
global.append('foreignObject')
.attr('x', x - (side/2))
.attr('y', y - (side/2))
.attr('width', side)
.attr('height', side)
.attr('color', 'red')
.append('xhtml:p')
.text('Text meant to fit within circle')
.attr('style', 'text-align:center;padding:2px;margin:2px;');