将标签放在 d3.js 中节点的中心
Placing labels at the center of nodes in d3.js
我从d3.js开始,并尝试创建一排节点,每个节点都包含一个居中数字标签。
我能够以视觉方式产生所需的结果,但我这样做的方式并不是最佳的,因为它涉及对每个文本元素的 x-y 坐标进行硬编码。下面是代码:
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 类,而类 nodes
和 labels
没有明确定义,它们是从这个答案借用的。
如图所示,每个文本标签的位置都是硬编码的,因此它显示在每个节点的中心。显然,这不是正确的解决方案。
我的问题是,我应该如何正确地将每个文本标签与每个节点圆圈动态关联,以便标签的位置与圆圈的位置一起自动变化。代码示例非常欢迎概念解释。
文本锚点属性在 D3 创建的 svg 元素上按预期工作。但是,您需要将text
和circle
追加到公共g
元素中,以确保text
和circle
彼此居中。
为此,您可以将nodes
变量更改为:
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.y
和d.x
,而不仅仅是字符串列表。
然后,将circle
和text
追加代码替换为以下内容:
// 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
的位置,而是更改g
元素的位置,该元素会同时移动circle
和text
。
下面是一个 JSFiddle,在圆圈上显示居中的文本。
如果要使文本位于单独的 g
元素中,以便它始终显示在顶部,请使用在第一个 g
元素的创建中设置的d.x
和d.y
值来transform
文本。
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 + ")";
});
最好的答案来自提问者本人:
只是进一步的观察:只有.attr("文本锚","中间") 对于每个文本元素,标签位于水平中间,但 垂直略有偏差。我通过添加attr("y",".3em")来解决此问题 (借用D3.js网站上的例子),似乎效果很好 即使对于任意大小的节点圆。然而,这到底是什么 附加属性确实无法理解。当然,它确实如此 每个文本元素的 y 坐标的东西,但为什么 .3em 在 特定?这对我来说几乎是神奇的...
只需向每个文本元素添加.attr("text-anchor", "middle")
即可。
例:
node.append("text")
.attr("x", 0)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.name; });
本页描述了当涉及到文本元素时,svg 引擎盖下发生了什么。了解底层机制和数据结构帮助我更好地处理如何修改代码以使其正常工作。
- 节点Js:How to catch a“;没有这样的文件或目录“;读取线模块出错
- 节点.js将变量显示为 HTML
- 如何解决'窗口未定义'终端上的节点JS出错
- S3文件上传文件对象使用节点js
- 在节点 js 中使用护照本地模块验证(登录)密码时出错
- 嵌套的promise节点js
- 使用节点JS发送电子邮件
- 节点JS重定向循环
- 起始节点.js用于并行的线程池
- 获取图像节点js的主色
- 调整节点js中的图像大小
- 节点JS express和控制台输出到命令行与浏览器
- 节点JS:时间机器坏了——timekeeper.travel不做时间旅行
- 如何访问日期并将其插入数据库?节点.JS&MongoDB
- 节点.js快速删除 req.body 不起作用
- 节点.js中的嵌套异步操作
- 如何在核心php应用程序中使用节点js json Web令牌库
- 使用节点js的Bootstrap和Jquery
- 节点.js加密输入/输出类型
- 节点.js在不可能的地方打印“未定义”