SVG 文本响应式定位
Posted
技术标签:
【中文标题】SVG 文本响应式定位【英文标题】:SVG Text responsive positioning 【发布时间】:2013-09-07 01:57:58 【问题描述】:所以我有一个 SVG 矩形,里面有 SVG 文本。放置在文本框中的 SVG 文本包括来自用户配置文件的内容。此信息是从服务器发送的,我希望它具有如下特定定位:
到目前为止,我已经相当轻松地做到了这一点......但问题是有时人们没有完全填写他们的个人资料(即他们留下了他们的出生日期或位置)所以它最终创建了一个空白的 SVG 文本。
<g display="default">
<text x="10" y="30">Alexander the Great</text>
<text x="10" y="40"></text>
<text x="10" y="50">Greece </text>
</g>
我可以假设他们总是有自己的名字,但如果没有提供出生日期,我想要它,以便我的文本框足够智能,它将位置移动到姓名下方。
现在我在我的文本节点中输入特定的 x 和 y 属性,这就是证明这有点困难的原因。有没有办法让定位更敏感?通过 CSS 还是通过 SVG 属性?我通过 D3.js 生成 SVG 元素,所以如果需要,我可以简单地设置 if 语句来检查,但我有点想避免这种情况。谢谢。
【问题讨论】:
听起来你会想要使用 html 和一组div
s。它们会自动重新定位。
请注意,您可以通过 <foreignContent>
将 XHTML 嵌入到 SVG 中。
我知道<foreignContent>
并正在考虑制作一个 div 以便它可以自动重新定位,但我不完全确定这是否是一个好习惯。我会尝试一些事情,让你们知道。如果你们中的一个人可以将其发布为其他人查看示例的答案,那就太好了。
【参考方案1】:
在文本元素中使用 tspan。完美解决你的问题。
<text y="30">
<tspan x="200">Alexander the Great</tspan>
<tspan x="200" dy="1em"></tspan>
<tspan x="200" dy="1em">Greece </tspan>
</text>
【讨论】:
【参考方案2】:假设您正在接收配置文件条目的 JSON 数据,您可以用非空条目填充一个数组,然后从该数组生成文本节点。
record =
"name": "Alex G.",
"dob": "",
"location": "Greece"
;
// This provides and array of objects with both key names and values.
var props = d3.entries(record).filter(function(d)
return d.value.length > 0;
).map(function(d)
return d.key + ": " + d.value;
);
然后你可以用 d3 将数据添加到 DOM 中:
d3.select('g[display="default"]')
.data(props)
.enter().append('text')
.attr('x', 10)
.attr('y', function(d, i) return (i+1) * 10;)
.text(function(d) return d; );
编辑:采纳了 Adam Pearce 的建议,提出了一种更惯用的构造 props 数组的方法。
【讨论】:
创建 props 数组的更惯用的方法 - var props = d3.entries(record).filter(function(d) return d.value.length > 0; ).map(function (d) return d.key + ": " + d.value; ); 我认为 div 足以满足我的情况,但我接受这个答案,因为它似乎是 D3 的做法。我也很喜欢 Scott Cameron 的回答,但他的回答似乎有点老套,因为它使用的比例可能是也可能不是它的预期用途。【参考方案3】:您可能会使用序数 Y 刻度和数据绑定来控制 <text>
元素的数量和位置。
因为您关心元素的数量而不是内容,所以您的比例可能基于数组索引:
var yScale = d3.scale.ordinal()
.domain([0, 1, 2])
.range([30, 40, 50]);
如果您将数据放入一个数组(或多个用户的数组数组),您可以执行以下操作(假设只有一个用户):
d3.selectAll("text")
.data(profile)
.enter().append("text")
.attr("x", 10)
.attr("y", function(d, i) return yScale(i); )
.text(function(d) return d; );
如果您的“个人资料”数组是["Alexander the Great", "Greece"]
,您将只得到名称和位置。如果您包含出生数据的元素,那么您将获得所有 3 个字段。
【讨论】:
以上是关于SVG 文本响应式定位的主要内容,如果未能解决你的问题,请参考以下文章