Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R ggplot2:如何区分单击和笔刷?_R_Ggplot2_Shiny - Fatal编程技术网

R ggplot2:如何区分单击和笔刷?

R ggplot2:如何区分单击和笔刷?,r,ggplot2,shiny,R,Ggplot2,Shiny,我希望在我闪亮的应用程序中有一个绘图,用户可以单击或选择某些区域,因此我使用了plotOutput的click-and-brush参数。我的问题是,当启动笔刷时,单击处理程序也被调用。我想知道什么时候点击,什么时候画笔,但是如果点击是画笔的一部分,我想忽略它 示例:在下面的应用程序中,如果你只是刷(单击某处并拖动鼠标),你会收到一条“单击”消息和一条“刷”消息。在这种情况下,我只想得到“刷”的信息 library(shiny) library(ggplot2) runApp(shinyApp(

我希望在我闪亮的应用程序中有一个绘图,用户可以单击或选择某些区域,因此我使用了
plotOutput
的click-and-brush参数。我的问题是,当启动笔刷时,单击处理程序也被调用。我想知道什么时候点击,什么时候画笔,但是如果点击是画笔的一部分,我想忽略它

示例:在下面的应用程序中,如果你只是刷(单击某处并拖动鼠标),你会收到一条“单击”消息和一条“刷”消息。在这种情况下,我只想得到“刷”的信息

library(shiny)
library(ggplot2)
runApp(shinyApp(
  ui = fluidPage(
    plotOutput("plot", click = "click", brush = "brush")
  ),
  server = function(input, output, session) {
    output$plot <- renderPlot({
      ggplot(mtcars, aes(wt, mpg)) + geom_point()
    })
    observeEvent(input$click, {
      cat("clicked\n")
    })
    observeEvent(input$brush, {
      cat("brushed\n")
    })
  }
))
库(闪亮)
图书馆(GG2)
runApp(shinyApp)(
ui=fluidPage(
plotOutput(“plot”,click=“click”,brush=“brush”)
),
服务器=功能(输入、输出、会话){

output$plot我知道这只是一个解决方法,但我唯一的解决方案是撤消上次单击时笔刷被激活的动作;我需要这个用于用户可以通过单击添加点的绘图。 使用刷牙将首先创建点,并在释放单击按钮后将其移除。 这只是一个缺点:有时你在没有注意到的情况下点击并使用微刷,在这种情况下,它显然不会创建点。我的应用程序:

library(shiny); library(dplyr); library(ggplot2)

ui <- fluidPage(
     fluidRow(

          h1("add by clicking anywhere on the plot"),
          plotOutput("mainplot",
                     click="mainplot_click",
          brush=brushOpts(id="mainplot_brush"))
     ),
     fluidRow(
          actionButton("add", "add"),
          actionButton("reset", "reset")
     )
)

server <- function(input, output, session) {

     vals = reactiveValues(
          keeprows = rep(TRUE, nrow(mtcars)),
          mydata = mtcars
     )

     observeEvent(input$mainplot_click, handlerExpr = {
          my.x = input$mainplot_click$x
          my.y = input$mainplot_click$y
          vals$mydata <- vals$mydata %>% bind_rows(data.frame("wt"=my.x, "mpg"=my.y))
     })

     output$mainplot = renderPlot({
          temp = vals$mydata
          ggplot() +geom_point(data=temp, col="black", fill="white", size=3) + aes(x=wt, y=mpg)
     })

     observeEvent(input$mainplot_brush, handlerExpr = {
           vals$mydata <- vals$mydata %>% head(-1)
     })

     observeEvent(input$reset, handlerExpr = {
          vals$mydata <- mtcars
          vals$keeprows <- rep(TRUE, nrow(mtcars))
     })
     session$onSessionEnded(stopApp)
}

shinyApp(ui, server)
library(闪亮);library(dplyr);library(ggplot2)

ui我用一组标志解决了这个问题,认识到拖动事件会触发单击(鼠标向下),然后是画笔,然后是第二次单击(实际上是鼠标向上)。我延迟处理第一次单击,然后如果我处理画笔,则取消第一次单击。如果我处理画笔,则我知道将有第二次单击,我应该忽略

single.click.up <- FALSE
single.click.down <- FALSE
brush.click <- FALSE

# Brush events trigger plot1_click twice (down and up) with a brush event in between.
observe({
    input$plot1_click
    if (single.click.down) {
        if (brush.click) {
            single.click.up <<- TRUE
            message("single click down ignored")
        } else {
            message("single click down processed")
        }
        single.click.down <<- FALSE
    } else if (single.click.up) {
        message("single click up, reset brush click")
        brush.click <<- FALSE
        single.click.up <<- FALSE
    } else {
        single.click.down <<- TRUE
        invalidateLater(1000)
        message("new single click. delay.")
    }
})

observeEvent( input$plot1_brush, {
  brush.click <<- TRUE
  message("Processing brush")
})

single.click.up我正在开发一个用于交互式热图()的闪亮应用程序。在热图上,用户可以单击热图查看该单元格的值,或者选择一个区域以捕捉子热图。我也不喜欢双击热图,这对用户来说非常不友好

以下是我区分单击和笔刷的解决方案,可能对您有所帮助:

可运行代码:

库(闪亮)
图书馆(网格)
图书馆(胶水)
库(圆圈)#仅适用于随机颜色
ui=fluidPage(
绘图输出(“绘图”,宽度=600,高度=400,
单击“单击”,刷“刷”),
标记$script(HTML(“
$(“#绘图”).mousedown(函数(e){
var parentOffset=$(this.offset();
var relX=e.pageX-parentOffset.left;
var relen=e.pageY-parentOffset.top;
setInputValue('x1',relX);
设置输入值('y1',依赖);
}).mouseup(函数(e){
var parentOffset=$(this.offset();
var relX=e.pageX-parentOffset.left;
var relen=e.pageY-parentOffset.top;
setInputValue('x2',relX);
设置输入值('y2',依赖);
setInputValue('action',Math.random());
});
")),
fluidRow(
列(3,htmlOutput(“输出1”)),
列(3,htmlOutput(“输出2”))
)
)
服务器=功能(输入、输出、会话){
输出$plot=renderPlot({
grid.newpage()
grid.rect()
})
observeEvent(输入$action{
如果(输入$x1==输入$x2&&input$y1==输入$y2){
输出$output1=renderText({
隔离(胶水)
点击:
x1={input$x1}
y1={input$y1}
x2={input$x2}
y2={input$y2}
input$click$coords\u css$x={input$click$coords\u css$x}
输入$click$coords\u css$y={input$click$coords\u css$y}”))
})
}否则{
输出$output2=renderText({
隔离(胶水)
刷子:
x1={input$x1}
y1={input$y1}
x2={input$x2}
y2={input$y2}
input$brush$coords_css$xmin={input$brush$coords_css$xmin}
input$brush$coords_css$ymin={input$brush$coords_css$ymin}
input$brush$coords_css$xmax={input$brush$coords_css$xmax}
输入$brush$coords\u css$ymax={input$brush$coords\u css$ymax}”))
})
}
})
}
shinyApp(用户界面、服务器)
这里有一个演示:

这个想法是比较鼠标在“mousedown”和“mouseup”的位置。在“mouseup”触发一个反应值(这里是
action
),以便在
server
函数中,它可以响应它。(这是在
标记$script(…)
中实现的)


如图所示,单击并使用笔刷独立更改框颜色,使用笔刷不会影响单击框。

根据
?plotOutput
似乎没有“鼠标按钮向上”消息,您需要正确区分单击和刷洗。一种解决方法是定义超时(例如,200 ms),仅在此超时后才将单击事件视为此类事件,并相应地忽略此超时后的所有笔刷事件。有没有理由不简单地听双击事件?我不希望dblclick仅仅因为用户体验-单击更简单,更有意义。也许我只需要睡觉(上午4:30),但我不确定你的建议将如何解决我的问题,我考虑了一下,它似乎没有解决我的问题。如果笔刷事件在上次单击事件后不到200毫秒发生,则由你处理。如果没有,则忽略它。如果在事件后仅200毫秒处理单击,则必须为此设置某种计时器。@达塔利:你找到解决办法了吗?我很想看看。没有,我得到的官方答案是(至少目前)没有办法。我最后用双击代替了单击