# 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)
})
}
)