我正在尝试通过单击节点本身来折叠节点。目前的图是具有可拖动节点的力导向图。
我面临的问题是,在附加节点点击事件后,我无法触发点击而是节点从其位置移开(就像在鼠标点击时拖动一样)。
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20);
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 graph = { "links" : [ { "relation" : "Relation 0",
"source" : 0,
"target" : 1
},
{ "relation" : "Relation 1",
"source" : 1,
"target" : 3
},
{ "relation" : "Relation 3",
"source" : 1,
"target" : 4
},
{ "relation" : "Relation 4",
"source" : 1,
"target" : 5
},
{ "relation" : "Relation 5",
"source" : 0,
"target" : 2
},
{ "relation" : "Relation 6",
"source" : 2,
"target" : 6
}
],
"nodes" : [ { "collapsed" : false,
"collapsing" : 0,
"id" : 0,
"name" : "Node 0"
},
{ "collapsed" : false,
"collapsing" : 0,
"id" : 1,
"name" : "Node 1"
},
{ "collapsed" : false,
"collapsing" : 0,
"id" : 2,
"name" : "Node 2"
},
{ "collapsed" : false,
"collapsing" : 0,
"id" : 3,
"name" : "Node 3"
},
{ "collapsed" : false,
"collapsing" : 0,
"id" : 4,
"name" : "Node 4"
},
{ "collapsed" : false,
"collapsing" : 0,
"id" : 5,
"name" : "Node 5"
},
{ "collapsed" : false,
"collapsing" : 0,
"id" : 6,
"name" : "Node 6"
}
]
};
var edges = [];
graph.links.forEach(function(e) {
var sourceNode = graph.nodes.filter(function(n) {
return n.id === e.source;
})[0],
targetNode = graph.nodes.filter(function(n) {
return n.id === e.target;
})[0];
edges.push({
source: sourceNode,
target: targetNode,
relation: e.relation
});
});
update();
function update() {
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.value); });
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 8)
.attr("fill", function(d) { return color(d.group); })
.on("click", togglenode)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
}
function dragstarted(d) {
console.log('drag started');
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
console.log('dragged');
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
console.log('drag ended');
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function togglenode(d) {
console.log('clicked node : '+d.id);
if (!d3.event.defaultPrevented) {
var inc = d.collapsed ? -1 : 1;
recurse(d);
function recurse(sourceNode){
//check if link is from this node, and if so, collapse
edges.forEach(function(l) {
if (l.source.id === sourceNode.id){
l.target.collapsing += inc;
recurse(l.target);
}
});
}
d.collapsed = !d.collapsed;
update();
}
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 4.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.js"></script>
<svg width="800" height="500"></svg>