繁体   English   中英

如何使d3.js强制布局重力矩形?

[英]How to make d3.js force layout gravity rectangular?

在d3.js强制布局中,给出重力值使布局呈圆形。

在此输入图像描述 但是,我想使力布局成矩形,而节点具有负电荷甚至距离 (如上)

有没有办法让力矩布局?

我可以通过修改tick函数来实现吗?

这是我的代码:

 var background = d3.select('.background'); var width = background.node().getBoundingClientRect().width, height = background.node().getBoundingClientRect().height; var nodes = d3.range(50).map(function(d, i) { return { text: "Hello" }; }); var messages = background.selectAll('.message') .data(nodes) .enter() .append('div') .attr('class', 'message') .text(d => d.text) .each(function(d, i) { d.width = this.getBoundingClientRect().width; d.height = this.getBoundingClientRect().height; }); var force = d3.layout.force() .gravity(1/88) .charge(-50) .nodes(nodes) .size([width, height]); messages.call(force.drag); force.on('tick', function(e) { messages.each(d => { dx = Math.max(0, Math.min(width - d.width, dx)); dy = Math.max(0, Math.min(height - d.height, dy)); }); messages.style('left', d => `${dx}px`) .style('top', d => `${dy}px`); }); force.start(); 
 body { padding: 0; margin: 0; } .background { width: 100%; height: 100vh; border: 1px solid #007aff; } .message { display: inline-block; font-family: sans-serif; border-radius: 100vh; color: white; padding: 10px; background-color: #007aff; position: absolute; } .boundary { display: inline-block; width: 10px; height: 10px; background-color: red; position: absolute; } 
 <script src="https://d3js.org/d3.v3.min.js"></script> <body> <div class="background"> </div> </body> 

好了,编辑3:在d3v4中, forceCollide可以用来设置节点之间的最小距离,如果你然后使用正强度,这会将节点拉到一起,帮助它们设置一个均匀的距离(尽管它看起来比圆形更好) ):

var force = d3.forceSimulation(nodes)
.force("charge", d3.forceManyBody().strength(-10))
.force("collide", d3.forceCollide(30).strength(1).iterations(1))
.force('x', d3.forceX(width/2).strength(0.5))
.force('y', d3.forceY(height/2).strength(10));

假设节点位于矩形svg中,将它们限制在SVG的中心可以帮助均匀化边缘:

position.nodes(nodes).on('tick', function ticks() {
        nodes.attr("cx", function(d) {
            return d.x = Math.max(20, Math.min(width + 20, d.x))
        }).attr("cy", function(d) {
            return d.y = Math.max(20, Math.min(height + 20, d.y));
        })
    });

并且利用力量力量可以帮助沿着y轴绘制它们:

var position = d3.forceSimulation(nodes).force("charge", d3.forceManyBody())
.force('x', d3.forceX(width/2).strength(1))
.force('y', d3.forceY(height/2).strength(5));

在这里小提琴

似乎v4中的力量比v3更加可定制,我认为forceCollide将一些变通方法集成到库中。 因此,您可以尝试找到v3解决方法,或者考虑升级到v4。

在第3节中,我玩重力,充电和限制x和y以保持盒子中的节点更好, 在这里摆弄。 但是我对v3的了解还不够多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM