【问题标题】:Handling image map clicks in a Shiny app在 Shiny 应用程序中处理图像地图点击
【发布时间】:2018-07-25 18:00:02
【问题描述】:

我正在构建一个闪亮的应用程序,其中selectInput 功能将作为传统的 HTML 选择下拉菜单和可点击的图像映射呈现。我当前的策略是将图像映射多边形链接回应用程序并添加 URL 参数,解析该 URL,然后更新选择。这当然每次都会重置应用,还可以但不是很好,而且UI闪烁也不是很优雅。

我的问题是:

  • 是否有更好的方法来捕获图像点击并更新输入?
  • 如果我继续我的解决方案,我是否可以延迟 selectInput 上的呈现,以便在解析 URL 之后才会显示它,以便在闪烁到参数化之前它暂时不显示默认选择选择?

这是一个演示:

library(shiny)
ui <- fluidPage(
   sidebarLayout(
      sidebarPanel(
         selectInput("letter_select",
                     "Pick a letter:",
                     choices = c('A' = 1, 'B' = 2, 'C' = 3, 'D' = 4))
      ),
      mainPanel(
         h3('Or click a letter'),
         img(src = 'testpattern.png', usemap = '#image-map'),
         HTML('
<map name="image-map">
<area target="_self" title="A" href="?letter=1" coords=0,0,50,0,50,50,0,50" shape="poly">
<area target="_self" title="B" href="?letter=2" coords=50,0,100,0,100,50,50,50" shape="poly">
<area target="_self" title="C" href="?letter=3" coords=0,50,50,50,50,100,0,100" shape="poly">
<area target="_self" title="D" href="?letter=4" coords=50,50,100,50,100,100,50,100" shape="poly">
</map>
              ')
      )
   )
)

server <- function(input, output, session) {
  observe({
    query <- parseQueryString(session$clientData$url_search)
    if (!is.null(query[['letter']])) {
      updateSelectInput(session, 'letter_select', selected = query[['letter']])
    }
  })
}

shinyApp(ui = ui, server = server)

图片位于 `www/testpattern.png',如下所示。

【问题讨论】:

    标签: r shiny imagemap


    【解决方案1】:

    在整个页面重新加载时很难维护状态并防止闪烁。最好的解决方法可能是在 javascript 中捕获事件并更新应用程序状态。接下来是一个非常粗略的概念证明,说明它是如何工作的。首先,我们抽象出图像映射的概念

    imageMap <- function(inputId, imgsrc, opts) {
      areas <- lapply(names(opts), function(n) 
        shiny::tags$area(title=n, coords=opts[[n]], 
                         href="#", shape="poly"))
      js <- paste0("$(document).on('click', 'map area', function(evt) {
      evt.preventDefault();
      var val = evt.target.title;
      Shiny.onInputChange('", inputId, "', val);})")
      list(
        shiny::tags$img(src=imgsrc, usemap=paste0("#", inputId),
        shiny::tags$head(tags$script(shiny::HTML(js)))),
        shiny::tags$map(name=inputId, areas))
    }
    

    这将从我们传入的 URL 和选项列表中呈现图像和地图数据。我们添加了一些 javascript 来捕获图像地图上的点击事件。例如

    imgsrc <- "https://i.stack.imgur.com/C5aoV.png"
    mapopts <- list(A="0,0,50,0,50,50,0,50",
      B="50,0,100,0,100,50,50,50",
      C="0,50,50,50,50,100,0,100",
      D ="50,50,100,50,100,100,50,100")
    imageMap("map1", imgsrc, mapopts)
    

    我们可以在我们的 UI 中使用它

    ui <- fluidPage(
      sidebarLayout(
        sidebarPanel(
          selectInput("letter_select",
                      "Pick a letter:",
                      choices = c('A', 'B', 'C', 'D'))
        ),
        mainPanel(
          h3('Or click a letter'),
          imageMap("map1", imgsrc , mapopts)
        )
      )
    )
    

    现在我们可以在服务器上监听事件,并更改选择输入

    server <- function(input, output, session) {
      observeEvent(input$map1,  {
        updateSelectInput(session, "letter_select", selected=input$map1)
      })  
    }
    

    现在你可以运行了

    shinyApp(ui = ui, server = server)
    

    你会看到,当你点击图片中的字母时,选择输入的值会随之改变。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    相关资源
    最近更新 更多