所以我有一个内置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语句来检查,但我有点想避免这种情况。感谢。
答案 0 :(得分: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个字段。
答案 1 :(得分:1)
假设您正在接收配置文件条目的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:
将数据添加到DOMd3.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关于构建道具数组的更惯用方法的建议。
答案 2 :(得分: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>