我有向图。它有3种力量:
我想暂时禁用centering
强制。我不是在问如何禁用整个力布局,而是只禁用一种特定的力。
我对d3.forceSimulation
和force
函数的文档进行了广泛的研究,但是没有地方提到如何暂停作用力。
我试图通过以下方式删除然后重置力:
this.simulation.force("center", null);
在dragstart
中,然后
this.simulation.force("center", oldCenterForce)
在dragend
中。问题在于,当拖动结束时,节点立即跳回中心,没有平滑的过渡。
我还尝试提供一个自定义的force
函数来检查是否this.isDragging
。如果它在拖动,则返回一个哑函数(alpha) => {}
,如果不是,则返回d3.forceCenter(...)
,但它抱怨缺少node
数组。在调用该函数之前,我尝试做过.bind(this.simulation)
,但仍然无法正常工作。
我创建力模拟并将其存储在this.simulation
createForceSimulation = (nodeData: G.Node[], edgeData: G.Link[]) => {
d3.forceSimulation(nodeData)
.force("link", d3.forceLink(edgeData).id((d: any) => d.id))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(this.props.width / 2, this.props.height / 2))
.force("collide", d3.forceCollide(this.circleSize * 2))
.velocityDecay(this.simulationVelocityDecay)
}
我处理拖动节点的部分:
drag = simulation => {
const dragStarted = d => {
if (!d3.event.active) {
simulation.alphaTarget(0.7).restart()
}
d.fx = d.x
d.fy = d.y
}
const dragged = d => {
d.fx = d3.event.x
d.fy = d3.event.y
}
const dragEnded = d => {
if (!d3.event.active) simulation.alphaTarget(0)
d.fx = null
d.fy = null
}
return d3
.drag()
.on("start", dragStarted)
.on("drag", dragged)
.on("end", dragEnded)
}
预期:强制立即停止
实际:力量不会停止或崩溃。
答案 0 :(得分:0)
使用带有强度参数的自定义中心力。
.force("center", myCenterForce(this.props.width / 2, this.props.height / 2))
在拖动功能调用中
simulation.force("center").strength(0);
simulation.force("center").strength(1.0);
或者您可以在刻度功能中对强度进行动画/内插。
var dragNode = null;
drag = simulation => {
const dragStarted = function (d) {
if (!d3.event.active) {
simulation.alphaTarget(0.7).restart()
}
dragNode = null;
d.fx = d.x
d.fy = d.y
}
const dragged = function (d) {
d.fx = d3.event.x
d.fy = d3.event.y
}
const dragEnded = function (d) {
if (!d3.event.active) simulation.alphaTarget(0);
dragNode = this;
d3.select(this).attr("data-strength", 0)
.transition().duration(2000)
.attr("data-strength", 1.0)
.on("end", function () { dragNode = null; } );
d.fx = null
d.fy = null
}
return d3
.drag()
.on("start", dragStarted)
.on("drag", dragged)
.on("end", dragEnded)
}
function tick() {
if (dragNode)
simulation.force("center")
.strength(d3.select(dragNode).attr("data-strength"));
// update nodes
}
海关部队
function myCenterForce(x, y) {
var nodes;
var strength = 1.0;
if (x == null) x = 0;
if (y == null) y = 0;
function force() {
var i,
n = nodes.length,
node,
sx = 0,
sy = 0;
for (i = 0; i < n; ++i) {
node = nodes[i], sx += node.x, sy += node.y;
}
for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
node = nodes[i], node.x -= strength * sx, node.y -= strength * sy;
}
}
force.initialize = function(_) {
nodes = _;
};
force.x = function(_) {
return arguments.length ? (x = +_, force) : x;
};
force.y = function(_) {
return arguments.length ? (y = +_, force) : y;
};
force.strength = function(_) {
return arguments.length ? (strength = +_, force) : strength;
};
return force;
}