Activate a mouse click event based on user input in a Shiny

I am currently developing a shiny app that includes a plotly sunburst chart.
Once I provide the correctly formatted dataframe, I need to interact with the sunburst chart by clicking on it to "drill-down."

Is there a way to replicate this mouse click action in order to control the drill-down functionality based on user input such as selectInput()?

How can I establish a connection between the selectInput() element and the shiny sunburst so that changes in the selectInput also impact the display of the sunburst? Maybe through the usage of an observer event? Thank you for your assistance.

Below is an example illustrating my issue:

library(shiny)
library(plotly)
library(DT)


d <- data.frame(
  ids = c(
    "North America", "Europe", "Australia", "North America - Football", "Soccer",
    "North America - Rugby", "Europe - Football", "Rugby",
    "Europe - American Football","Australia - Football", "Association",
    "Australian Rules", "Autstralia - American Football", "Australia - Rugby",
    "Rugby League", "Rugby Union"
  ),
  labels = c(
    "North<br>America", "Europe", "Australia", "Football", "Soccer", "Rugby",
    "Football", "Rugby", "American<br>Football", "Football", "Association",
    "Australian<br>Rules", "American<br>Football", "Rugby", "Rugby<br>League",
    "Rugby<br>Union"
  ),
  parents = c(
    "", "", "", "North America", "North America", "North America", "Europe",
    "Europe", "Europe","Australia", "Australia - Football", "Australia - Football",
    "Australia - Football", "Australia - Football", "Australia - Rugby",
    "Australia - Rugby"
  ),
  stringsAsFactors = FALSE
)


ui <- fluidPage(
  
  mainPanel(
    
    # an option to simulate or mirror the mouse click event using this user input
    selectInput( 
      "make_selection", label = h5("Make selection:"),
      choices = c("all" = " ", setNames(nm = d$ids)),
      selectize = TRUE,
      selected = "all"
    ),
    
    plotlyOutput("p"), 
    textOutput("mytext")
    
    
  )
)

server <- function(input, output, session) {
  
  output$p <- renderPlotly({
    
    plot_ly(d, ids = ~ids, labels = ~labels, parents = ~parents, customdata = ~ids, 
            level = input$make_selection, type = 'sunburst', 
            source = "mysource") 
    
    
    
  })
  
  hoverClick <- reactive({
    currentEventData <- unlist(event_data(event = "plotly_click", source = "mysource", priority = "event"))
  })

  output$mytext <- renderText({

    hoverClick()

  })

  observe({
    x <- input$make_selection

    # Using character(0) will clear all choices
    if (is.null(hoverClick())){
      x <- "all"
    } else {
      x <- as.character(hoverClick()[3])
    }

    updateSelectInput(session, "make_selection",
                      selected = x
                      
                      # Is it possible to add something here just to update the selector without triggering a selector event?
                      # (Otherwise both plotly and the selector are trying to choose the level and it results in a jerky behavior)
    )
  })
  
}


shinyApp(ui = ui, server = server)


Answer №1

To show a specific level, you can utilize the level argument in your code. However, there are a couple of issues with this implementation:

  • The changes made are not animated. Consider exploring solutions using plotly.animate or using it as a foundation for resolving this.
  • make_selection does not update when clicking on the plot. You might want to experiment with the plotly_sunburstclick event to address this issue.
library(shiny)
library(plotly)


d <- data.frame(
  ids = c(
    "North America", "Europe", "Australia", "North America - Football", "Soccer",
    "North America - Rugby", "Europe - Football", "Rugby",
    "Europe - American Football","Australia - Football", "Association",
    "Australian Rules", "Autstralia - American Football", "Australia - Rugby",
    "Rugby League", "Rugby Union"
  ),
  labels = c(
    "North<br>America", "Europe", "Australia", "Football", "Soccer", "Rugby",
    "Football", "Rugby", "American<br>Football", "Football", "Association",
    "Australian<br>Rules", "American<br>Football", "Rugby", "Rugby<br>League",
    "Rugby<br>Union"
  ),
  parents = c(
    "", "", "", "North America", "North America", "North America", "Europe",
    "Europe", "Europe","Australia", "Australia - Football", "Australia - Football",
    "Australia - Football", "Australia - Football", "Australia - Rugby",
    "Australia - Rugby"
  ),
  stringsAsFactors = FALSE
)


ui <- fluidPage(
  
  mainPanel(
    
    # an option to override or replicate mouse click action through user input
    selectInput( 
      "make_selection", label = h5("Make selection:"),
      choices = c("all" = " ", setNames(nm = d$ids)),
      selectize = TRUE,
      selected = "all"
    ),
    
    plotlyOutput("p")
    
    
  )
)

server <- function(input, output, session) {
  
  output$p <- renderPlotly({
    
    plot_ly(d, ids = ~ids, labels = ~labels, parents = ~parents, 
            level = input$make_selection, type = 'sunburst') %>% 
      event_register("plotly_sunburstclick")
    
    
    
  })
  
  observeEvent(event_data("plotly_sunburstclick"), {
    # retrieve id name and update "make_selection"
  })
}

shinyApp(ui = ui, server = server)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhance data table by displaying a set number of rows that do not completely fill the table's height

