D3.js静态力布局不适用于路径?



我试图将此示例更改为使用路径而不是行 https://bl.ocks.org/mbostock/1667139,但它不起作用。 我尝试使用自己的tick函数,如下所示:

function tick() {
link.attr("d", function(d) {
var x1 = d.source.x,
y1 = d.source.y,
x2 = d.target.x,
y2 = d.target.y,
dx = x2 - x1,
dy = y2 - y1,
dr = Math.sqrt(dx * dx + dy * dy),
// z uzla do ineho uzla
drx = dr,
dry = dr,
xRotation = 0,
largeArc = 0,
sweep = 1;
//do sameho seba
if ( x1 === x2 && y1 === y2 ) {
xRotation = -45;
largeArc = 1;
drx = 30;
dry = 30;
x2 = x2 + 1;
y2 = y2 + 1;
}
return "M" + x1 + "," + y1 + "A" + drx + "," + dry + " " + xRotation + "," + largeArc + "," + sweep + " " + x2 + "," + y2;
});     
}

我不知道,如果我错过了什么或静态力布局就不能使用路径。 路径正常工作的强制布局

从文档中(粗体我的):

simulation.tick()

将当前 alpha 递增 (alphaTarget - alpha) × alphaDecay; 然后调用每个注册的力,传递新的阿尔法;然后 通过速度递减每个节点的速度×速度衰减;最后 按速度递增每个节点的位置。

此方法不调度事件;事件仅由 模拟自动启动时的内部计时器 创建或通过调用 Simulation.Restart。刻度的自然数 模拟开始时为 ⌈log(alphamin)/log(1 - 阿尔法衰变)⌉;默认情况下,此值为 300。

此方法可以与 simulation.stop 结合使用以计算 静态力布局。对于大型图形,静态布局应为 在 Web 辅助角色中计算以避免冻结用户界面。

由于它不调度事件,因此永远不会调用或使用tick函数。 相反,只需替换该行并设置一次路径:

<!DOCTYPE html>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var n = 100,
nodes = d3.range(n).map(function(i) {
return {
index: i
};
}),
links = d3.range(n).map(function(i) {
return {
source: i,
target: (i + 3) % n
};
});
var simulation = d3.forceSimulation(nodes)
.force("charge", d3.forceManyBody().strength(-80))
.force("link", d3.forceLink(links).distance(20).strength(1).iterations(10))
.force("x", d3.forceX())
.force("y", d3.forceY())
.stop();
var loading = svg.append("text")
.attr("dy", "0.35em")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.text("Simulating. One moment please…");
// Use a timeout to allow the rest of the page to load first.
d3.timeout(function() {
loading.remove();
// See https://github.com/d3/d3-force/blob/master/README.md#simulation_tick
for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
simulation.tick();
}
g.append("g")
.attr("stroke", "#000")
.attr("stroke-width", 1.5)
.selectAll("line")
.data(links)
.enter().append("path")
.attr("d", function(d) {
var x1 = d.source.x,
y1 = d.source.y,
x2 = d.target.x,
y2 = d.target.y,
dx = x2 - x1,
dy = y2 - y1,
dr = Math.sqrt(dx * dx + dy * dy),
// z uzla do ineho uzla
drx = dr,
dry = dr,
xRotation = 0,
largeArc = 0,
sweep = 1;
//do sameho seba
if (x1 === x2 && y1 === y2) {
xRotation = -45;
largeArc = 1;
drx = 30;
dry = 30;
x2 = x2 + 1;
y2 = y2 + 1;
}
return "M" + x1 + "," + y1 + "A" + drx + "," + dry + " " + xRotation + "," + largeArc + "," + sweep + " " + x2 + "," + y2;
});
g.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", 4.5);
});
</script>

对评论的回应:

要将圆圈和文本附加为"节点",我将创建一个g,定位它,然后将圆圈和文本放入其中:

var g = node
.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("transform", function(d){
return "translate(" + d.x + "," + d.y + ")";
});
g.append("circle")
.attr("class", "node")
.attr("stroke", "#fff")
.attr("r", 28);
g.append("text")
.text("test");

最新更新