gpt4 book ai didi

javascript - D3js Force Layout barrier 和 fall in

转载 作者:行者123 更新时间:2023-11-28 07:35:57 24 4
gpt4 key购买 nike

我正在做力布局。我已经在 svg 中实现了碰撞和边界(我不想使用重力)。但是,现在我想在中间放置一个 div 并让节点避开它。

我正在尝试的方法是使用绝对位置将 SVG 叠加在 div 之上,并尝试让节点在 tick 函数中避开它。这被证明是非常困难的。还有另一种方法吗?如果没有,我将不胜感激指出正确的方向!

作为次要问题,我希望节点从顶部落入。再一次,我没有引力,所以我不确定如何处理它。我希望他们保持间距,所以我认为焦点可能不起作用。

我附上了我的 Javascript 和 CSS 代码!

提前致谢。

    width = parseInt(d3.select('#canvas').style('width'), 10),
height = parseInt(d3.select('#canvas').style('height'), 10),
padding = 30, // separation between circles
radius = 70;

//Set up the force layout
var force = d3.layout.force()
.gravity(0)
.charge(0)
.size([width, height]);

//Append a SVG to the body of the html page.
//Assign this SVG as an object to svg
var svg = d3.select("#canvas").append("svg")
.attr("width", width)
.attr("height", height);

//Read the data
d3.json("dots.json", function(error, graph) {
if (error) throw error;

//Creates the graph data structure out of the json data
force.nodes(graph.nodes)
.start();


//Do the same with the circles for the nodes - no
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);

node.append("circle")
.attr("r", radius)
.style("fill", "black")
.call(force.drag);

node.append("text")
.attr("dx", 0)
.attr("dy", 5)
.attr("height", 10)
.attr("text-anchor", "middle")
.text(function(d) { return d.name })
.style("fill", "white");


//Now we are giving the SVGs co-ordinates - the force layout
//is generating the co-ordinates which this code is using to
//update the attributes of the SVG elements
force.on("tick", function (e) {

node.attr("cx", function(d) {
return d.x =
Math.max(
radius,
Math.min(
width - radius,
d.x
)
);
}).attr("cy", function(d) {
return d.y = Math.max(radius, Math.min(height - radius, d.y));
});

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });


node.each(collide(0.5)); //Added
});

function collide(alpha) {
var quadtree = d3.geom.quadtree(graph.nodes);
return function(d) {
var rb = 2*radius + padding,
nx1 = d.x - rb,
nx2 = d.x + rb,
ny1 = d.y - rb,
ny2 = d.y + rb;

quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y);
if (l < rb) {
l = (l - rb) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}

node.on("mousedown", function(d1, i) {
var $this = d3.select(this);
if(node.active) {
$this = $this.transition()
.duration(1000)
.attr("stroke-width", 0)
.attr("r", radius);

node.active = false;
} else {
$this = $this.transition()
.duration(1000)
.attr("stroke-width", 20)
.attr("stroke", "4DD2B6")
.attr("fill", "white")
.attr("r", radius * 2)
}
});

});



#canvas, #playground {
width: 100%;
height: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
overflow: visible;
display: block;
}

#playground {
height: 100%;
}

header {
width: 320px;
margin: 100px auto 50px;
display: block;
z-index: 10;
background-color: red;
}

screen

最佳答案

边界

碰撞检测的难点在于每个节点都可能与任何其他节点发生碰撞,这就是为什么使用四叉树来减少排列的原因。当你谈论边界时,它更直接,因为只有一个边界。在您的情况下,您需要做的就是扩展边界的几何形状以包括遮挡。

陷入困境

这完全取决于您的意思,但是您可以将初始 cx/cy 值设置为您希望它们从中发出的源,然后扩展您的边界行为以包括如果节点在 svg 之外时要做什么.因此,这将是某种自定义重力,可以根据当前位置和您希望它们落入的方向确定下一个 cx/cy。同时,碰撞例程不知道边界,因此它将负责保持节点当它们掉落时分开。

关于javascript - D3js Force Layout barrier 和 fall in,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31197742/

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