Shiny.onInputChange is suppressing replicate keypress keys

339 views
Skip to first unread message

Jerry Black

unread,
Nov 6, 2015, 9:46:27 AM11/6/15
to Shiny - Web Framework for R
I would like to add keystroke manipulation of shiny plots to support zooming.

It appears to me that while javascript is handling replicate keys (i.e. pressing the '+' key repeatedly without other intervening keys) Shiny.onInputChange suppresses the successive keystrokes.

# shiny-plot-keyboard-interaction-bug  
# save this script as app.R
# Try to use keyboard to control zoom level on a plot
# when the '+' key is pressed the map is zoomed in correctly
# when the '-' key is pressed the map is zoomed out correctly
# while the keypress javascript handles all key strokes [tested with alert()],
# repeated pressing of any key is SUPPRESSED in Shiny.onInputChange
#    (a bug? that can't be worked around)
# You have to press any other key e.g. '0' between '+' keys to have the
# plot zoom repeatedly


  zoom_in
= 43  # '+' on MacBook US keyboard
  zoom_out
= 95 # '-' on MacBook US keyboard
  zoom_level
= 0.0


shinyApp
(
  ui
= fluidPage(
    tags$script
('
    $(document).on("keypress", function (e) {
            Shiny.onInputChange("key_press", e.which);
            // alert("key_press" + e.which)
            });
            '
),
    fluidRow
(
      column
(width = 6,
             uiOutput
("plotui")
     
)
   
),
    fluidRow
(
      column
(width = 3,
             verbatimTextOutput
("plot_keyinfo")
     
)
   
)
 
),
 
  server
= function(input, output, session) {
    output$plotui
<- renderUI({
      plotOutput
("plot", height=300)
   
})
    output$plot
<- renderPlot({
     
print("renderPlot")
      xvals
<- seq(1:10)
      yvals
<- seq(1:10)
     
print(paste("key_press",input$key_press))
      key_press
<- input$key_press
     
if (is.null(key_press)) key_press <- 0
     
if (key_press == zoom_in) {
        zoom_level
<<- zoom_level + 0.1;
     
} else
       
if (key_press == zoom_out) {
          zoom_level
<<- zoom_level - 0.1;
     
}
     
print(paste("zoom_level",zoom_level))
      xmin
<- min(xvals); xmax <- max(xvals); xrange <- xmax - xmin
      ymin
<- min(yvals); ymax <- max(yvals); yrange <- ymax - ymin
      xlim
=c(xmin + xrange*zoom_level, xmax - xrange*zoom_level)
      ylim
=c(ymin + yrange*zoom_level, ymax - yrange*zoom_level)
      plot
(xvals,yvals,xlab="x",ylab="y",xlim=xlim,ylim=ylim,
           xaxs
="r",yaxs="r",axes=TRUE)
     
   
})
   
    output$plot_keyinfo
<- renderPrint({
      cat
("input$key_press:\n")
      str
(input$key_press)
   
})
   
 
}
)





Dean Attali

unread,
Nov 8, 2015, 1:28:35 AM11/8/15
to Shiny - Web Framework for R
I think what's happening is not that shiny is "suppressing" the keypress events, but the way reactivity works in shiny means that things don't get triggered if the reactive hasn't changed. In you case, you're setting the "key_press" input to a specific key, so whenever that key changes, shiny triggers a reactive event. But if the JavaScript layer tells shiny "the 'g' key was pressed" and on shiny's end "g" is already the value of that variable, then it doesn't do anything.

So it makes sense why this is happening, but I agree that it'd be nice to be able to force shiny to not ignore even when the value is the same. I have an open issue on shiny on github for this https://github.com/rstudio/shiny/issues/928 
Reply all
Reply to author
Forward
0 new messages