Skip to content

Commit 864c3e9

Browse files
committed
Fix a bug in link strength scaling.
There was a bug in the previous fix to increase the stability of link relaxation; the strength of a link would decrease relative to the link degree of the connected nodes. Instead of decreasing link strength, we should instead bias the relaxation so that the lighter node moves more than the heavier node, while preserving the strength of the link.
1 parent cd135d5 commit 864c3e9

4 files changed

Lines changed: 23 additions & 20 deletions

File tree

d3.layout.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ d3.layout.force = function() {
256256
s, // current source
257257
t, // current target
258258
l, // current distance
259+
k, // current force
259260
x, // x-distance
260261
y; // y-distance
261262

@@ -270,30 +271,30 @@ d3.layout.force = function() {
270271
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
271272
x *= l;
272273
y *= l;
273-
t.x -= x / t.weight;
274-
t.y -= y / t.weight;
275-
s.x += x / s.weight;
276-
s.y += y / s.weight;
274+
t.x -= x * (k = s.weight / (t.weight + s.weight));
275+
t.y -= y * k;
276+
s.x += x * (k = 1 - k);
277+
s.y += y * k;
277278
}
278279
}
279280

280281
// apply gravity forces
281-
var kg = alpha * gravity;
282+
k = alpha * gravity;
282283
x = size[0] / 2;
283284
y = size[1] / 2;
284285
i = -1; while (++i < n) {
285286
o = nodes[i];
286-
o.x += (x - o.x) * kg;
287-
o.y += (y - o.y) * kg;
287+
o.x += (x - o.x) * k;
288+
o.y += (y - o.y) * k;
288289
}
289290

290291
// compute quadtree center of mass
291292
d3_layout_forceAccumulate(q);
292293

293294
// apply charge forces
294-
var kc = alpha * charge;
295+
k = alpha * charge;
295296
i = -1; while (++i < n) {
296-
q.visit(repulse(nodes[i], kc));
297+
q.visit(repulse(nodes[i], k));
297298
}
298299

299300
// position verlet integration

d3.layout.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/force/force.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ var vis = d3.select("#chart")
99

1010
d3.json("miserables.json", function(json) {
1111
var force = d3.layout.force()
12-
.charge(-60)
12+
.charge(-120)
13+
.linkDistance(30)
1314
.nodes(json.nodes)
1415
.links(json.links)
1516
.size([w, h])

src/layout/force.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ d3.layout.force = function() {
5050
s, // current source
5151
t, // current target
5252
l, // current distance
53+
k, // current force
5354
x, // x-distance
5455
y; // y-distance
5556

@@ -64,30 +65,30 @@ d3.layout.force = function() {
6465
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
6566
x *= l;
6667
y *= l;
67-
t.x -= x / t.weight;
68-
t.y -= y / t.weight;
69-
s.x += x / s.weight;
70-
s.y += y / s.weight;
68+
t.x -= x * (k = s.weight / (t.weight + s.weight));
69+
t.y -= y * k;
70+
s.x += x * (k = 1 - k);
71+
s.y += y * k;
7172
}
7273
}
7374

7475
// apply gravity forces
75-
var kg = alpha * gravity;
76+
k = alpha * gravity;
7677
x = size[0] / 2;
7778
y = size[1] / 2;
7879
i = -1; while (++i < n) {
7980
o = nodes[i];
80-
o.x += (x - o.x) * kg;
81-
o.y += (y - o.y) * kg;
81+
o.x += (x - o.x) * k;
82+
o.y += (y - o.y) * k;
8283
}
8384

8485
// compute quadtree center of mass
8586
d3_layout_forceAccumulate(q);
8687

8788
// apply charge forces
88-
var kc = alpha * charge;
89+
k = alpha * charge;
8990
i = -1; while (++i < n) {
90-
q.visit(repulse(nodes[i], kc));
91+
q.visit(repulse(nodes[i], k));
9192
}
9293

9394
// position verlet integration

0 commit comments

Comments
 (0)