我从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
没有显式定义,它们是从这个answer借用的。
如图所示,每个文本标签的位置都是硬编码的,因此它出现在每个节点的中心。显然,这不是正确的解决方案。
我的问题是,我应该如何正确地将每个文本标签与每个节点圆圈动态关联,以便如果标签的位置随着圆圈的位置自动更改。非常欢迎使用代码示例进行概念性解释。
发布于 2012-08-08 21:40:59
在由D3创建的text-anchor元素上,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
的位置,而是更改同时移动circle
和text
的g
元素的位置。
这是一个在圆形上显示居中文本的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 + ")";
});
发布于 2013-07-06 09:48:36
当涉及到文本元素时,此页面为describes what's going on under the svg hood。了解底层机制和数据结构帮助我更好地掌握了如何修改代码以使其正常工作。
https://stackoverflow.com/questions/11857615
复制相似问题