Javascript D3.js v4+;-如何确定强制搁置中的具体位置

Javascript D3.js v4+;-如何确定强制搁置中的具体位置,javascript,d3.js,dom,svg,Javascript,D3.js,Dom,Svg,其他在线教程/答案是关于D3.js v3.x或可拖动元素的特定位置 我查看了文档,但不完全了解如何操作: 我试图在不改变矩形位置的情况下防止红色矩形与圆形重叠。 我指定了fx和fy,但仍然没有成功 const nodes=d3.range(100.map)(d=>({radius:5,type:“circle”})); const walls=[{},{},{},{}].map(({,索引)=>({ 外汇:200*指数, 财政年度:100, 类型:“墙” })); 常数循环中心=[100300

其他在线教程/答案是关于D3.js v3.x或可拖动元素的特定位置

我查看了文档,但不完全了解如何操作:

我试图在不改变矩形位置的情况下防止红色矩形与圆形重叠。

我指定了
fx
fy
,但仍然没有成功

const nodes=d3.range(100.map)(d=>({radius:5,type:“circle”}));
const walls=[{},{},{},{}].map(({,索引)=>({
外汇:200*指数,
财政年度:100,
类型:“墙”
}));
常数循环中心=[100300500];
d3.力模拟(节点、混凝土(墙))
.force('电荷',d3.forceManyBody().强度(10))
.force('x',d3.forceX().x(函数(d,i){
如果(d.类型==“圆”)
返回循环中心[i%3];
其他的
返回d.fx;
}))
.force('y',d3.forceY().y(100))
.force('collision',d3.forceCollide().radius(d=>d.radius))
.在(‘勾选’)上;
函数勾选(){
d3.选择(“svg”)
.selectAll('rect')
.数据(墙)
.输入()
.append('rect')
.attr('width',100)
.attr('height',10)
.attr('fill','red')
.attr('x',d=>d.x)
.attr('y',d=>d.y);
常量u=d3.select('svg')
.selectAll('圆圈')
.数据(节点);
u、 输入()
.append('圆')
.合并(u)
.attr('填充','蓝色')
.attr('r',d=>d.radius)
.attr('cx',d=>d.x)
.attr('cy',d=>d.y);
}

您需要用正确大小的保护节点填充整个rect

如果您想看到代码中的保护圈取消注释部分

有2个
g
元素,一个包含保护节点,另一个包含
blue
节点

编辑

如果你使X-力更强一点,节点就会更接近实际的中心

.force('x', d3.forceX()
    .x( (d, i) => (d.type === "circle") ? circleCenters[i % 3] : d.fx )
    .strength(0.3))
const nodes=d3.range(100.map)(d=>({radius:5,type:“circle”}));
const walls=[{},{},{},{}].map(({,索引)=>({
外汇:200*指数,
财政年度:100,
宽度:100,
身高:10,
半径:5,
类型:“墙”
}));
常数循环中心=[100300500];
//构造覆盖矩形的“不可见”圆
var=[];
墙。forEach(e=>{
d3.范围(e.fx+3,e.fx+e.width-3,3).forEach(cx=>{
推({
外汇:cx,
fy:e.fy+e.radius,
半径:即半径,
类型:e.type
});
});
});
d3.力模拟(节点、concat(invCircles))
.force('电荷',d3.forceManyBody().强度(10))
.force('x',d3.forceX().x((d,i)=>(d.type==“圆圈”)?圆圈中心[i%3]:d.fx)。强度(0.3))
.force('y',d3.forceY().y(100))
.force('collision',d3.forceCollide().radius(d=>d.radius))
.在(‘勾选’)上;
var wallGeom=d3.select('svg')。append('g')。attr('class','wall');
var circlesgome=d3.select('svg').append('g').attr('class','circles');
wallGeom.selectAll('rect')
.数据(墙)
.输入()
.append('rect')
.attr('width',d=>d.width)
.attr('height',d=>d.height)
.attr('fill','red')
.attr('x',d=>d.fx)
.attr('y',d=>d.fy);
//wallGeom.selectAll('圆')
//.数据(圈)
//.输入()
//.append('圆')
//.attr('填充','黄色')
//.attr('r',d=>d.radius)
//.attr('cx',d=>d.fx)
//.attr('cy',d=>d.fy);
函数勾选(){
常量u=d3.select('svg')
.选择(“.circles”)
.selectAll('圆圈')
.数据(节点);
u、 输入()
.append('圆')
.attr('填充','蓝色')
.attr('r',d=>d.radius)
.合并(u)
.attr('cx',d=>d.x)
.attr('cy',d=>d.y);
}


首先,谢谢。这是一个伟大的解决方案!第二,你确定没有一个解决方案不涉及创造这么多看不见的圆圈吗?我可能需要创建3000多个隐形球。这对浏览器来说不是太多了吗?(我的矩形更宽更高)@StavAlfi当前力引擎没有约束节点的方法。您必须自己使用
tick()
方法或创建大小(角点)不可见圆来填充矩形,不可见节点仅涉及力引擎,可能会减慢速度,但在
ticks()
中使用碰撞检测也不是免费的,使用圆相当快。