Search code examples
rshinyc3.js

`c3` package does not work with reactivity in a shinyApp


I'm trying to use a reactive object inside the c3 package graphics in a shinyApp.

However, the graph is not produced by the server.

See the code I used:

library(shiny)

ui <- fluidPage(

  shinyjs::useShinyjs(),
  
  column(
    
    width = 12,
    
    actionButton(
      inputId = "dbtn1",
      label = "Click me!"
    ),
    
    sliderInput(
      inputId = "id1",
      label = "Choose 1",
      value = 5,
      min = 1, 
      max = 10, 
      step = 1
    ),
    
    sliderInput(
      inputId = "id2",
      label = "Choose 2",
      value = 5,
      min = 1, 
      max = 10, 
      step = 1
    )
    
  ),
  
  c3::c3Output(outputId = "dsgraph")
  
)

server <- function(input, output, session) {
  
  reac1 <- reactive({
    
    fx <- function(x, y) {
      
      x + y
      
    }
    
    fx(
      x = input$id1,
      y = input$id2
    )
    
  })
  
  output$dsgraph <- c3::renderC3({
    
    req(input$dbtn1)
    
    isolate(expr = q1 <- reac1())
    isolate(expr = q2 <- reac1())
    
    data.frame(Before = q1, After = q2) %>%
      c3::c3() %>%
      c3::c3_donut(title = "Show donut")
  })
  
}

shinyApp(ui, server)

If however, I put absolute values, something like:

  output$dsgraph <- c3::renderC3({
    
    req(input$dbtn1)
    
    data.frame(Before = 20, After = 80) %>%
      c3::c3() %>%
      c3::c3_donut(title = "Show donut")

  }) 

Works fine.

It also seems to me that the actionButton, after being pressed for the first time, loses its click effect...

EDIT

I added the following code to the server to try to get the actionButton working, but it didn't work:

  observeEvent(input$dbtn1, {

    shinyjs::reset("dbtn1")

  })

I also tried something like:

  vals <- reactiveValues(clicks = 0)

  observeEvent(input$dbtn1, {
    vals$clicks <- vals$clicks + 1
  })

Solution

  • That is strange: the reason is that q1 and q2 are integers. If you convert them to double, then it works:

    data.frame(Before = as.double(q1), After = as.double(q2)) %>%
          c3::c3() %>%
          c3::c3_donut(title = "Show donut")
    

    The button does not lose its effect. But once it is pressed then its value is >0 and the req always allows this value.