d3节点标签

我一直在使用这个D3项目的示例代码来学习如何显示D3graphics,我似乎无法让文字显示在圆圈中间(类似于这个例子和这个例子 )。 我看了其他的例子,并试图添加

node.append("title").text("Node Name To Display") 

 node.append("text") .attr("text-anchor", "middle") .attr("dy", ".3em").text("Node Name To Display") 

刚刚定义了节点之后,但我看到的唯一结果是当我将鼠标hover在每个节点上时,“显示的节点名称”正在显示。 它没有显示为圈内的文字。 我是否必须编写自己的svg文本对象,并根据圆的半径坐标确定需要放置的坐标? 从另外两个例子来看,似乎D3已经在某种程度上关心了这一点。 我只是不知道调用/设置的正确的属性。

有很多示例显示如何将标签添加到graphics和树形可视化中,但是我可能从这个最简单的开始:

你还没有发布一个链接到你的代码,但我猜这个node指的是SVG圈元素的select。 您不能将文本元素添加到圆形元素,因为圆形元素不是容器 ; 将一个文本元素添加到一个圆圈将被忽略。

通常,使用G元素为每个节点分组一个圆形元素(或一个图像元素,如上)和一个文本元素。 最终的结构如下所示:

 <g class="node" transform="translate(130,492)"> <circle r="4.5"/> <text dx="12" dy=".35em">Gavroche</text> </g> 

使用数据连接为每个节点创buildG元素,然后使用selection.append为每个节点添加一个圆和一个文本元素。 像这样的东西:

 var node = svg.selectAll(".node") .data(nodes) .enter().append("g") .attr("class", "node") .call(force.drag); node.append("circle") .attr("r", 4.5); node.append("text") .attr("dx", 12) .attr("dy", ".35em") .text(function(d) { return d.name }); 

这种方法的一个缺点是,你可能希望标签绘制在圆圈之上。 由于SVG还不支持z-index,因此元素按文档顺序绘制; 所以,上面的方法会使一个标签被绘制在其圆上 ,但是也可能被绘制在其他圆圈下面 。 您可以通过使用两个数据连接并为圆圈和标签创build单独的组来解决此问题,如下所示:

 <g class="nodes"> <circle transform="translate(130,492)" r="4.5"/> <circle transform="translate(110,249)" r="4.5"/> … </g> <g class="labels"> <text transform="translate(130,492)" dx="12" dy=".35em">Gavroche</text> <text transform="translate(110,249)" dx="12" dy=".35em">Valjean</text> … </g> 

和相应的JavaScript:

 var circle = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(nodes) .enter().append("circle") .attr("r", 4.5) .call(force.drag); var text = svg.append("g") .attr("class", "labels") .selectAll("text") .data(nodes) .enter().append("text") .attr("dx", 12) .attr("dy", ".35em") .text(function(d) { return d.name }); 

该技术用于移动专利诉讼示例(具有用于创build白色阴影的附加文本元素)。

如果要将节点增大以适应大标签,则可以在绘制SVG文本节点后使用getBBox属性。 以下是我如何做的,具有固定坐标的节点列表以及两种可能的形状:

 nodes.forEach(function(v) { var nd; var cx = v.coord[0]; var cy = v.coord[1]; switch (v.shape) { case "circle": nd = svg.append("circle"); break; case "rectangle": nd = svg.append("rect"); break; } var w = 10; var h = 10; if (v.label != "") { var lText = svg.append("text"); lText.attr("x", cx) .attr("y", cy + 5) .attr("class", "labelText") .text(v.label); var bbox = lText.node().getBBox(); w = Math.max(w,bbox.width); h = Math.max(h,bbox.height); } var pad = 4; switch (v.shape) { case "circle": nd.attr("cx", cx) .attr("cy", cy) .attr("r", Math.sqrt(w*w + h*h)/2 + pad); break; case "rectangle": nd.attr("x", cx - w/2 - pad) .attr("y", cy - h/2 - pad) .attr("width", w + 2*pad) .attr("height", h + 2*pad); break; } }); 

请注意,添加了形状,添加了文本, 然后定位了形状,以便将文本显示在顶部。

我发现这个指南在尝试完成类似的东西时非常有用:

https://www.dashingd3js.com/svg-text-element

根据以上链接,此代码将生成圈子标签:

 <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> </head> <body style="overflow: hidden;"> <div id="canvas" style="overflow: hidden;"></div> <script type="text/javascript"> var graph = { "nodes": [ {name: "1", "group": 1, x: 100, y: 90, r: 10 , connected : "2"}, {name: "2", "group": 1, x: 200, y: 50, r: 15, connected : "1"}, {name: "3", "group": 2, x: 200, y: 130, r: 25, connected : "1"} ] } $( document ).ready(function() { var width = 2000; var height = 2000; var svg = d3.select("#canvas").append("svg") .attr("width", width) .attr("height", height) .append("g"); var lines = svg.attr("class", "line") .selectAll("line").data(graph.nodes) .enter().append("line") .style("stroke", "gray") // <<<<< Add a color .attr("x1", function (d, i) { return dx }) .attr("y1", function (d) { return dy }) .attr("x2", function (d) { return findAttribute(d.connected).x }) .attr("y2", function (d) { return findAttribute(d.connected).y }) var circles = svg.selectAll("circle") .data(graph.nodes) .enter().append("circle") .style("stroke", "gray") .style("fill", "white") .attr("r", function (d, i) { return dr }) .attr("cx", function (d, i) { return dx }) .attr("cy", function (d, i) { return dy }); var text = svg.selectAll("text") .data(graph.nodes) .enter() .append("text"); var textLabels = text .attr("x", function(d) { return dx; }) .attr("y", function(d) { return dy; }) .text( function (d) { return d.name }) .attr("font-family", "sans-serif") .attr("font-size", "10px") .attr("fill", "red"); }); function findAttribute(name) { for (var i = 0, len = graph.nodes.length; i < len; i++) { if (graph.nodes[i].name === name) return graph.nodes[i]; // Return as soon as the object is found } return null; // The object was not found } </script> </body> </html>