Intégrer Chart.js avec des données dynamiques JSON dans une application Grails 3
C'est le Gist Responsive Chart.js Example with AJAX Callback qui a inspiré cet article : cet extrait de page HTML, qui inclut du code JavaScript, montre comment afficher un graphe de la librairie Chart.js, avec des données JSON qui sont obtenues de manière asynchrone à l'aide de jQuery.
Voyons comment intégrer un tel graphe dans une application Grails 3, en passant en revue les différents moyens de produire les données JSON dont le graphe a besoin, du côté serveur donc, y compris avec une vue JSON.
L'application Grails dont des extraits de code sont présentés par la suite, est disponible dans mon projet odelia-grails-chart.
Cette application comprend le contrôleur ChartController
associé à la vue GSP par défaut index.gsp
, qui permet de générer une page HTML qui affiche des graphes Chart.js
de type doughnut.
Chaque graphe est affiché grâce à un bouton qui déclenche l'exécution d'une fonction JavaScript définie dans le fichier doughtnut.js
; par exemple, on utilise ce qui suit pour le premier graphe :
1 2 3 4 5 6 7 8 9 10 |
|
La fonction JavaScript displayChart
est définie dans le fichier JavaScript doughtnut.js
(dans le répertoire grails-app/assets/javascripts
avec Chart.min.js
) qui est intégré en tant que dépendance du fichier application.js
, lui-même ajouté dans le layout Grails main
.
Notez que l'on transmet l'URL servant à récupérer les données JSON dans le premier argument de la fonction displayChart
, tandis que le second argument définit le sélecteur jQuery permettant d'identifier l'élément canvas
dans lequel le graphe va s'afficher.
Le fichier JavaScript doughtnut.js
comprend les fonctions JavaScript displayChart
et displayChart1
, ainsi que la fonction createChart
qu'elles appellent :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
C'est la fonction de rappel passée lors de l'appel jQuery.get()
qui construit les informations dont le graphe a besoin, à partir des données JSON reçues du contrôleur Grails.
Voyons de quelles différentes manières on peut générer ces données JSON.
Méthode 1 : utiliser le convertisseur Grails JSON
Pour cette première approche et l'affichage du graphe, on utilise l'appel JavaScript displayChart('/chart/data_1', '#invoice_status_chart_1')
lors du clic sur le bouton.
Il y a un document JSON à générer qui permet de définir quatre valeurs ; la manière la plus simple de procéder est d'employer le convertisseur grails.converters.JSON
de Grails à partir d'une Map
Groovy :
1 2 3 |
|
L'URL /chart/data_1
correspondant à l'action data_1
produit le document JSON suivant :
1
|
|
Méthode 2 : utiliser un builder JSON
Pour cette deuxième méthode et l'affichage du graphe, on utilise l'appel JavaScript displayChart('/chart/data_2', '#invoice_status_chart_2')
lors du clic sur le bouton.
La méthode de contrôleur Grails render
accepte aussi des arguments qui permettent la construction d'un document JSON grâce à un builder JSON interne, avec donc une approche plus déclarative.
L'action data_2
ci-dessous produit le même document JSON que précédemment :
1 2 3 4 5 6 7 8 |
|
Méthode 3 : utiliser une vue JSON
Le troisème doughnut est affiché au moyen de l'appel JavaScript displayChart('/chart/data_3_1', '#invoice_status_chart_3_1')
.
Le projet Grails Views permet d'utiliser des technologies de vues supplémentaires dans Grails 3, à savoir des vues XML et JSON (au moment de l'écriture de cet article).
Tout comme une vue GSP, une vue JSON prend la forme d'un fichier à créer dans le répertoire grails-app/views/chart
(chart
indiquant le contrôleur concerné), avec l'extension .gson
.
On a donc une action de contrôleur nommée data_3_1
:
1
|
|
Ecrite de cette manière, par convention, Grails va automatiquement rechercher une vue qui porte le nom de l'action dans le réperoire grails-app/views/chart
, afin de générer une réponse JSON.
Dans le projet Grails odelia-grails-chart, la vue JSON data_3_1.gson
contient ceci :
1 2 3 4 5 6 |
|
Il s'agit d'un script Groovy dans lequel on utilise la référence json
, de type StreamingJsonBuilder, qui permet construire la réponse JSON.
Par défaut, et pour des raisons de performance, les vues JSON sont compilées statiquement.
Plus loin avec la vue JSON
Jusqu'à présent, le document JSON construit sert à transmettre uniquement les différentes valeurs à utiliser dans la définition complète du graphe qui figure dans le code JavaScript de la fonction displayChart
.
Par ailleurs, dans le cas de la vue JSON, ces données ne devraient pas y figurer "en dur".
Utilisons une nouvelle vue JSON de telle sorte qu'elle génère la définition complète du graphe, et utilise des valeurs passées par le contrôleur :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Procéder ainsi demande à ce que l'action liée du contrôleur Grails transmette les valeurs au travers d'une variable data
du modèle :
1 2 3 |
|
Dans la vue JSON qui est compilée par Grails, il est nécessaire de préciser le type de la variable data
dans la construction model {}
, sous peine d'un échec de compilation.
Avec la définition JSON complète produite dans la vue, on utilise maintenant la fonction JavaScript displayChart1
qui est beaucoup plus simple que la fonction displayChart
utilisée jusqu'ici.
Dans le projet odelia-grails-chart, cela est donné en démonstration avec le quatrième graphe, qui est affiché avec l'appel displayChart1('/chart/data_3_2', '#invoice_status_chart_3_2'
.
D'autre part, la définition du graphe utilise des libellés fixes en anglais ("Temp", "Pending", "Partial" et "Complete"), ce qu'il vaudrait mieux éviter si l'on écrit une application multilingue.
Pour cela, on peut utiliser dans la vue, la méthode g.message
qui fait partie du support i18n de Grails et qui permet de récupérer un message traduit dans la Locale en cours, en fonction d'un code (par exemple g.message(code: 'chart.status.temp')
).
On peut également créer des vues spécifiques en ajoutant le code de la Locale au nom de la vue ; par exemple data_3_2_fr.gson
pour le français ou data_3_2_en.gson
pour l'anglais. Grails choisira automatiquement la vue adéquate en fonction de la langue.
Pour tester cet aspect-là, vous pouvez passer le code langue dans le paramètre d'URL lang
(par exemple : http://localhost:8080/chart?lang=fr).
N'hésitez pas à consulter la documentation du projet Grails Views pour en savoir plus sur les vues JSON ou XML !