我试图制作d3力图,但我无法让标签发挥作用。有时文本会弹出屏幕顶部。如何为每个节点分配标签(标签为其标识)。
这就是我尝试过的:
var label = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("text")
.attr("class", "label")
.text("test")
还有一个额外的问题,我如何在我的线上获得箭头?
答案 0 :(得分:2)
将组元素中的圆圈和文本分组。您可以使用marker-end属性向行添加结束标记。
还有marker-mid
和marker-start
配置。
var graph = JSON.parse('{"nodes":[{"id":"0","color":"#4444E5"},{"id":"1","color":"#4444E5"},{"id":"2","color":"#CCCCCC"},{"id":"3","color":"#CCCCCC"},{"id":"4","color":"#CCCCCC"},{"id":"5","color":"#CCCCCC"},{"id":"6","color":"#CCCCCC"},{"id":"7","color":"#CCCCCC"},{"id":"8","color":"#CCCCCC"},{"id":"9","color":"#CCCCCC"},{"id":"10","color":"#cc0000"},{"id":"11","color":"#CCCCCC"},{"id":"12","color":"#CCCCCC"},{"id":"13","color":"#CCCCCC"},{"id":"14","color":"#CCCCCC"},{"id":"15","color":"#cc0000"}],"links":[{"source":1,"target":15,"weight":-0.7582412523901727},{"source":0,"target":6,"weight":-0.08179822732917646},{"source":6,"target":10,"weight":0.0939757437427291},{"source":3,"target":4,"weight":0.436380368086641},{"source":4,"target":5,"weight":-0.5385567058738547},{"source":1,"target":2,"weight":-0.277729004201837},{"source":2,"target":3,"weight":0.7675128737907505},{"source":13,"target":14,"weight":0.5519067984674436},{"source":14,"target":15,"weight":0.832660697502495},{"source":5,"target":7,"weight":0.8607887414383458},{"source":7,"target":8,"weight":-0.8965760877371078},{"source":8,"target":9,"weight":-0.2488791800975232},{"source":9,"target":10,"weight":-0.646075500567235},{"source":12,"target":13,"weight":0.40622804770087395},{"source":0,"target":11,"weight":0.24806004723386413},{"source":11,"target":12,"weight":0.8035303834469385}]}');
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var defs = svg.append("defs")
var marker = defs
.append("svg:marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
marker.append("path")
.attr("d", "M0,-5L10,0L0,5")
.attr("class", "arrowHead");
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.weight);
}).attr("marker-end", "url(#arrow)")
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("g");
node.append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return d3.color(d.color);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var label = node.append("text")
.attr("class", "label")
.text("test")
node.append("title")
.text(function(d) {
return d.id;
});
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}

line {
stroke: black;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="600"></svg>
&#13;
答案 1 :(得分:1)
您的文字不是模拟的一部分。除此之外,当你做...
var label = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("text")
...您的“输入”选择会减少一个元素,因为该SVG中已经有一个<g>
元素,其中包含node
个类。
解决方案:将圈子和文字附加到群组:
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("foo")
.data(graph.nodes)
.enter().append("g");
var circles = node.append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return d3.color(d.color);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var label = node.append("text")
.attr("class", "label")
.text("test");
在transform
函数中使用ticked
:
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
这是您更新的代码:
var graph = JSON.parse('{"nodes":[{"id":"0","color":"#4444E5"},{"id":"1","color":"#4444E5"},{"id":"2","color":"#CCCCCC"},{"id":"3","color":"#CCCCCC"},{"id":"4","color":"#CCCCCC"},{"id":"5","color":"#CCCCCC"},{"id":"6","color":"#CCCCCC"},{"id":"7","color":"#CCCCCC"},{"id":"8","color":"#CCCCCC"},{"id":"9","color":"#CCCCCC"},{"id":"10","color":"#cc0000"},{"id":"11","color":"#CCCCCC"},{"id":"12","color":"#CCCCCC"},{"id":"13","color":"#CCCCCC"},{"id":"14","color":"#CCCCCC"},{"id":"15","color":"#cc0000"}],"links":[{"source":1,"target":15,"weight":-0.7582412523901727},{"source":0,"target":6,"weight":-0.08179822732917646},{"source":6,"target":10,"weight":0.0939757437427291},{"source":3,"target":4,"weight":0.436380368086641},{"source":4,"target":5,"weight":-0.5385567058738547},{"source":1,"target":2,"weight":-0.277729004201837},{"source":2,"target":3,"weight":0.7675128737907505},{"source":13,"target":14,"weight":0.5519067984674436},{"source":14,"target":15,"weight":0.832660697502495},{"source":5,"target":7,"weight":0.8607887414383458},{"source":7,"target":8,"weight":-0.8965760877371078},{"source":8,"target":9,"weight":-0.2488791800975232},{"source":9,"target":10,"weight":-0.646075500567235},{"source":12,"target":13,"weight":0.40622804770087395},{"source":0,"target":11,"weight":0.24806004723386413},{"source":11,"target":12,"weight":0.8035303834469385}]}');
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.weight);
})
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("foo")
.data(graph.nodes)
.enter().append("g");
var circles = node.append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return d3.color(d.color);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var label = node.append("text")
.attr("class", "label")
.text("test");
node.append("title")
.text(function(d) {
return d.id;
});
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="400"></svg>