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毫秒处理单击,则必须为此设置某种计时器。@达塔利:你找到解决办法了吗?我很想看看。没有,我得到的官方答案是(至少目前)没有办法。我最后用双击代替了单击