Nothing
library(shiny)
library(plotly)
library(dplyr)
library(crosstalk)
ui <- fluidPage(
checkboxInput("persist", "Persistent?", FALSE),
plotlyOutput("p"),
verbatimTextOutput("dat")
)
server <- function(input, output, session) {
# change these variables to customize the app
data_shared <- SharedData$new(mtcars)
color_base <- "black"
color_select <- "red"
var_x <- "wt"
var_y <- "mpg"
data_orig <- data_shared$origData()
output$p <- renderPlotly({
plot_ly(x = data_orig[[var_x]], y = data_orig[[var_y]]) %>%
add_markers(
color = I(color_base),
selected = list(
marker = list(color = color_select)
)
) %>%
layout(
dragmode = "select",
xaxis = list(title = var_x),
yaxis = list(title = var_y)
) %>%
config(
displayModeBar = FALSE,
edits = list(shapePosition = TRUE)
) %>%
toWebGL()
})
# listen to the brushing event and draw a
# rect shape that mimics the brush
observe({
brush <- event_data("plotly_brushing")
# if the brush is undefined, remove all shapes and exit
if (is.null(brush)) {
plotlyProxy("p", session) %>%
plotlyProxyInvoke("relayout", list(shapes = NULL))
return()
}
# mimc the brush as a rect shape
brush_rect <- list(
type = "rect",
x0 = brush$x[1],
x1 = brush$x[2],
y0 = brush$y[1],
y1 = brush$y[2],
fillcolor = NA,
line = list(
color = "black",
dash = "dot",
width = 1
)
)
# draw the rect shape and turn off brush coloring
# imposed by plotly.js
plotlyProxy("p", session) %>%
plotlyProxyInvoke("relayout", list(shapes = list(brush_rect))) %>%
plotlyProxyInvoke("restyle", "selectedpoints", list(list()))
})
# A reactive value that tracks the dimensions of the brush
brush <- reactiveVal()
# Update the brush in response to changes to shapes
# NOTE: if you need more shapes in the plot your brushing,
# you'll need to be mindful of which shape the brush represents
observe({
evt <- event_data("plotly_relayout")
val <- if (!is.null(evt$shapes)) {
evt$shapes
} else if (!is.null(evt[["shapes[0].x0"]])) {
list(
x0 = evt[["shapes[0].x0"]],
x1 = evt[["shapes[0].x1"]],
y0 = evt[["shapes[0].y0"]],
y1 = evt[["shapes[0].y1"]]
)
}
brush(val)
})
# double-click clears the brush
observe({
event_data("plotly_doubleclick", priority = "event")
event_data("plotly_deselect", priority = "event")
brush(NULL)
})
# map the brush limits to a data selection
observe({
# if brush isn't active, no selection is active
if (is.null(brush())) {
data_shared$selection(FALSE)
return()
}
selection <- between(data_orig[[var_x]], brush()$x0, brush()$x1) &
between(data_orig[[var_y]], brush()$y0, brush()$y1)
if (isTRUE(input$persist)) {
selection_old <- data_shared$selection()
# This should be fixed in crosstalk
if (is.null(selection_old)) selection_old <- FALSE
data_shared$selection(selection_old | selection)
} else {
data_shared$selection(selection)
}
})
# update the marker colors
observe({
dat <- data_shared$data(withSelection = TRUE)
color <- if_else(dat$selected_, color_select, color_base)
plotlyProxy("p", session) %>%
plotlyProxyInvoke("restyle", "marker.color", list(color), 0)
})
# display the selected data
output$dat <- renderPrint({
dat <- data_shared$data(withSelection = TRUE)
filter(dat, selected_)
})
}
shinyApp(ui, server)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.