我制作了一个 D3 强制有向图d3.forceSimulation()
并附加了拖动功能。单击一个节点时,我不希望其他节点相应移动。d.fx
现在我可以通过设置and来冻结被拖动的节点d.fy
,如下所示:
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = d.x;
d.fy = d.y;
}
拖动一个节点时是否可以冻结所有其他节点?
我制作了一个 D3 强制有向图d3.forceSimulation()
并附加了拖动功能。单击一个节点时,我不希望其他节点相应移动。d.fx
现在我可以通过设置and来冻结被拖动的节点d.fy
,如下所示:
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = d.x;
d.fy = d.y;
}
拖动一个节点时是否可以冻结所有其他节点?
感谢@rioV8 的提示!我试图在拖动一个节点时修复其他节点。
node.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended))
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
fix_nodes(d);
}
// Preventing other nodes from moving while dragging one node
function fix_nodes(this_node) {
node.each(function(d){
if (this_node != d){
d.fx = d.x;
d.fy = d.y;
}
});
}
这是一个允许在拖动过程中灵活操纵模拟力的解决方案:
let tempForces = {};
const modifyForces = (simulation) => {
tempForces = {};
// For example, I want to temporarily remove the "link" and "charge" forces during dragging.
(["link", "charge"]).forEach((forceName) => {
tempForces[forceName] = simulation.force(forceName);
simulation.force(forceName, null);
});
// You may modify your forces here. Store them to 'tempForces' if you'd like to restore them after dragging.
};
const restoreForces = (simulation) => {
for (let [name, force] of Object.entries(tempForces)) {
simulation.force(name, force);
}
tempForces = {};
};
然后分别在拖动开始和结束时调用 modifyForces() 和 restoreForces()。(改编自这个observable)
const start = function(event) {
modifyForces(simulation); // Modifying
if (!event.active) {
simulation.alphaTarget(0.1).restart();
}
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
};
const drag = function (event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
};
const end = function (event) {
restoreForces(simulation); // Restoring
if (!event.active) {
simulation.alphaTarget(0);
}
event.subject.fx = null;
event.subject.fy = null;
};
const dragBehavior = d3.drag()
.on("start", start)
.on("drag", drag)
.on("end", end);
node.call(dragBehavior);