r语言 - 在 Rshiny 交互式绘图中放置重置按钮



我想在交互式绘图闪亮应用程序中添加一个重置按钮。该应用程序执行以下操作:在鼠标单击时捕获鼠标的位置,在该位置上绘制一个红点,并用蓝线连接所有先前的位置。如果按下重置按钮,则应删除所有红点和蓝线,并开始新的绘图过程。但是,实际上,当我单击重置按钮时,最后一个红点仍在绘图区域上。我不确定出了什么问题。谢谢你的帮助。

PS:感谢jcheng5提供剧情鼠标事件!

服务器。R 如下所示:

library(shiny)
N = 30 # sample size
x = sort(runif(N, 0, 10)); y = x + rnorm(N)
xval=NULL
yval=NULL
shinyServer(function(input, output) {
get.coords <- reactive({
    data.frame(x=input$coords$x, y=input$coords$y)
})
actiontype <- reactiveValues()
actiontype$lastAction <- 'draw'
observe({
    if (input$reset != 0) 
        actiontype$lastAction <- 'reset'
})
observe({
    if (input$closepolygon != 0) 
        actiontype$lastAction <- 'closepolygon'
})
output$diagPlot = renderPlot({
    plot(x, y, xlim = range(x), ylim = range(y))
    grid()
    if (identical(actiontype$lastAction, 'reset')) {
        xval <<- NULL
        yval <<- NULL
        actiontype$lastAction <- 'draw'
    } else if (identical(actiontype$lastAction, 'draw')){
        temp <- get.coords()
        xval <<- c(xval,temp$x)
        yval <<- c(yval,temp$y)
        points(xval, yval, pch = 19, col = 'red', cex = 1.5)
        for (i in 1:(length(xval)-1))
             lines(c(xval[i],xval[i+1]),c(yval[i],yval[i+1]),type="l",col="blue")
        if(identical(actiontype$lastAction, 'closepolygon'))
             lines(c(xval[1],xval[length(xval)]),c(yval[1],yval[length(yval)]),type="l",col="blue")         
    }
}, width = 700, height = 600)
})

和 ui。R

library(shiny)
shinyUI(pageWithSidebar(
headerPanel('iPED: The interactive ChIP-PED analysis platform'),
sidebarPanel(
    helpText("graph"),
    actionButton('closepolygon', 'Close the Polygon'),
    actionButton('reset', 'Reset')
),
mainPanel(
    plotOutput('diagPlot', clickId="coords", height="auto", width="100%")
)
))

问题是,当您测试actiontype$lastAction是否'reset'时,您会立即将actiontype$lastAction设置为'draw',因此,您输入创建temp并最终绘制的else部分。即使您将xvalyval设置为 NULL ,上次单击时input$coords仍然存在。因此,解决方案应该在于 "重置"input$coords .

经过许多不同的尝试(例如,将input$coords设置为NULL等),我想出了以下内容(无论我在哪里更改,我都会用注释指出):

#server.R
library(shiny)
N = 30
x = sort(runif(N, 0, 10)); y = x + rnorm(N)
xval=NULL
yval=NULL
checker <- 1 #### CHANGE
shinyServer(function(input, output) {
get.coords <- reactive({
    data.frame(x=input$coords$x, y=input$coords$y)
})
actiontype <- reactiveValues()
actiontype$lastAction <- 'draw'
observe({
    if (input$reset != 0)
        actiontype$lastAction <- 'reset'
})
observe({
    if (input$closepolygon != 0)
        actiontype$lastAction <- 'closepolygon'
})
output$diagPlot = renderPlot({
    plot(x, y, xlim = range(x), ylim = range(y))
    grid()
    if (identical(actiontype$lastAction, 'reset')) {
        xval <<- NULL
        yval <<- NULL
        checker <<- 0 ####CHANGE
        actiontype$lastAction <- 'draw'
    } else if (identical(actiontype$lastAction, 'draw')){
        temp <- get.coords()
        xval <<- c(xval,temp$x)
        yval <<- c(yval,temp$y)
        ########### CHANGE...
        if(identical(checker, 0))
         {
           points(xval, yval, pch = 19, col = rgb(1,0,0,0), cex = 1.5)
           xval <<- NULL
           yval <<- NULL
           checker <<- 1
         }else
         {
          points(xval, yval, pch = 19, col = 'red', cex = 1.5)
         }
        ############# ...CHANGE
        for (i in 1:(length(xval)-1))
             lines(c(xval[i],xval[i+1]),c(yval[i],yval[i+1]),type="l",col="blue")
        if(identical(actiontype$lastAction, 'closepolygon'))
       lines(c(xval[1],xval[length(xval)]),c(yval[1],yval[length(yval)]),
              type="l",col="blue")
    }
}, width = 700, height = 600)
})

我想到的是实际绘制最后存储的input$coords但具有 100% 的透明度,并且还删除了上次单击的input$coords .checker的作用是在10之间波动,并做到这一点。

这可能更容易实现,但我现在想不出更清晰的方法。

您的最后一个点没有消失的原因是,一旦点击,它就会一直存在,直到它被新点击的数据所取代。 据我所知,此功能无法修改。 但是处理这些数据的方式可以。

事实证明,clickID 实际上将 3 个数值(而不仅仅是 2 个)发送回 Shiny 会话:x、y 和一个唯一标识符双精度。我发现解决方案实际上在于充分利用第三个标识符。 我存储在一个 reactiveValue 对象中,我们称之为"reactive$uniqueIdentifier",该标识符只更新了第二个 reactiveValue 对象,我们称之为"reactive$clickedCoordinates",当新的 clickID 的标识符与以前的不同时,使用 clickID 坐标。 然后,我使用 reactive$clickedT坐标作为我要绘制的点的坐标。 然后,当我想重置单击的坐标并取消绘制所有内容时,我只需将 reactive$clickedT坐标的值设置为 NULL。 这使得所有标绘点都消失了! :-)

最新更新