gpt4 book ai didi

javascript - 使用拖动行为时,具有链接力的 D3.js v4 力布局会导致奇怪的移动

转载 作者:行者123 更新时间:2023-11-28 04:23:01 24 4
gpt4 key购买 nike

我正在尝试使用 d3.js v4 创建一个强制布局,并且市长部分在使用拖动行为时确实很好地接受了一个问题。

当点击一个节点并将其拖动到其他未连接到被点击节点的节点周围时,飞走:

var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

function drawNode(nodes) {
return svg.selectAll("circle.node")
.data(nodes, function (d, i) { return d.Id; })
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.attr("fill", "blue")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
}

function drawMainNode(nodes) {
return svg.selectAll("circle.mainnode")
.data(nodes, function (d, i) { return d.Id; })
.enter().append("circle")
.attr("class", "mainnode")
.attr("r", 15)
.attr("fill", "red")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
}

function drawLinks(links) {
return svg.selectAll("line")
.data(links, function (d, i) { return d.source + "-" + d.target; })
.enter().append("line")
.attr("stroke-width", 3);
}

function dragstarted(d) {
if (!d3.event.active) dragSimualtion.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) dragSimualtion.alphaTarget(0);
d.fx = null;
d.fy = null;
}

function ticked() {
dLinks
.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; });

dNodes
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });

dMainNodes
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}

var dLinks = drawLinks(mainLinks.concat(nodeLinks));
var dNodes = drawNode(nodes);
var dMainNodes = drawMainNode(mainNodes);

var simulation = d3.forceSimulation(mainNodes.concat(nodes))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collide", d3.forceCollide(20).radius(20))
.force("links", d3.forceLink(mainLinks.concat(nodeLinks))
.id(function (d) { return d.Id; }))
.alpha(0.9)
.alphaDecay(0.1)
.on("tick", ticked);

var dragSimualtion = d3.forceSimulation(mainNodes.concat(nodes))
.force("collide", d3.forceCollide(20).radius(20))
.force("links", d3.forceLink(mainLinks.concat(nodeLinks))
.id(function (d) { return d.Id; }))
.alphaDecay(0.1)
.on("tick", ticked)
.stop()

Plunkr

我尝试对拖动事件使用单独的模拟,该模拟仅使用链接力和碰撞力 - 因为节点应该与附加到它们的每个节点一起拖动,并且其他未附加的节点应该被推开,但前提是他们发生碰撞。

所以问题是,如何防止其他节点乱飞?

编辑1:我的第一次尝试仅使用第一个模拟对象,但我认为观察到的效果是由d3.forceManyBody由于其排斥力引起的。我尝试使用 distanceMax 限制这种效果,但没有成功。我的第二次尝试是使用单独的d3.forceSimulation,它仅包含与拖动动画相关的力。

最佳答案

拖动功能的forceCollide似乎是问题所在......

尝试:

    .force("collide", d3.forceCollide(20).radius(20).strength(0))

然后你会得到相反的问题,然后在0和1之间尝试,找到一个你喜欢的。

关于javascript - 使用拖动行为时,具有链接力的 D3.js v4 力布局会导致奇怪的移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45297356/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com