teller.py3
teller.py3

Reputation: 844

Tooltip next to axis titles

Currently, I am making a dashboard with rshiny where I plot a graph. However, I am wondering if there is a way to add a tooltip next to the X and Y axis titles in the plot?

Specifically, a question mark or (something equivalent) next to the axis title, where end-users can click or hover on to see a more extensive description of what the axis really mean.

Something like this (does not work though):

layout(showlegend = FALSE,
       separators = ',.',
       xaxis = list(title = "Age", tooltip = "The age of every female above 50 years in the Unites States of America"))

Upvotes: 2

Views: 264

Answers (1)

koolmees
koolmees

Reputation: 2783

Unfortunately I don't know a package that can do this but you can use plotly with HTML and JS to bind a container to your title that contains a tooltip:

Edit: added yaxis (which tends to be a bit tougher)

df <- data.frame(a = 1:3,
                 b = 4:6)

jscode <- "
$(document).ready(function() {
    $(\"[data-toggle='tooltip']\").tooltip({container: 'body'}); 
});
"

csscode <- HTML('
    .plot-container {
        position: relative;
    }
    .xaxis-container {
        height: 20px;
        position:absolute;
        bottom: 0;
        left: 40px;
        background: #fff;
        opacity: 0.5;
    }
    .yaxis-container {
        width: 20px;
        position:absolute;
        bottom: 0;
        left: 5px;
        background: #fff;
        opacity: 0.5;
    }
    .xaxis-tooltip {
        width: 30px;
        height: 20px;
        background: #000;
        margin:auto;
    }
    .yaxis-tooltip {
        width: 20px;
        height: 30px;
        background: #000;
        margin:auto;
    }
')

library(shiny)
library(plotly)

ui <- fluidPage(
  tags$head(
    tags$script(jscode),
    tags$style(csscode)
  ),
  div(class = 'plot-container',
      plotlyOutput("plot"),
      div(
        class = "xaxis-container",
        div(class = "xaxis-tooltip", "data-toggle" = "tooltip", "title" = "x")
      ),
      div(
        class = "yaxis-container",
        div(class = "yaxis-tooltip", "data-toggle" = "tooltip", "title" = "y")
      )
  )
)

server = function(input, output) {
  output$plot <- renderPlotly({
    plot_ly() %>%
      add_trace(
        data = df,
        x =  ~ a,
        y =  ~ b,
        type = "scatter"
      ) %>%
      htmlwidgets::onRender("
          function(el, x) {
             var width = $('.draglayer')[0].getBoundingClientRect().width;
             var height = 0.5*$('.yaxis-tooltip')[0].getBoundingClientRect().height+$('.plot-container')[0].getBoundingClientRect().height-0.5*$('.draglayer')[0].getBoundingClientRect().height;
             $('.xaxis-container').css('width', width);
             $('.yaxis-container').css('height', height);
          }
        ")
  })
}

shinyApp(ui, server)

Which will look like so:

enter image description here

You can change the opacity to 0 to make the containers invisible, this is just a proof of concept.

Upvotes: 1

Related Questions