将标签放在d3.js中节点的中心 [英] Placing labels at the center of nodes in d3.js

查看:131
本文介绍了将标签放在d3.js中节点的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am starting with d3.js, and am trying to create a row of nodes each of which contains a centered number label.

我能够生成所需的结果在视觉上,但我做的方式是几乎不是最佳的,因为它涉及硬编码每个文本元素的xy坐标。下面是代码:

I am able to produce the desired result visually, but the way I did it is hardly optimal as it involves hard-coding the x-y coordinates for each text element. Below is the code:

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;
                });

类是自定义CSS类I分别为 circle 元素定义,而类 nodes 标签未明确定义,而是从此答案借用。

The node class is custom CSS class I've defined separately for the circle elements, whereas classes nodes and labels are not explicitly defined and they are borrowed from this answer.

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

As seen, the positioning of each text label is hard-coded so that it appears at the center of the each node. Obviously, this is not the right solution.

我的问题是,我应该如何正确地关联每个文本标签与每个节点圆动态,以便如果标签的位置更改以及一个圆的自动。

My question is that how should I correctly associate each text label with each node circle dynamically so that if the positioning of a label changes along with that of a circle automatically. Conceptual explanation is extremely welcome with code example.

推荐答案

text-anchor 属性在D3创建的svg元素上按预期工作。但是,您需要将文本附加到公共 g 元素,以确保文本彼此居中。

The text-anchor attribute works as expected on an svg element created by D3. However, you need to append the text and the circle into a common g element to ensure that the text and the circle are centered with one another.

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

To do this, you can change your nodes variable to:

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 + ")"; 
           });

请注意,数据集现在是一个列表的对象,以便可以使用 dy dx 而不只是一个字符串列表。

Note that the dataset is now a list of objects so that d.y and d.x can be used instead of just a list of strings.

然后,替换您的文本 p>

Then, replace your circle and text append code with the following:

// 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;
      });

现在,不是改变圆的位置您更改 g 元素的位置,它会移动文本

Now, instead of changing the position of the circle you change the position of the g element which moves both the circle and the text.

以下是 JSFiddle

如果您希望将文本放在单独的 g 元素中,总是显示在顶部,然后使用第一个 g 中设置的 dx dy / code>元素的创建转换

If you want to have your text be in a separate g element so that it always appears on top, then use the d.x and d.y values set in the first g element's creation to transform the text.

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 + ")"; 
    });

这篇关于将标签放在d3.js中节点的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