rplotlyhtmlwidgetsonrender

Removing old trace and adding new trace each time user interacts in onRender htmlwidgets


I am aiming to make a plot using the onRender() function in the R package htmlwidgets in which a user can click on a point and a thick gray semi-transparent line is drawn. I have the crux of it working as is shown in the code below.

library(plotly)
library(broom)
library(htmlwidgets)

dat <- mtcars
dat$mpg <- dat$mpg * 10

p <- ggplot(data = dat, aes(x=disp,y=mpg)) + geom_point(size=0.5)

ggplotly(p) %>%
  onRender("
           function(el, x, data) {
              el.on('plotly_click', function(e) {

              //Plotly.deleteTraces(el.id, trace1);
              var trace1 = {
                 x: [100, 400],
                 y: [100, 400],
                 mode: 'lines',
                 line: {
                   color: 'gray',
                   width: 100
                 },
                 opacity: 0.5
              }

              //Plotly.deleteTraces(el.id, trace1);
              Plotly.addTraces(el.id, trace1);
           })
          }
          ", data = dat)

The problem that remains for me is the fact that each time the user clicks on a point, the opacity of the gray line becomes darker and darker. That is not my intention. In my real application, the gray line line thickness can change as well depending on other parameters not included in this MWE. As a result, in terms of this MWE, I would like to determine a way that, when a user clicks on a point, the old gray line is removed and the new gray line is drawn.

After some research, it seems that my best bet is to use the Plotly.deleteTraces(el.id, trace1) function. I tried to insert that command in two places (currently commented out in the code above). However, in both of these locations, that command seems to prevent any gray line from being drawn. I am unsure why this is happening and how to resolve it. As a result, any information on why this happens and how I can resolve it would be very helpful! Thank you.

Note: This is somewhat of a continuation of a previous post (Changing line thickness and opacity in scatterplot on onRender() htmlWidgets in R).


Solution

  • The trace object you want to remove is stored into x.data[1]. This should work:

    ggplotly(p) %>%
        onRender("function(el, x, data) {
                     el.on('plotly_click', function(e) {
    
                     if(x.data[1]) Plotly.deleteTraces(el.id, 1);
    
                     var trace1 = {
                         x: [100, 400],
                         y: [100, 400],
                         mode: 'lines',
                         line: {
                             color: 'gray',
                             width: 100
                         },
                         opacity: 0.5
                     }
    
                     Plotly.addTraces(el.id, trace1);
                     })
                 }", data = dat)