image/svg+xml

How to transform a dashboard design in R shiny

DESIGN - OUTILS - LANCEMENT PUBLIC

Découvrez comment nous avons professionalisé l’application de l’Observatoire Français des Conjonctures Économiques.

Sommaire

L'application Debtwatch, publiée récemment par l'OFCE Observatoire Français des Conjonctures Économiques, a été codée en R Shiny.

Dans cette étude de cas, on va discuter de comment je suis intervenu dans le développement pour que le lancement de l'application soit un succès. Et surtout, on va voir comment passer de ça :

Avant Avant

Après Après

Une application assez simple sur le principe

Quand Xavier Timbeau m’a montré l’application pour la première fois, j’ai vu un dashboard des plus classiques.

Une barre latérale qui contient des paramètres et des filtres.

Une série de graphiques qui se mettent à jour quand on change les filtres.

Dans les coulisses, des modèles macro-économiques assez balèzes qui tournent et qui simulent des scénarios.

Plutôt la base pour une application Shiny.

Appli basic Appli basique

Xavier m’a amené 2 problématiques:

  1. Ajouter des nouvelles fonctionnalités.
  2. Améliorer l’esthétique.

Clairement, c’était pas la technique qui manquait à Xavier.

Il avait déjà codé une application fonctionnel, et il fallait juste rajouter des petites features à droite à gauche.

C’était plutôt un problème de timing, avec une date de lancement déjà prévue.

Niveau esthétique, l’application de base n’était pas moche.

C’était sobre. Propre. C’était acceptable.

Sauf que l’idée, c’était de voir que l’application appartenait à l’OFCE. On voulait retrouver la charte graphique de l’OFCE sur l’appli.

Et là, pour le coup, j’ai vite vu que le design c’était pas le truc de Xavier.

Étape 1 Comment choisir la bonne technologie de base ?

La question qui turlupinait Xavier, c’était « shinyBS ou shinydashboard ? »

bsdash vs shinydashboard

En fait, même si la question est complètement légitime, elle ne répond pas à la problématique.

Il existe des tonnes de techno pour faire du dashboard.

Si demain vous voulez créer un dashboard en R Shiny, vous pouvez utiliser shinyBS, shinydashboard, shinydashboardplus, shiny.semantic, bs4dash, bslib, …

C’est pas les packages qui manquent. On a une surabondance de choix.

Mais à nouveau…

C’est pas ça qui importe ici.

Quel que soit le choix qu’on allait faire, on allait toujours avoir le même résultat.

Le résultat : Une interface neutre.

Sobre. Propre. Agréable à utiliser. Certes.

Mais aussi neutre. Générique. Fade. Sans personnalité.

C’est normal, c’est du one-size-fits-all, c’est censé être utilisé par n’importe qui dans n’importe quel contexte !

Sauf que nous, on voulait donner une vraie identité à l’application.

Objectif : Maximiser la communication autour de l’outil.

Un des moyens d’y parvenir, c’est de transformer les utilisateurs de votre application en ambassadeurs de votre produit.

Et pour ça, il faut davantage qu’un outil sobre, propre, et neutre.

Il faut :

  • Une vraie identité visuelle.
  • Un dashboard intuitif et facile à utiliser.

Étape 2 Préparer une maquette graphique

Le design se découpe en deux parties : L’UI et l’UX.

L’UI, pour User Interface, c’est tout ce qui est création de l’interface et rendre cette interface jolie.

L’UX, pour User eXperience, c’est tout ce qui a trait à la manière dont l’utilisateur va interagir avec l’application.

En gros : On veut un truc qui soit beau ET pratique. C’est comme ça qu’on maximise l’adoption de l’outil.

L’UI et l’UX, c’est un vrai métier.

C’est clairement pas le mien. Je n’ai aucun goût artistique et aucune capacité à me projeter dans un autre design.

Pour ces problématiques, je fais appel à une experte : Cécile Uzel, graphiste et fondatrice de l’Atelier Qui Fait Mouche.

Je lui ai présenté l’application, comment elle fonctionnait, et l’objectif qu’on avait.

Je n’avais aucune idée de ce à quoi l’application allait ressembler.

Mais quand j’ai vu la maquette, je me suis tout de suite dit : « Bah oui ! Mais c’était sûr en fait ! »

On reconnaît instantanément la charte graphique de l’OFCE :

Maquette v1 Maquette

Il ne restait plus qu’à intégrer tout ça dans un code en R Shiny.

Et là…

Ben là, je pense que vous avez compris que la question du « shinyBS ou shinydashboard ? », elle est vite répondue.

Aucun des deux.

C’est finalement beaucoup plus simple de repartir de zéro en construisant les blocs avec du HTML et du CSS.

Étape 3 Créer la structure en HTML

On pourrait penser que c’est une perte de temps de tout recoder en HTML au lieu d’utiliser un package comme shinydashboard.

En fait, pas tant que ça.

Le HTML, c’est la partie la plus facile.

Comme shiny utilise Bootstrap par défaut (quand on utilise la fonction fluidPage()), on ne part pas tout à fait de zéro.

En fait, Bootstrap donne déjà énormément d’outils.

Par exemple, la possibilité d’utiliser une grille avec le système de colonnes : Les fonctions fluidRow() et column().

Voici comme reconstituer une structure de dashboard :

fluidPage(
  fluidRow(
    id = "title_panel",
    # Contenu de l'en-tête
  ),
  fluidRow(
    id = "body",
    column(
      id = "sidebar_panel",
      width = 3,
      div(
        # Contenu de la barre latérale
      )
    ),
    column(
      id = "main_panel",
      width = 9,
      div(
        # Contenu du corps principal
      )
    )
  )
)

