2

所以我有一个 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 语句来检查,但我有点想避免这种情况。谢谢。

4

3 回答 3

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 个字段。

于 2013-09-03T19:28:39.277 回答
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>
于 2014-08-27T08:03:17.663 回答
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 将数据添加到 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 数组的更惯用方法的建议。

于 2013-09-03T21:11:42.567 回答