Angulaire | Travailleurs Web | Graphique.js
Comment utiliser OffscreenCanvas pour créer des graphiques à partir d’un travailleur Web
Dans notre article précédent, nous avons parlé des web workers dans Angular. Nous avons présenté certains des avantages et des inconvénients de son utilisation. Nous avons également eu la chance de les voir en action dans une application de démonstration.
Dans cet article, nous allons poursuivre l’étude des web workers. Nous utiliserons le OffscreenCanvas
API pour créer un graphique avec un web worker. Au cours du processus, nous soulignerons quelques-unes de leurs limites et comment nous pouvons les contourner.
Commençons!
Clause de non-responsabilité: À ce jour, l’API OffscreenCanvas n’est pas encore supporté par tous les navigateurs.
Nous utiliserons Graphique.js pour le rendu de nos cartes. Nous devons donc installer le package correspondant en exécutant la commande suivante dans le terminal :
npm install chart.js
Nous ajoutons une nouvelle page à notre application de démonstration. Cette page crée un graphique basé sur le nombre sélectionné sélectionné via un élément d’entrée de plage.
Respectivement, nous avons le fichier de classe. Chaque fois que l’utilisateur modifie la valeur, le modelChange
méthode est appelée. Cette méthode passe le newValue
au updateDataLength
méthode de la DataService
(ligne 13).
Nous n’avons pas de véritable backend, donc le DataService
simule la génération et la récupération de données à partir d’une API. A chaque fois le updateDataLength
est appelée, le service génère de nouvelles données.
De retour dans le ChartComponent
nous souscrivons à la data$
observable de ce service. Nous faisons cela dans le ngAfterViewInit
méthode du hook de cycle de vie. Nous utiliserons les données générées pour faire quelque chose.
Comme nous le verrons, ce quelque chose implique l’utilisation du chartCanvas
, une référence à un élément DOM. Nous interrogeons l’élément de la vue à l’aide de la ViewChild
décorateur. Mais les requêtes d’affichage sont définies avant le ngAfterViewInit
est appelé, d’où l’emplacement de l’abonnement.
À la ligne 15, nous vérifions si les web workers sont pris en charge ou non. Si ce n’est pas le cas, nous créons le graphique à partir du fil principal.
Voyons à quoi cela ressemble en action.
L’application « se fige » (par exemple, l’utilisateur ne peut pas naviguer) pendant le chargement du graphique. Les travailleurs du Web peuvent-ils aider à cela ?
Examinons à nouveau l’application, cette fois en utilisant un web worker.
Le web worker a fait le travail. Mais maintenant, il y a un autre problème. Notez qu’aucune étiquette n’apparaît plus lorsque vous survolez le graphique !
L’une des principales limitations des web workers est qu’ils n’ont pas accès au DOM. De plus, ils ont un accès limité aux méthodes et propriétés des window
objet.
Selon eux documents officielslors de l’utilisation de Chart.js dans un web worker :
« […] Les plugins Chart.js qui utilisent le DOM (y compris les interactions avec la souris) ne fonctionneront probablement pas.
La bonne nouvelle est que nous pouvons contourner ces limites… mais nous devrons faire tout le travail.
Wow, quelle est la mauvaise nouvelle ?
La mauvaise nouvelle est que tous les événements liés au DOM ne fonctionneront plus. Le redimensionnement ne fonctionnera pas non plus. Nous devons donc faire le travail pour chaque événement qui nous intéresse.
Mais avant tout !
Comment pouvons-nous même créer le graphique à partir du Web Worker ?
Entrer OffscreenCanvas
.
Au lieu de transmettre le canevas lui-même au Web Worker, nous transférer le contrôle du rendu du canevas. Nous créons le canevas une fois, puis utilisons son OffscreenCanvas
transférable pour effectuer n’importe quel rendu à partir du Web Worker.
Considérez les éléments transférables comme des objets pouvant être transférés dans un contexte JavaScript différent, comme une autre fenêtre ou un travailleur.
- Aux lignes 16 à 21, nous gérons le rendu sur le canevas. Tout d’abord, nous initialisons le web worker (ligne 17) et dessinons sur le canevas pour la première fois (ligne 18). Ensuite, nous effectuons tous les redessins de suivi (ligne 20).
- Sur les lignes 34 à 40, le premier tirage a lieu. Nous créons le canevas hors écran (ligne 34) et le transmettons au Web Worker. Nous passons également la toile hors champ comme transférable (ligne 40).
- Aux lignes 44 à 46, nous créons un canevas manuellement, l’ajoutons au DOM et renvoyons son
OffscreenCanvas
. - A la ligne 50, on utilise le
postMessage
pour envoyer de nouvelles données et effectuer un redessin.
Qu’en est-il de la mise en œuvre du travailleur ?
Jusqu’à présent, l’implémentation du Web Worker ressemble à ceci :
Nous utilisation importScripts
importer chart.js. Nous aurions eu des erreurs de compilation si nous avions essayé de l’importer avec la syntaxe habituelle. La raison en est les limitations du DOM dont nous avons parlé plus tôt. Nous avons aussi expliqué cela en détail dans notre article précédent.
En termes simples, nous envoyons des événements personnalisés au Web Worker et déclarons une fonction pour gérer chaque événement à l’intérieur du Web Worker.
Nous envoyons un firstDraw
au début pour initialiser le canevas et créer le graphique. Ensuite, nous envoyons redraw
événements pour détruire le graphique précédent et en dessiner un nouveau sur le canevas hors écran.
Le rendu du graphique à partir du Web Worker entraînait plusieurs effets secondaires.
L’un d’eux était que le graphique n’était plus réactif. Si nous redimensionnons la fenêtre du navigateur, le graphique ne se redimensionne pas avec, ce qui peut être problématique.
N’ayez pas peur !
Nous pouvons proxy l’événement de redimensionnement et redimensionner le graphique manuellement.
- Sur la ligne 16, nous enregistrons nos événements de redimensionnement.
- À la ligne 23, nous ajoutons un écouteur d’événement sur le
window
objet. Chaque fois que notre navigateur est redimensionné, nous transmettons l’événement au Web Worker pour redimensionner le graphique en conséquence.
Respectivement, notre travailleur Web doit être capable de gérer l’événement de redimensionnement. Nous créons un resize
fonction et ajoutez-la aux gestionnaires.
Un autre effet secondaire que nous avons observé plus tôt était que les interactions avec la souris cessaient de fonctionner. Aucune étiquette n’était affichée lors du survol du graphique.
Eh bien, vous connaissez l’exercice !
Nous pouvons proxy les événements de souris et les gérer comme bon nous semble. Nous modifions ChartComponent
et, plus précisément, sa createCanvas
méthode. Nous ajoutons des écouteurs d’événements au canevas pour mousemove
, mouseenter
et mouseleave
événements.
Du côté du travailleur, nous ajoutons les fonctions de gestionnaire respectives. Voici le code :
Sur les lignes 3 à 16, nous traitons mousemove
événements.
Nous identifions la barre la plus proche sur l’axe des x par rapport à l’emplacement actuel de la souris. Dans notre cas, nous avons deux jeux de données. Nous accéder aux métadonnées de chaque ensemble de données à partir du graphique (lignes 7 et 8).
Ensuite, nous vérifions si la souris touche l’une des barres voisines et affichons (ou masquons) l’étiquette par programme (lignes 9 à 14).
Sur mouseenter
nous permettons mousemove
la gestion des événements, alors que sur mouseleave
nous le désactivons et fermons toutes les étiquettes ouvertes. L’activation/la désactivation est nécessaire pour s’assurer qu’aucune étiquette ne reste affichée.
Clause de non-responsabilité: Il s’agit simplement de notre implémentation personnalisée qui fonctionnera pour le graphique à barres verticales de cette démo. Notre objectif est de vous enseigner le chemin, pas la mise en œuvre. J’espère que vous obtenez l’image!
Nous n’entrerons pas dans les détails des fonctions d’assistance spécifiques à l’implémentation, telles que getNearestElementOfX
et getNearestTouched
.
Vous pouvez trouver le code source complet dans ce référentiel GitHub.
Cet article a étudié comment rendre des graphiques avec des travailleurs Web dans Angular.
Le rendu des graphiques en arrière-plan est possible mais s’accompagne de plusieurs effets secondaires. Cela est dû au fait que les travailleurs Web ont un accès limité au DOM.
Nous avons montré comment contourner ces effets secondaires en transmettant des événements par proxy au Web Worker. Mais ensuite, il faut faire tout le travail, c’est-à-dire gérer ces événements avec leur propre implémentation personnalisée.
Merci d’avoir lu. Restez à l’écoute pour plus.