christophergandrud / networkD3

D3 JavaScript Network Graphs from R
http://christophergandrud.github.io/networkD3
649 stars 270 forks source link

Freeze Force Network #290

Closed higor-gomes93 closed 2 years ago

higor-gomes93 commented 2 years ago

Hi!

Is there any way to stop the animation from the ForceNetwork()?

Here is part of my code:

p <- forceNetwork(Links = links, Nodes = nodes, Source = 'source', Target = 'target', NodeID = 'name', Group = 'group', Value = "value", Nodesize = "size", radiusCalculation = JS("d.nodesize"), zoom = TRUE, arrows = FALSE, linkWidth = JS("function(d){return d.value;}"), linkDistance = JS("function(d){return d.value*10}"), charge = gravity, opacity = 0.95, fontSize = 24, linkColour = "#424242" )

customJS <- "function() { d3.selectAll('.node text').style('fill', 'white').attr('stroke-width', '.1px').attr('stroke', '#3f3f3f'); d3.select('body').style('background-color', '#15171a'); }"

g <- htmlwidgets::onRender(p, customJS) g

cjyetman commented 2 years ago

When do you want to stop it and for how long?

higor-gomes93 commented 2 years ago

It would be great to have no animation at all, just plot the static network. The animation is taking a huge performance toll, since I have 2k nodes and 1M connections.

cjyetman commented 2 years ago

If you don't want to run the animation at all, you can do this (below), but it's not going to be very useful because the animation is what achieves a nice looking output... without it all the nodes begin in the same place in the top left corner...

library(networkD3)

p <-
  forceNetwork(
    Links = MisLinks,
    Nodes = MisNodes,
    Source = "source",
    Target = "target",
    Value = "value",
    NodeID = "name",
    Group = "group",
    opacity = 0.4,
    zoom = TRUE
  )

customJS <- "
  function() {
    this.stop();
  }
"

htmlwidgets::onRender(p, customJS)
cjyetman commented 2 years ago

maybe this could help... you could stop the simulation, run forward through the ticks without updating the positions (effectively the "animation"), and then restart the simulation so the nodes' positions are updated...

library(networkD3)

p <-
  forceNetwork(
    Links = MisLinks,
    Nodes = MisNodes,
    Source = "source",
    Target = "target",
    Value = "value",
    NodeID = "name",
    Group = "group",
    opacity = 0.4,
    zoom = TRUE
  )

customJS <- '
  function() {
    simulation = this;
    simulation.stop();
    for (var i = 0; i < 300; ++i) simulation.tick();
    simulation.nodes().forEach( function(d,i) {
      d.cx = d.x;
      d.cy = d.y;
    });
    simulation.restart();
  }
'

htmlwidgets::onRender(p, customJS)
higor-gomes93 commented 2 years ago

That last snippet was everything I needed! Thank you very much, @cjyetman!

cjyetman commented 2 years ago

FYI... in this new package I've been working on, you can achieve this like this...

library(network.r2d3)
url <- "https://gist.githubusercontent.com/mbostock/ad70335eeef6d167bc36fd3c04378048/raw/df541a01e850c6073ece4516fcd74ea1bae080ab/miserables.json"
force_network(url, plot_static = TRUE)

although it's also using canvas by default, rather than SVG, which means it can handle a lot more data, so even the animation might work

higor-gomes93 commented 2 years ago

Awesome, @cjyetman! Is this new package read to go?

cjyetman commented 2 years ago

no, not at all.... it's in a very alpha state... and when I will have time to work on it is very uncertain at the moment (busy times with work I get paid for)

higor-gomes93 commented 2 years ago

Fair enough. I wish I had the expertise and ask to join this projetct, but I am only a data analyst who loves python lol. Let me know if I can be of any help, and thank you very much for your help!

Btw, any clues on how to set a standard zoom with that last snippet that you sent me?