Maintain force simulation on mouseover change

Hi, I made this notebook (Force Simulation / fiorins / Observable) and I’d like to add an effect like this (https://stamen.com) on mouseover on a circle. With mouseover I modify radius size of the circle but force simulation doesn’t work idk why, could you help me ?

I’ve sent you a suggestion here.

1 Like

Thank you @Fil you are awesome ! As you may have guessed, I’m new in d3, anyway I’m seeing the code and I have few questions:

  • what’s the difference of your .join(“circle”) instead .enter().append(“circle”)
  • is event parameter (in node.on(pointerenter) and node.on(pointerout) mandatory or can it be removed?

selection.join is a simpler pattern, but there is no fundamental difference selection.join / D3 / Observable

event is now the first parameter of all the event listeners, see D3 6.0 migration guide / D3 / Observable for details.

Ok, is simulation.on(“tick”, …) triggered by simulation.tick() and executes code after it, right ?

So into the handler .on(eventName, …) besides simples events by JS [https://developer.mozilla.org/en-US/docs/Web/Event] I could also use all of these simulation.function() by d3 [d3-force/README.md at main · d3/d3-force · GitHub] just like my ‘tick’ explanation that I wrote above ?

Furthermore with your code into pointerenter and pointerout how can I manage duration of transition like it was with mine .duration(350) for example ?

Also my curiosity, what do you mean by naming the variable d.t ? Did you choose a random letter or is it an abbreviation for a part of the circle ?

Thank you for all your help, I’m learning a lot.

In my version t is a value that goes from 0 to 1 to interpolate between “normal sized“ (0) and “mouseover sized” (0).

We can’t rely on a duration because the mouse might exit the circle before the 350ms, and the circle should in that case start shrinking immediately (it’s possible to interrupt transitions, but I find it easier to reason with an interpolate t that belongs to each circle, and that is “pushed towards 1” when the circle is hovered, and “pushed towards 0" if not hovered.

The “pushing” is done with the t = 0.99*t in one direction, and t = 1-(1-t)*0.99 in the other direction. (Here an alternative is to split the time interval into n equal parts, and use only additions or substractions.)

The duration of the transition with my system is number of steps it takes for the exponential (t = 0.99^n) to reach “immobility”, which is not really zero of course. You can use 0.993 to make it slower, or 0.985 to make it faster—now that you mention it, maybe I should rewrite it as an addition, it would be simpler to reason about than this exponential growth/decay :slight_smile:

(I’ve also tried to make the target radius equal to 50 in all cases, but a circle that shrinks when hovered is really awkward, since it tends to “flee the mouse”— so instead I make all the circles grow.)

Hope this helps.

1 Like

Would shrinking the circle with the cursor as origin work?

Thank you, yeah this is a lot of help! I used the value 50 as a minimum size, in my original plans it was to bring the circles to 50 if they were smaller and leave those larger than 50 at their value, and now I should be managed to add this feature, seems it works, even if there is a strange behaviour with Japan circle for example, in fact at first time it enlarge but not resize at its starting point