以下是一个简单的D3.js力导向图示例,演示如何添加新节点和关系连线:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3.js力导向图 - 新增节点和关系连线示例</title>
<script src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
<svg width="800" height="600"></svg>
<script>
// 定义节点和关系数据
var nodes = [
{ id: "node1", name: "节点1" },
{ id: "node2", name: "节点2" },
{ id: "node3", name: "节点3" },
{ id: "node4", name: "节点4" }
];
var links = [
{ source: "node1", target: "node2" },
{ source: "node1", target: "node3" },
{ source: "node2", target: "node4" }
];
// 创建力导向图对象
var simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(400, 300));
// 创建节点和关系连线
var svg = d3.select("svg");
var link = svg.selectAll("line")
.data(links)
.enter().append("line")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.attr("stroke-width", d => Math.sqrt(d.value));
var node = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 10)
.attr("fill", "#ccc")
.call(drag(simulation));
var label = svg.selectAll("text")
.data(nodes)
.enter().append("text")
.text(d => d.name)
.attr("font-size", "12px")
.attr("dx", 15)
.attr("dy", 4);
// 定义拖拽行为
function drag(simulation) {
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event, d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
// 新增节点和关系连线
var newNode = { id: "node5", name: "节点5" };
var newLink = { source: "node4", target: "node5" };
nodes.push(newNode);
links.push(newLink);
node = node.data(nodes, d => d.id);
node.exit().remove();
node = node.enter().append("circle")
.attr("r", 10)
.attr("fill", "#ccc")
.call(drag(simulation))
.merge(node);
label = label.data(nodes, d => d.id);
label.exit().remove();
label = label.enter().append("text")
.text(d => d.name)
.attr("font-size", "12px")
.attr("dx", 15)
.attr("dy", 4)
.merge(label);
link = link.data(links);
link.exit().remove();
link = link.enter().append("line")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.attr("stroke-width", d => Math.sqrt(d.value))
.merge(link);
// 更新力导向图
simulation.nodes(nodes);
simulation.force("link").links(links);
simulation.alpha(1).restart();
</script>
</body>
</html>
```
在上面的示例中,我们首先定义了一个简单的节点和关系数据,并创建了一个力导向图对象。然后,我们使用D3.js创建了节点和关系连线的SVG元素,并绑定了数据。
接下来,我们定义了一个拖拽行为,以便用户可以拖动节点。然后,我们添加了一个新节点和一个新的关系连线,并使用D3.js更新了节点和关系连线的SVG元素。
最后,我们更新了力导向图对象,并重新启动了力导向图的模拟,以确保新节点和关系连线被正确地添加到力导向图中。
请注意,这只是一个简单的示例,实际应用中需要根据具体需求进行更复杂的处理。