I'm trying to emulate the behavior of plotly::highlight() in a Shiny app, but on the server side, for line traces generated from long-format data, where the data frame has columns x, y, CurveID, where each CurveID is a separate line. The idea is similar to the Texas housing example shown here, where multiple lines can be highlighted on click.
My plot is generated by
df1 |>
plotly::plot_ly(
source = 'raw_curves',
customdata = ~CurveID
) |>
dplyr::group_by(CurveID) |>
plotly::add_lines(
x = ~x,
y = ~y
) |>
plotly::highlight(
on = 'plotly_click',
off = 'plotly_doubleclick',
color = 'red',
dynamic = FALSE,
selectize = FALSE
) |>
plotly::event_register('plotly_click') |>
plotly::toWebGL()
I want to get the CurveID for each highlighted curve so I can send these values to other functions on the server side of my app. This part is easy enough using a reactive value updated by
plotly::event_data('plotly_click', source = 'raw_curves')$customdata
However, I then want to programmatically highlight lines with the same CurveID on separate plotly figure. This second figure is constructed in the same general way as figure 1, except the data is a heavily transformed and filtered version of the first dataset. I thought of using crosstalk functionality here, but this seems to require using the same data.frame for both plots, but this isn't possible, since the transformations and filtering need to happen on the server.
I also attempted to use plotlyProxy()
and plotlyProxyInvoke()
to restyle the lines, but this seems to operate only on the trace level, rather than on each group within a line trace:
myPlotlyProxy <- plotlyProxy('curves_plot', session)
observe({
plotlyEventData <- event_data('plotly_click', source = 'raw_curves')
# This restyles all the lines in red, rather than the selected CurveID
plotlyProxyInvoke(
myPlotlyProxy,
'restyle',
list(line = list(
color = 'red'
)),
plotlyEventData$curveNumber # All lines have the same curveNumber
)
}) |>
bindEvent(event_data('plotly_click', source = 'raw_curves'))
Using a loop with add_lines()
is too slow, given than I need to plot hundreds of lines.
My questions I think boil down to:
- How can I send
plotly::highlight()
selections to the server, if at all? - How can I set traces to be highlighted by
plotly::highlight()
? Alternatively, is there some way to use restyle that operates on individual lines within a trace, similarly to how we can use curveNumber and pointNumber to index points within a marker trace?
Thank you!