Show/hide series interractively in dygraph

994 Views Asked by At

Is there a possibility to show/hide the series interactively in a R dygraph?

The idea is to compare many time series and have for example a ticking box where one could select/deselect the series to show or hide any of them.

I could not find such an option in the dygraphs package. Such ticking legend exist for example in the package leaflet with addLayersControl().

2

There are 2 best solutions below

0
On

I know the question is about R and 4 years old, but I ran into this same need in JavaScript. I put together an implementation of this for my own JS, thought others might be interested.

In my case, I'm displaying historical data for a device (voltage, current, etc). Part of that involves building a readable title for the graph, such as "Generator 1: Voltage, Current". the data array contains all my results, and the property of each dataset is the readable title. When I am looping through to build my main title I do this:

var thistitle = data[i].property;
var thislink = `<a href="#" onclick="HV3_toggleVis(${i})">${thistitle}</a>`

var visArray = [];        
for(var i=0;i<data.length;i++) { //for each requested dataset
  visArray.push(true); //build out boolean visibility array
}

When I build my graph, i do:

window.dygraphs.history_output = new Dygraph([...]);

window.dygraphs.history_output.visArray = visArray;

Now my array of booleans for each dataset is stored as a property of my graph object.

When I build my title, I do:

var thistitle = data[i].property;
var thislink = `<a href="#" onclick="HV3_toggleVis(${i})">${thistitle}</a>`

titles[data[i].name].titlestring += thislink;

Now I have an array of links for running my visibility toggles. For my function, i have:

function HV3_toggleVis(seriesIndex) {
    var visArray = window.dygraphs.history_output.visArray; //i like short working names for vars.
    
    visArray[seriesIndex] = !visArray[seriesIndex]; //toggle boolean
    window.dygraphs.history_output.setVisibility(seriesIndex,visArray[seriesIndex]); //toggle the selected dataset

    window.dygraphs.history_output.visArray = visArray; //save the changes to the object
}

In future I might try to put it in the legend instead, but for now this is lovely. Here's an example of it in action. I haven't copied it over to my live unit yet, so the dataset is just a line, but you get the idea:

https://i.imgur.com/K3mq0oA.png

0
On

You can do it with the package "shiny" in R Studio. No need to venture outside of R Studio (unless you really want to).

This chunk of code should work for anyone so long as you have the four packages installed. Use it as a jumping off point with your own data. I used drop down menus, but Shiny lets you use check boxes for user inputs as well. Hope this helps!

library(shiny)                # to dynamically select/plot variables here
library(tidyverse)            # required for transmute under server logic
library(dygraphs)             
library(magrittr)             # allows you to use pipes with dygraph()

a <- (1:10)                   # create example dataframe for dygraphs to plot
b <- rnorm(10, mean = 2)      
c <- rnorm(10, mean = 3)
d <- rnorm(10, mean = 4)

df <- as.data.frame(cbind(a,b,c,d))     

# User interface ----     # shiny does checkboxes too, modify accordingly
ui3 <- fluidPage(
  titlePanel("Example"),
  
  sidebarLayout(                                           # dropdown menus
    sidebarPanel(
      selectInput("column1", label = "Select a variable",  
              choices = c("None Selected", "Column B", "Column C", "Column D"), 
              selected = "Column B"),
      
      selectInput("column2", label = "Select a variable", 
              choices = c("None Selected", "Column B", "Column C", "Column D"), 
              selected = "None Selected")),
    
    mainPanel(dygraphOutput("dygraph"))
  )
)

# Server logic ----
server3 <- function(input, output) {
  output$dygraph <- renderDygraph({
    
  datax <- switch(input$column1,       # With no mapping for "None Selected"...
                   "Column B" = 2,     # ... nothing is graphed.
                   "Column C" = 3,
                   "Column D" = 4)
  
  datay <- switch(input$column2, 
                   "Column B" = 2,
                   "Column C" = 3,
                   "Column D" = 4)
  
  
  df2 <- df |>                            # df2 is dynamic, based on user input
    transmute(a, df[datax], df[datay])    # ... df2 passed to dygraph()
  
  dygraph(df2, main = "Fancy Plot Title") |>
    dyAxis("x", label = "Time") |>
    dyAxis("y", label = "Value")
  
})
  
}

# Run app ----
shinyApp(ui3, server3)           # you can run this in a browser if you prefer