---
title: "Interactivité"
author: "Maxime Wack"
date: "17/11/2020"
output:
  xaringan::moon_reader:
    css: ['default','css/my_style.css']
    lib_dir: libs
    seal: false
    nature:
      ratio: '4:3'
      countIncrementalSlides: false
      self-contained: true
      beforeInit: "addons/macros.js"
---

```{r, include = FALSE}
library(gapminder)
library(tidyverse)
library(DT)
library(knitr)

opts_chunk$set(message = F)

options(DT.options = list(paging = F,
                          info = F,
                          searching = F))

datatable <- partial(datatable, rownames = F)
```

class: center, middle, title

# UE Visualisation

### 2020-2021

## Dr. Maxime Wack

### AHU Informatique médicale
#### Hôpital Européen Georges Pompidou, </br> Université de Paris

---
class: center, middle

# Objectif

## Ajouter de l'**interactivité** à une visualisation

---

# Interactivité

## Réactivité

L'objet **réagit** à l'utilisateur, mais n'est pas modifié

## Interactivité

L'utilisateur peut **influer** sur l'objet </br>
Un objet peut en **modifier** un autre

---
class: center

# Outils

### ggplot2 + ggplotly

### plotly

### D3

### VegaLite

### Shiny

---
class: center, middle

# ggplot2 + ggplotly

---

### Installer `plotly`

```{r install plotly, eval = F}
install.packages("plotly")
```

```{r libs}
library(tidyverse)
library(plotly)
```

---

```{r ggplotly simple}
iris %>%
  ggplot() +
  aes(x = Petal.Length, fill = Species) +
  geom_histogram() -> plot

ggplotly(plot)
```

---

```{r ggplotly pipe}
(iris %>%
  ggplot() +
   aes(x = Petal.Length, y = Petal.Width, color = Species) +
   geom_point()) %>%
  ggplotly
```

---

```{r ggplotly complex}
iris %>%
  ggplot() +
  geom_histogram(data = iris %>% select(-Species), aes(x = Petal.Length)) +
  geom_histogram(aes(x = Petal.Length, fill = Species)) +
  facet_grid(~Species) -> plot

ggplotly(plot)
```

---
class:center, middle

# Plotly

---

# Plotly

### Utilise aussi une **grammaire de graphiques**

### Bibliothèque **JS**

### Interface par un **package R**

### Couche d'**abstraction** pour ggplot2

https://plot.ly/r

---

# Plotly

### `ggplot` → `plot_ly()`

### `geom_*` → `add_*` ou `add_trace`

Les *aes* sont données avec des formules dans les traces

### `facet_*` → **subplots**

### `scale_*_*` + `theme` → `layout`

### `+` → `%>%`

---

```{r plotly simple}
iris %>%
  plot_ly() %>%
  add_markers(x = ~Sepal.Length,
              y = ~Sepal.Width)
```

---

```{r plotly global aes}
iris %>%
  plot_ly(x = ~Sepal.Length,
          y = ~Sepal.Width) %>%
  add_trace(color = ~Species,
            size = 4,
            mode = "markers")
```

---

```{r plotly hover}
iris %>%
  plot_ly(x = ~Sepal.Length,
          y = ~Sepal.Width,
          color = ~Species) %>%
  add_markers(size = 2,
              hoverinfo = "text",
              text = ~str_c("Espèce : ", Species, "\n",
                            "Longueur de sépale :", Sepal.Length, "\n",
                            "Largeur de sépale :", Sepal.Width))
```

---

# Plotly

### Interaction poussée (JS)

### Animations (frame)

*Aesthetic* d'animation, variable définissant l'état à chaque image clé

---
class:center, middle

```{r plotly anim, warning = F, echo = F}
gapminder %>%
  plot_ly(x = ~gdpPercap,
          y = ~lifeExp,
          size = ~pop,
          frame = ~year,
          color = ~continent,
          text = ~country,
          hoverinfo = "text") %>%
  add_markers() %>%
  layout(xaxis = list(type = "log")) %>%
  animation_opts(1000)
```

---

# D3

.pull-left[
### **D**ata **D**riven **D**ocuments
### Créé par **Mike Bostock**
*Data journalist* au NYT
]

.pull-right[
![:scale 50%](04-img/bostock.jpg)
]

### Moteur *bas niveau* pour manipuler des éléments du DOM et du SVG à partir de données.

### Notion de grammaire liant données et propriétés CSS, dont **animations** et **transitions**

.center[https://d3js.org]

---
class: center

# Outils dérivés de D3.js

## Plot.ly

## Vega(lite)

## C3.js

## R2D3 https://rstudio.github.io/r2d3/

---

# Réactivité

## Tous les outils précédents sont **réactifs**

### → affichage d'un overlay

### → changement de position/échelle

### → afficher / masquer / réordonner

(modulo interactions en *JS* à bricoler soi-même)


---

# Interactivité

## Manipulation des données

## Interactions avec la visualisation

## Interactions entre éléments de visualisation

---

# Shiny

### Architecture client/serveur

### Client = interface web

### Serveur = runtime R

https://shiny.rstudio.com/

https://mastering-shiny.org/

---

# Shiny

## Programmation **événementielle** → programmation **réactive**

## L'interface est mise à jour *quand nécessaire*

---


# Interface web

### Créée dans R

### Génère HTML + CSS + JS

### Définit des **input** et **output**

---

# UI

```{r shiny ui, eval = F}
ui <- fluidPage(titlePanel = "Titre",
                sidebarLayout(
                    sidebarPanel(
                      sliderInput(inputId = "bins",
                                  label = "Bins",
                                  min = 1,
                                  max = 50,
                                  value = 30,
                                  animate = animationOptions(interval = 100))),
                    mainPanel(plotOutput(outputId = "figure"))))
```

---

# Serveur

### Créé et exécuté dans R

### Génère les éléments d'**output** en fonction des **input**

### Les **outputs** peuvent *générer* de l'input (htmlwidgets : DT, plotly, etc.)

### Le serveur peut créer des **input** dynamiques

---

# Server

```{r shiny server, eval = F}
server <- function(input, output, session)
{
  set.seed(1234)
  normale <- tibble(val = rnorm(1000))

  output$figure <- renderPlot(
  {
    normale %>%
      ggplot() +
      aes(x = val) +
      geom_histogram(bins = input$bins)
  })
}
```