I'm currently attempting to implement a v-data-table with fixed header and footer. However, I've encountered an issue where if I set the table height to be larger than the row height, the table takes on the defined height and the footer ends up b ...

Receiving 'Unexpected end of input' error when using a string as a JavaScript function argument

I am trying to implement an ajax request function in my project. This is the code snippet I have: function Reject(id, scomment) { jQuery.ajax({ type: "POST", url: "reject.php", data: {id: id, Scomment: scom ...

Analyzing the efficiency of data.table::setorder versus base::sort

As I attempt to arrange rows of the data.table (R-3.3.1 Win x64 & data.table_1.9.6), I have noticed that the function setorder produces different results compared to the base::sort function. Could it be that I am incorrectly using setorder? dt < ...

Using the map function twice in React Native causes a rendering issue

<View style={styles.card} > {store.crud.list.map(function(element, index){ return ( <View style={styles.wrapper}> {element.map(function(number, index){ return( ...

Issues with Grunt functionality after installation on Ubuntu

I successfully installed Grunt by running the following commands in the terminal: sudo apt-get install nodejs sudo apt-get install npm npm install -g grunt-cli After executing npm install -g grunt-cli, here is the output from the terminal: (output he ...

"Encountered the following error message: "Error [ERR_HTTP_HEADERS_SENT]: Unable to modify headers once they have been sent to the client" while attempting

My attempts to set a cookie when someone inputs the correct key (1234) are resulting in an error message: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client. I'm confused on what steps to take next. I've tried r ...

Issue with retrieving relative time using Moment.js - fromNow()

I want to utilize moment.js to display relative time fromNow(), but I am encountering an issue where the values are being rounded and showing higher durations instead of exact completion times. For example, moment().subtract('s',110).fromNow() / ...

Can anyone suggest a method for adding comments and improving the organization of a bower.json file?

Managing a large project with numerous bower dependencies can be challenging. It's often unclear whether these dependencies are still being used or if the specified versions are necessary for a reason. It would be ideal to have the ability to add comm ...

retrieve the parent frame's request URL

I am faced with the task of writing a JSP code that retrieves the getRequestURL() of the parent frame (the URL shown in the address bar) from a child frame. However, when I attempt to do this, I only obtain the URL of the child frame. Is there anyone who ...

The interactivity of data-ng-click in HTML is not functioning as expected

I need help with implementing the data-ng-click functionality for a dynamically created button. Can someone assist me with this? var table = document.getElementById("dashboard"); for( var i = 0; i < $scope.namesOfMembers.length; i++ ){ var row = t ...

The angular application fails to load the page properly and keeps refreshing itself

I'm currently working on an Angular app that searches for a Github user based on their username and then displays the list of repositories. When a user clicks on a repo name, it should show the open issues and contributors associated with that reposit ...

Remove all instances of an empty array within a larger array

Is there a way to eliminate an empty array from within a parent array prior to adding a new element? In the structure provided, it appears as follows: var parentArray = [ ['123', '345'], [], ['12'] ] The goal is to remove t ...

Missing information in input field using JQUERY

I've been attempting to extract a value from an input tag, but all I keep getting is an empty string. Upon inspecting the frame source, it appears as follows: <input type="hidden" name="" class="code_item" value="00-00000159" /> In order to re ...

Looking for the Mustache template library?

Can you provide some examples of how mustache can be used effectively? I recently came across it, but I'm struggling to grasp how it differs from the traditional approach of creating template files within frameworks like cakePHP or django, or simply ...

Tips for transmitting an array of Objects to AngularJS

Summary I'm curious about how I can successfully send the following array of objects from NodeJS to an AngularJS app. var players = [ Footer: { username: 'Footer', hp: 200, exp: 1 }, Barter: { username: 'Barter', hp: 200, e ...

Is JsonEditor capable of editing JSON Schemas effectively?

For a while now, I have been impressed by the functionality of JSON-editor and have been using it to edit documents based on a specific JSON schema. But why stop there? Many users utilize JSON-Editor to make changes to JSON documents according to the corr ...

Having trouble with $.post request to a different domain in a node.js/express app running on port 8081

Whenever I try to use $.post, I keep getting the error message POST https://thewebsite.com 400 (Bad Request). Here is the code snippet that's causing the issue: $.post("https://website.com/blabla", { domain: "infoinfo.com", room: "someInfo", ap ...

Uncovering the Android tablet browser: A guide

I have implemented the code below to detect mobile/tablet browsers. function isMobile() { var index = navigator.appVersion.indexOf("Mobile"); return (index > -1); } Although it works well for desktop browsers and iOS devices (iPhon ...

After being redirected from another page using history() in React, the state is initially set to null but later gets updated to the correct value - Firebase integration

After logging in and being redirected to the profile page, I encounter an error that says 'Unhandled Rejection (TypeError): Cannot read property 'email' of null'. How can I ensure that the state is set before proceeding with any additio ...

Combine identical arrays of object keys into one unified array

https://i.sstatic.net/A2r5c.png I am striving for this particular output [ productId:106290, productserialno:[{ "12121", "212121" }] ] ...