3

I have the following sample flexdashboard:

---
title: "Hover"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
data(iris)
Column {data-width=650}
-----------------------------------------------------------------------

### Chart A

```{r}
iris %>% group_by(Species) %>% 
  summarise(mean = mean(Sepal.Length)) %>% 
  ggplot(aes(Species, mean)) + geom_col()

What I want is a tooltip when hovering over the bars in the plot and show its values. I read this article in SO How do I show the y value on tooltip while hover in ggplot2 but it works for Shiny. I tried this:

p <- iris %>% group_by(Species) %>% 
  summarise(mean = mean(Sepal.Length))

labels <- sprintf("<strong>%s</strong><br/>Mean: %f", 
                     p$Species, p$mean) %>% 
     lapply(htmltools::HTML)

p %>% ggplot(aes(Species, mean)) + geom_col() + geom_text(aes(label = labels))

This creates an html tool with the specie and value, what I don't have is the hover (plot_hover maybe?) to show the tooltip.

Any help will be greatly appreciated

Regards,

Manu
  • 1,070
  • 10
  • 27
  • You don't want to use `ggplotly`? – Stéphane Laurent Feb 29 '20 at 13:10
  • 1
    I'm interested in the answer for this question. I myself tried ggiraph, ggplotly and highcharter but I think a JS/Shiny solution would be great. Do you know how can I raise the bounty offered by Manu (using my points of course)? – Alexis Feb 29 '20 at 16:33
  • Hello @StéphaneLaurent, I prefer not to use ggplotly, since a JS or a built-in function answer could be great for those who want to extend their flexdashboard solution. As you see in the link I provided, a JS was available for shiny but I don't know how to make it work in flexdashboard. – Manu Mar 02 '20 at 13:39
  • Hello @alexismenanieves, I'm ok if you want to raise the bounty, any point given helps. – Manu Mar 02 '20 at 13:40

2 Answers2

5

Here is a way. You have to target the top center of a bar to get the tooltip.

---
title: "Untitled"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
library(dplyr)
library(ggplot2)
library(shiny)
```

Column {data-width=650}
-----------------------------------------------------------------------

### Chart A

```{r}
dat <- iris %>% group_by(Species) %>% 
  summarise(mean = mean(Sepal.Length))
output[["ggplot"]] <- renderPlot({
  dat %>% 
  ggplot(aes(Species, mean)) + geom_col()
})
output[["hoverinfo"]] <- renderUI({ 
  hover <- input[["plot_hover"]]
  if(is.null(hover)) return(NULL)
  point <- nearPoints(dat, hover, threshold = 50, maxpoints = 1)
  if(nrow(point) == 0) return(NULL)
  left_px <- hover$coords_css$x
  top_px <- hover$coords_css$y
  style <- 
    paste0("position:absolute; z-index:100; background-color: rgba(245, 245, 245, 0.85); ",
           "left:", left_px, 
           "px; top:", top_px, "px;")
  # tooltip created as wellPanel
  tooltip <- paste0(
    "<b> Species: </b>", point[["Species"]], "<br/>",
    "<b> mean: </b>", point[["mean"]]
  )
  wellPanel(
    style = style, p(HTML(tooltip))
  )
}) 
plotOutput("ggplot", hover = hoverOpts("plot_hover"))
div(uiOutput("hoverinfo"), style = "pointer-events: none;")
```
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Hello @Stephane Laurent, I tried your proposed solution and worked fine. What tI would like to ask you is about you using the double brackets `[["hoverinfo"]]`. Thank you. – Manu Mar 04 '20 at 14:05
  • 2
    @Manu `output[["hoverinfo"]]` is equivalent to `output$hoverinfo`. Does it answer your question ? I prefer `output[["hoverinfo"]]` because of the syntax highlighting in RStudio. – Stéphane Laurent Mar 04 '20 at 14:10
  • Hello @Stephane Laurent, thank you! It does answer my question. Have a great day! – Manu Mar 04 '20 at 18:25
1

I tried many different options with shinyBs, and the others described here, but I still had issues with adding tooltips without using runtime: shiny, so I added

output:
    includes:
       in_header: my_custom.html

And in my_custom.html I had:

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
  $( document ).tooltip(
    {
      position: {
        using: function( position, feedback ) {
          $( this ).css( position );
          $( "<div>" )
            .addClass( "arrow" )
            .addClass( feedback.vertical )
            .addClass( feedback.horizontal )
            .appendTo( this );
        }
      },
      show: {
        effect: "slideDown",
        delay: 500
      }
    }
  );
} );
</script>

Other options for styling could be found here

deann
  • 756
  • 9
  • 24
  • Hello Dean, thank you for your interest in this question, just a doubt, isn't it a javascript function? Why not on a `js` file instead? – Manu Mar 26 '21 at 15:44
  • 1
    I initially started writing in an html file, and I also wanted to insert the `` line there as well as it was needed. might work in a js file as well. – deann Mar 26 '21 at 16:29