Et c’est tout ! Le reste, c’est ajouter le contenu.

Si vous êtes curieux, voici le code de l’interface : Lien vers le dépôt Github

Notez l’utilisation du paramètre id.

Les id seront beaucoup utilisés ensuite en CSS pour personnaliser l’apparence. Ils permettent de créer ce qu’on appelle des sélecteurs.

Parce qu’en effet, par défaut ça va être un peu moche.

C’est là que si on utilise un package comme shinydashboard, on va par défaut avoir une apparence correcte, mais non personnalisée et sans identité marquée. Ce qui convient bien dans certains cas. Mais pas dans le nôtre.

Il ne reste plus qu’à coder la partie visuelle ! Pour ça, il faut faire du CSS.

Étape 4 Le package sass pour écrire du CSS facilement

Mon outil préféré pour tout ce qui touche au graphisme, c’est le package sass.

sass, pour Syntactically Awesome Style Sheets, est une sorte de d’extension de CSS.

Je l’utilise principalement pour hiérarchiser mon code CSS, ce qui est plus facile à lire et à écrire.

Par exemple :

#main_panel {
  
  padding: 50px 7%;
  
  .introduction {
    
    position: relative;
    background-color: white;
    padding: 10px 25px 30px 25px;
    margin-bottom: 20px;
    
    h3 {
      font-size: 20px;
      color: $red;
      text-transform: uppercase;
    }
  }
}

Alors qu’en CSS, ça donnerait :

#main_panel {  
  padding: 50px 7%;
}
  
#main_panel .introduction {    
  position: relative;
  background-color: white;
  padding: 10px 25px 30px 25px;
  margin-bottom: 20px;
}
    
#main_panel .introduction h3 {
  font-size: 20px;
  color: $red;
  text-transform: uppercase;
}

Pas de structure, et des sélecteurs à rallonge.

Sur cet exemple, ça va encore, mais quand on en a pour quelques centaines de lignes, on est content de pouvoir structurer et hiérarchiser les sélecteurs !

Là aussi, si vous êtes curieux, le code est disponible sur le dépôt Github : Lien vers les fichiers SASS.

Au final, la maquette n’était pas très compliquée à intégrer.

Sauf un petit détail…

Étape 5 : Créer ses propres widgets

Un challenge qu’on a dû résoudre, c’était celui de pouvoir afficher les paramètres sur la gauche d’une manière qui soit à la fois :

Clairement, la solution d’origine ne permettait pas tous ces points.

Elle utilisait bsCollapse pour la partie condensée, mais on ne comprenait pas bien qu’il s’agissait de boîtes qu’on pouvait déplier, et surtout on n’avait pas d’accès facile aux valeurs sélectionnées.

Un autre problème, c’est le design du sliderInput de Shiny.

Il prend énormément de place !

Comparez avec ce qui était prévu par la maquette :

Slider 1 : sliderInput

Slider 2 : sliderInput2

Au-delà même de l’aspect visuel et des couleurs, il y a pas mal de problèmes à résoudre :

atl text

J'ai vite compris que j'allais devoir recoder un widget.

Créer un nouveau widget, quand on ne l'a jamais fait avant, c'est pas une mince affaire.

La documentation sur le sujet est par ailleurs assez légère.

RStudio propose deux articles :

Ils sont tous les deux bien, et permettent de démarrer sur le sujet, sauf qu’ils sont un peu vieux (2014 et 2017 respectivement), et en plus ils ne documentent pas tout.

En fait, ils écrivent :

In addition to the previously discussed methods, several other JavaScript methods can be added to your input binding object, notably; getId, getState, getRatePolicy, receiveMessage and unsubscribe. These are discussed in the various references provided and are not further discussed here.

Oui, en fait, non, pas vraiment.

Les références qu’ils mentionnent, c’est l’article de 2014, qui reste introductif, et des liens vers des exemples sur Github. Donc, en gros : « Débrouillez-vous pour le reste. »

Et c’est justement ces méthodes JavaScript qui sont importantes pour que le widget fonctionne bien !

Ça me fait un peu penser aux papiers scientifiques qui écrivent La démonstration de cette propriété est laissée au lecteur.

Bref.

Au final, des recherches supplémentaires m’ont conduit vers :

Et puis après, bah… Le meilleur moyen, c’est encore de creuser dans le code.

Il va encore falloir que je me tape l’écriture d’un guide-fleuve. ^_-

Je suis allé voir le code de la fonction originelle sliderInput, et je me suis aussi aidé de ce qui a été fait dans le package shinyWidgets.

Et au bout d’un moment, on s’en sort.

Le widget créé est pas parfait, notamment il ne se généralise pas très bien à d’autres applications. Mais il marche, et il fait exactement ce que la maquette avait prévu :

Si vous êtes curieux, voici le code :

Il y a aussi un bout de code en plus pour mettre à jour la valeur dans le “contenant” du slider.

Bref, c’est pas très généralisable.

Au final, une fois passés les premiers errements sur la documentation, la création d’un nouveau widget s’est faite assez facilement.

Prochaine étape ?

À présent que l'application est lancée, elle pourra être utilisée pour simuler les trajectoires économiques et échanger autour de la soutenabilité de la dette.

Avec l'approche des élections, ces problématiques vont entrer de plus en plus dans les débats, alors que l'objectif de garder la dette à 60% du PIB (prévu par le traité de Maastricht) est de plus en plus remis en question.

Nous entrons donc dans une phase d'amélioration continue de l'application pour encore améliorer l'expérience utilisateur, via la prise en compte des retours utilisateurs, comme par exemple la possibilité de facilement retrouver les scénarios simulés d'une fois sur l'autre (grâce à nos amis les cookies !).

Give me a call!