Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny node reactivity dependency tree

I have started to maintain an Rshiny package of ~3000 code lines. I would like to get an overview of what is triggering what in the server.R file.

Is there by chance a neat way to generate a reactivity trigger dependency chart?

like image 863
Soren Havelund Welling Avatar asked Apr 27 '17 12:04

Soren Havelund Welling


3 Answers

This might be interesting to you: https://www.r-bloggers.com/announcing-shinytester-a-package-that-helps-you-build-shiny-apps/

It introduces a library called shinyTester with the function ShinyHierarchy(). For an example from that article see the picture below. enter image description here

like image 119
Tonio Liebrand Avatar answered Oct 19 '22 23:10

Tonio Liebrand


There is a shiny "reactive log visualizer" built into shiny. It builds up a graph incrementally that shows how the various reactive nodes depend on each other. Its output after a run looks like this:

enter image description here

Instructions on using this tool can be found here:Reactive Log Visualizer

These are my notes on this tool:

  • It is enabled with the line options(shiny.reactlog = TRUE) inserted before the shinyApp call
  • It causes a log to be recorded of how the nodes activate each other.
  • The log visualizer can then be enabled with Ctrl-F3 (or Command-F3 on Apple)
  • There is a node layouter that can be manually overridden. It can be challenging when a lot of nodes are displayed to keep the lines from crossing each other.
  • You can then move back in forth in the log (basically you are moving in time in the log) with the arrow keys.
  • The reactive symbols are explained here: Shiny Reactivity Overview
  • It exposes a lot of reactive activity that is invisible to the user so it can be confusing.
  • It does not work well on large Shiny applications - many aspects of this tool simply do not scale.
like image 21
Mike Wise Avatar answered Oct 19 '22 22:10

Mike Wise


The reactive log visualizer is a powerful tool, but unfortunately doesn't scale well with larger apps as @Mike Wise noted. A while ago I read some interesting ideas for improving the debugging experience in rstudio/shiny#1846 and rstudio/shiny#1532, and started exploring ways to implement them.

After stumbling a bit here and there (summary), I found that the best way to do this was to parse the raw reactive log and construct a dependency graph from it.

Package at https://github.com/glin/reactlog. The two main features are:

Showing the call stack that triggered invalidation

observe({
  reactlog::traceInvalidation()
  rx()
})
4: observe({
       reactlog::traceInvalidation()
       rx()
   })
3: rx [<text>#7]
2: val =>  num 10
1: observe(val(10))

and listing reactive dependencies in a tree view

observe({
  reactlog::listDependencies()
  rxA() + rxB() + rxAB()
}, label = "obs")
obs*
+-- rxA*
| `-- valA*
+-- rxB
| `-- valB
`-- rxAB*
  +-- valA*
  `-- valB

A tree view might be particularly useful to see if multiple dependencies were invalidated (asterisks denote invalidation or change).

like image 32
greg L Avatar answered Oct 20 '22 00:10

greg L