首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在d3.js中将标签放在节点的中心

在d3.js中将标签放在节点的中心
EN

Stack Overflow用户
提问于 2012-08-08 12:21:07
回答 2查看 62.1K关注 0票数 56

我从d3.js开始,尝试创建一行节点,每个节点都包含一个居中的数字标签。

我能够在视觉上产生想要的结果,但我这样做的方式很难是最佳的,因为它涉及到为每个文本元素硬编码x-y坐标。代码如下:

代码语言:javascript
复制
var svg_w = 800;
var svg_h = 400;
var svg = d3.select("body")
    .append("svg")
    .attr("width", svg_w)
    .attr("weight", svg_h);

var dataset = [];
for (var i = 0; i < 6; i++) {
    var datum = 10 + Math.round(Math.random() * 20);
    dataset.push(datum);
}

var nodes = svg.append("g")
               .attr("class", "nodes")
               .selectAll("circle")
               .data(dataset)
               .enter()
               .append("circle")
               .attr("class", "node")
               .attr("cx", function(d, i) {
                   return (i * 70) + 50;
               })
               .attr("cy", svg_h / 2)
               .attr("r", 20);

var labels = svg.append("g")
                .attr("class", "labels")
                .selectAll("text")
                .data(dataset)
                .enter()
                .append("text")
                .attr("dx", function(d, i) {
                    return (i * 70) + 42
                })
                .attr("dy", svg_h / 2 + 5)
                .text(function(d) {
                    return d;
                });

node类是我为circle元素单独定义的自定义CSS类,而类nodeslabels没有显式定义,它们是从这个answer借用的。

如图所示,每个文本标签的位置都是硬编码的,因此它出现在每个节点的中心。显然,这不是正确的解决方案。

我的问题是,我应该如何正确地将每个文本标签与每个节点圆圈动态关联,以便如果标签的位置随着圆圈的位置自动更改。非常欢迎使用代码示例进行概念性解释。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-08 21:40:59

在由D3创建的text-anchor元素上,svg属性按预期工作。但是,您需要将textcircle附加到一个通用的g元素中,以确保textcircle彼此居中。

为此,您可以将nodes变量更改为:

代码语言:javascript
复制
var nodes = svg.append("g")
           .attr("class", "nodes")
           .selectAll("circle")
           .data(dataset)
           .enter()
           // Add one g element for each data node here.
           .append("g")
           // Position the g element like the circle element used to be.
           .attr("transform", function(d, i) {
             // Set d.x and d.y here so that other elements can use it. d is 
             // expected to be an object here.
             d.x = i * 70 + 50,
             d.y = svg_h / 2;
             return "translate(" + d.x + "," + d.y + ")"; 
           });

请注意,dataset现在是一个对象列表,因此可以使用d.yd.x,而不仅仅是字符串列表。

然后,将您的circletext附加代码替换为以下代码:

代码语言:javascript
复制
// Add a circle element to the previously added g element.
nodes.append("circle")
      .attr("class", "node")
      .attr("r", 20);

// Add a text element to the previously added g element.
nodes.append("text")
     .attr("text-anchor", "middle")
     .text(function(d) {
       return d.name;
      });

现在,不是更改circle的位置,而是更改同时移动circletextg元素的位置。

这是一个在圆形上显示居中文本的JSFiddle

如果希望将文本放在单独的g元素中,使其始终显示在顶部,则使用在创建第一个g元素时设置的d.xd.y值来transform文本。

代码语言:javascript
复制
var text = svg.append("svg:g").selectAll("g")
         .data(force.nodes())
         .enter().append("svg:g");

text.append("svg:text")
    .attr("text-anchor", "middle")
    .text(function(d) { return d.name; });

text.attr("transform",  function(d) {
      return "translate(" + d.x + "," + d.y + ")"; 
    });
票数 69
EN

Stack Overflow用户

发布于 2013-07-06 09:48:36

当涉及到文本元素时,此页面为describes what's going on under the svg hood。了解底层机制和数据结构帮助我更好地掌握了如何修改代码以使其正常工作。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11857615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档