--- title: "Grouping plot elements" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Grouping plot elements} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- Sometimes you may want to include more complex patterns of interactivity into a plot, for example where interaction with one plot elements triggers changes or appearance / disappearance in a wider group of other plot elements. In this case you can utilise the ability to group elements in a plot, so that interaction with any one of the group elements that has been indicated as interactive with the argument `interactive = TRUE` will trigger changes as specified by `highlight` in all other plot elements in the same group. The example below builds up a plot with more complex interactivity based on these principles. ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(r3js) ``` ```{r, out.width="100%", out.height="600px"} # Set data x_vals <- iris$Sepal.Length y_vals <- iris$Sepal.Width z_vals <- iris$Petal.Length point_cols <- rainbow(3)[iris$Species] # Setup plot data3js <- plot3js( x = x_vals, y = y_vals, z = z_vals, xlab = "Sepal Length", ylab = "Sepal Width", zlab = "Petal Length" ) # Add points for each point for (n in seq_along(x_vals)) { # Set a record of point ids you're going to group point_ids <- c() # Add the 3d point data3js <- points3js( data3js, x = x_vals[n], y = y_vals[n], z = z_vals[n], col = point_cols[n], size = 1, highlight = list( size = 2 ), interactive = TRUE ) point_ids <- c(point_ids, lastID(data3js)) # Add the point on the x- face data3js <- points3js( data3js, x = data3js$lims[[1]][1] + 0.001, y = y_vals[n], z = z_vals[n], col = point_cols[n], shape = "circle", size = 1, opacity = 0.2, highlight = list( size = 2, opacity = 1 ), interactive = TRUE, depthWrite = FALSE, rotation = c(0, 90, 0), face = "x-" ) point_ids <- c(point_ids, lastID(data3js)) # Add the point on the x+ face data3js <- points3js( data3js, x = data3js$lims[[1]][2] - 0.001, y = y_vals[n], z = z_vals[n], col = point_cols[n], size = 1, shape = "circle", opacity = 0.2, highlight = list( size = 2, opacity = 1 ), interactive = TRUE, depthWrite = FALSE, rotation = c(0, 90, 0), face = "x+" ) point_ids <- c(point_ids, lastID(data3js)) # Add the line to the x- face data3js <- lines3js( data3js, x = c(data3js$lims[[1]][1], x_vals[n]), y = c(y_vals[n], y_vals[n]), z = c(z_vals[n], z_vals[n]), lwd = 0, highlight = list( lwd = 2 ), face = "x-" ) point_ids <- c(point_ids, lastID(data3js)) # Add the line to the x+ face data3js <- lines3js( data3js, x = c(x_vals[n], data3js$lims[[1]][2]), y = c(y_vals[n], y_vals[n]), z = c(z_vals[n], z_vals[n]), lwd = 0, highlight = list( lwd = 2 ), face = "x+" ) point_ids <- c(point_ids, lastID(data3js)) # Add the point on the y- face data3js <- points3js( data3js, x = x_vals[n], y = data3js$lims[[2]][1] + 0.001, z = z_vals[n], col = point_cols[n], size = 1, shape = "circle", opacity = 0.2, highlight = list( size = 2, opacity = 1 ), interactive = TRUE, depthWrite = FALSE, rotation = c(90, 0, 0), face = "y-" ) point_ids <- c(point_ids, lastID(data3js)) # Add the point on the y+ face data3js <- points3js( data3js, x = x_vals[n], y = data3js$lims[[2]][2] - 0.001, z = z_vals[n], col = point_cols[n], size = 1, shape = "circle", opacity = 0.2, highlight = list( size = 2, opacity = 1 ), interactive = TRUE, depthWrite = FALSE, rotation = c(90, 0, 0), face = "y+" ) point_ids <- c(point_ids, lastID(data3js)) # Add the line to the y- face data3js <- lines3js( data3js, x = c(x_vals[n], x_vals[n]), y = c(data3js$lims[[2]][1], y_vals[n]), z = c(z_vals[n], z_vals[n]), lwd = 0, highlight = list( lwd = 2 ), face = "y-" ) point_ids <- c(point_ids, lastID(data3js)) # Add the line to the y+ face data3js <- lines3js( data3js, x = c(x_vals[n], x_vals[n]), y = c(y_vals[n], data3js$lims[[2]][2]), z = c(z_vals[n], z_vals[n]), lwd = 0, highlight = list( lwd = 2 ), face = "y+" ) point_ids <- c(point_ids, lastID(data3js)) # Add the point on the z- face data3js <- points3js( data3js, x = x_vals[n], y = y_vals[n], z = data3js$lims[[3]][1] + 0.001, col = point_cols[n], size = 1, shape = "circle", opacity = 0.2, highlight = list( size = 2, opacity = 1 ), interactive = TRUE, depthWrite = FALSE, face = "z-" ) point_ids <- c(point_ids, lastID(data3js)) # Add the line to the z- face data3js <- lines3js( data3js, x = c(x_vals[n], x_vals[n]), y = c(y_vals[n], y_vals[n]), z = c(data3js$lims[[3]][1], z_vals[n]), lwd = 0, highlight = list( lwd = 2 ), face = "z-" ) point_ids <- c(point_ids, lastID(data3js)) # Add the line to the z+ face data3js <- lines3js( data3js, x = c(x_vals[n], x_vals[n]), y = c(y_vals[n], y_vals[n]), z = c(z_vals[n], data3js$lims[[3]][2]), lwd = 0, highlight = list( lwd = 2 ), face = "z+" ) point_ids <- c(point_ids, lastID(data3js)) # Add the point on the z+ face data3js <- points3js( data3js, x = x_vals[n], y = y_vals[n], z = data3js$lims[[3]][2] - 0.001, col = point_cols[n], size = 1, shape = "circle", opacity = 0.2, highlight = list( size = 2, opacity = 1 ), interactive = TRUE, depthWrite = FALSE, face = "z+" ) point_ids <- c(point_ids, lastID(data3js)) # Now group all the points you've added data3js <- group3js(data3js, point_ids) } # View the plot r3js(data3js) ```