Open princiya opened 6 years ago
I think this is a cool experiment but I actually think a lot of the perf improvements could be improved in the main thread first which I did in #232. I can't remember the line of code but essentially I just reduced the large amount of recalc.
@jonathanKingston
I think, you commented out the manualTick()
and things still looked good. But there are other use cases and now that I understand how alpha
really works, I shall try to explain them below.
simulateForce() {
if (!this.simulation) {
this.simulation = d3.forceSimulation(this.nodes);
this.simulation.on('tick', () => this.drawOnCanvas());
this.registerSimulationForces();
} else {
this.simulation.nodes(this.nodes);
}
this.registerLinkForce();
this.manualTick();
}
d3.forceSimulation(this.nodes)
.alpha
is 1
.tick()
runs from alpha=1
to alpha=0
.alpha=0
.tick()
the graph updates x, y, vx, vy
for each node, by adhering to the registered forces.
x, y, vx, vy
shouldn't result in a collision and this it takes care by making sure the collisionRadius
is applied.The tick function increments the current
alpha
by(alphaTarget – alpha) × alphaDecay
; then invokes each registered force, passing the newalpha
; then decrements each node’s velocity byvelocity × velocityDecay
; lastly increments each node’s position by velocity.
Case 1: Page Load
this.manualTick()
is unnecessary.tick()
runs from alpha=1
to alpha=0
.alpha=0
.Case 2: Add new nodes (alpha
is still not 0
)
tick()
function.Case 3: Add new nodes (alpha
is 0
)
alpha
=0
), and when new nodes come in, then these newly added nodes appear on top left.tick()
function has stopped.tick()
function only runs for alpha
ranging from 1
to 0
.manualTick()
initially.Next Steps:
alpha=0
is to restart the simulation.alpha
in the range [1,0]
and simulation.restart()
.tick()
function will not run if alpha=0
.alpha
and restarting the simulation makes the tick()
function run and we again get the right graph.cc @biancadanforth
Debugging the ALPHA! :)
This is an initial attempt to improve the graph's performance for large no. of nodes.
Issue #232
The idea in this PR is to off-load the heavy force layout computations to the web worker. This improves performance during page load.
I am also experimenting on passing the logic to web workers during the drag events. This part is still work in progress.
Here is the rough idea that I try to achieve:
In the present situation, when we drag, the force layout restarts the simulation. When there are large no. of nodes, the graph takes a lot of time to achieve equilibrium, thereby dropping the frame rates. Restarting the simulation is necessary, to compute the updated coordinates and give the soft transition, else the drag effect doesn't appear smooth.
Using web workers, I try to keep the dragged coordinates in the main thread, invoke the web worker during
dragEnd
. The web worker computes the updated coordinates and waits until the graph attains equilibrium. I need to figure a way to get the updated coordinates and achieve smooth animations.cc @jonathanKingston @biancadanforth