[英]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.