web-dev-qa-db-fra.com

Tableaux / graphiques interactifs rapides et réactifs: SVG, Canvas, autres?

J'essaie de choisir la bonne technologie à utiliser pour mettre à jour un projet qui, en gros, restitue des milliers de points dans un graphique zoomable et analysable. L'implémentation actuelle, utilisant Protovis, est sous-performante. Vérifiez le ici:

http://www.planethunters.org/classify

Il y a environ 2000 points lorsque vous effectuez un zoom arrière. Essayez d’utiliser les poignées du bas pour effectuer un zoom avant et faites-le glisser pour vous déplacer. Vous constaterez qu'il est assez instable et que l'utilisation de votre processeur atteint probablement 100% sur un seul cœur, à moins que vous n'ayez un ordinateur très rapide. Chaque modification de la zone de mise au point appelle une mise au point vers protovis, ce qui est sacrément lent et pire encore avec plus de points.

J'aimerais apporter des mises à jour à l'interface et changer la technologie de visualisation sous-jacente pour qu'elle soit plus réactive avec l'animation et les interactions. D'après l'article suivant, il semble que le choix soit entre une autre bibliothèque basée sur SVG ou une bibliothèque basée sur une zone de travail:

http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/

d3.js , issu de Protovis, est basé sur SVG et est censé être meilleur pour le rendu des animations . Cependant, je doute que son rendement soit meilleur et meilleur. Pour cette raison, j’envisage également une refonte plus complète en utilisant une bibliothèque basée sur la toile telle que KineticJS . Cependant, avant de trop m'appliquer à une approche ou à une autre, j'aimerais entendre quelqu'un qui a créé une application Web similaire avec autant de données et obtenir son opinion.

Le facteur le plus important est la performance, l’accent étant mis sur la facilité d’ajout d’autres fonctionnalités d’interaction et la programmation de l’animation. Il n'y aura probablement pas plus de 2000 points à la fois, avec ces petites barres d'erreur sur chacun d'eux. Le zoom avant, arrière et le survol doivent être lisses. Si les bibliothèques SVG les plus récentes sont correctes, alors peut-être que la facilité d'utilisation de d3 facilitera l'emporte sur la configuration accrue de KineticJS, etc. Mais s'il y a un avantage énorme en termes de performances à utiliser une toile, en particulier pour les utilisateurs d'ordinateurs plus lents, je préférerais définitivement aller de cette façon.

Exemple d'application créée par le NYTimes qui utilise SVG, mais continue à animer de manière acceptable: http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering -compares.html . Si je peux obtenir cette performance et ne pas avoir à écrire mon propre code de dessin sur toile, je choisirais probablement SVG.

J'ai remarqué que certains utilisateurs ont utilisé un hybride de manipulation de d3.js combinée avec un rendu canvas . Cependant, je ne peux pas trouver beaucoup de documentation à ce sujet en ligne ou entrer en contact avec le PO de ce post. Si quelqu'un a une expérience quelconque de ce type d'implémentation de DOM-to-Canvas ( démo , code ), j'aimerais également avoir de vos nouvelles. Cela semble être un bon hybride, à savoir pouvoir manipuler des données et avoir un contrôle personnalisé sur la manière de les restituer (et donc les performances), mais je me demande si le fait de tout charger dans le DOM va encore ralentir les choses.

Je sais qu'il existe des questions similaires à celle-ci, mais aucune ne pose exactement la même chose. Merci de votre aide.

Suivi : l'implémentation que j'ai finalement utilisée est à https://github.com/zooniverse/LightCurves

112
Andrew Mao

Heureusement, dessiner 2000 cercles est un exemple assez facile à tester. Voici donc quatre implémentations possibles, deux de Canvas et de SVG:

Ces exemples utilisent D3 comportement du zoom pour implémenter le zoom et le panoramique. Indépendamment du fait que les cercles soient rendus en Canvas ou en SVG, l’autre distinction majeure est de savoir si vous utilisez géométrique ou sémantique zoom.

Le zoom géométrique signifie que vous appliquez une seule transformation à l’ensemble de la fenêtre: lorsque vous effectuez un zoom avant, les cercles deviennent plus grands. Le zoom sémantique en contraste signifie que vous appliquez des transformations à chaque cercle individuellement: lorsque vous effectuez un zoom avant, les cercles conservent la même taille mais s’étalent. Planethunters.org utilise actuellement le zoom sémantique, mais il pourrait être utile de considérer d'autres cas.

Le zoom géométrique simplifie la mise en œuvre: vous appliquez une translation et une mise à l'échelle une fois, puis tous les cercles sont restitués. L'implémentation SVG est particulièrement simple, mettant à jour un seul attribut "transform". Les performances des deux exemples de zoom géométrique semblent plus que suffisantes. Pour le zoom sémantique, vous remarquerez que D3 est nettement plus rapide que Protovis. Ceci est dû au fait que cela fait beaucoup moins de travail pour chaque événement de zoom. (La version Protovis doit recalculer tous les attributs de tous les éléments.) Le zoom sémantique basé sur Canvas est un peu plus rapide que le format SVG, mais le zoom sémantique SVG est toujours réactif.

Pourtant, il n’ya pas de solution miracle pour la performance et ces quatre approches possibles ne commencent pas à couvrir tout l’espace des possibilités. Par exemple, vous pouvez combiner zoom géométrique et sémantique, en utilisant l'approche géométrique pour le panoramique (mise à jour de l'attribut "transformer") et en ne retraçant que les cercles individuels lors du zoom. Vous pouvez probablement même combiner une ou plusieurs de ces techniques avec des transformations CSS3 pour ajouter une accélération matérielle (comme dans exemple de regroupement Edge hiérarchique ), bien que cela puisse être délicat à implémenter et introduire des artefacts visuels.

Néanmoins, ma préférence personnelle est de conserver autant que possible en SVG et d’utiliser Canvas uniquement pour la "boucle interne" lorsque le rendu est le goulot d’étranglement . SVG a tellement de commodités pour le développement - telles que CSS, les jointures de données et l'inspecteur d'élément - qu'il est souvent trop tôt d'optimiser commencer par Canvas. La combinaison de Canvas avec SVG, comme dans la visualisation IPO de Facebook que vous avez liée, constitue un moyen flexible de conserver la plupart de ces commodités tout en vous offrant les meilleures performances. J'ai également utilisé cette technique dans Cubism.js , où le cas particulier de la visualisation chronologique se prête bien à la mise en cache bitmap.

Comme le montrent ces exemples, vous pouvez utiliser D3 avec Canvas, même si certaines parties de D3 sont spécifiques à SVG. Voir aussi ceci graphe dirigé par la force et ceci exemple de détection de collision .

181
mbostock

Je pense que dans votre cas , le choix entre canvas et svg ne ressemble pas à un choix entre "conduire un cheval" ou conduire une "Porsche". Pour moi, cela ressemble plus à la décision concernant la couleur des voitures.

Permettez-moi de vous expliquer: En supposant que, sur la base du cadre des opérations

  • dessiner une étoile,
  • ajouter une étoile et
  • enlever une étoile

prendre du temps linéaire. Donc, si votre décision du cadre était bonne, elle est un peu plus rapide, sinon un peu plus lente.

Si vous continuez à supposer que le cadre est juste rapide, il devient alors tout à fait évident que le manque de performances est causé par le nombre élevé d'étoiles et que le traitement de ces étoiles est quelque chose qu'aucun des cadres ne peut faire pour vous, du moins je ne sais pas à propos de ça.

Ce que je veux dire, c’est que la base du problème mène à un problème fondamental de géométrie algorithmique, à savoir: recherche de plage et un autre d’infographie: niveau de détail .

Pour résoudre votre problème de performances, vous devez implémenter un bon pré-processeur capable de trouver très rapidement les étoiles à afficher et de regrouper peut-être des étoiles proches les unes des autres, en fonction du zoom. La seule chose qui garde votre vue vive et rapide est de garder le nombre d'étoiles à dessiner aussi bas que possible.

Comme vous l'avez dit, le facteur le plus important est la performance, ce que j'aurais tendance à utiliser canvas, car cela fonctionne sans opérations DOM. Il offre également la possibilité d'utiliser webGL, ce qui augmente considérablement les performances graphiques.

BTW: avez-vous vérifié paper.js ? Il utilise canvas, mais émule des graphiques vectoriels.

PS: Dans ce livre vous pouvez trouver une discussion très détaillée sur les graphiques sur le Web, les technologies, les avantages et les inconvénients de canvas, SVG et DHTML.

8
philipp

J'ai récemment travaillé sur un tableau de bord presque en temps réel (actualisé toutes les 5 secondes) et choisi d'utiliser des graphiques rendus à l'aide de la zone de dessin.

Nous avons essayé Highcharts (bibliothèque de graphiques JavaScript basée sur SVG) et CanvasJS (bibliothèque de graphiques JavaScript à base de toile). Bien que Highcharts soit une API de cartographie fantastique et offre bien plus de fonctionnalités, nous avons décidé d'utiliser CanvasJS.

Nous devions afficher au moins 15 minutes de données par graphique (avec possibilité de choisir une plage de deux heures maximum).

Donc, pendant 15 minutes: 900 points (points de données par seconde) x2 (graphique de combinaison de lignes et de barres) x4 graphiques = total de 7 200 points.

Avec chrome profiler, avec CanvasJS, la mémoire ne dépassait jamais 30 Mo, tandis qu'avec Highcharts, l'utilisation de la mémoire dépassait 600 Mo.

De plus, avec un temps d'actualisation de 5 secondes, le rendu CanvasJS était beaucoup plus réactif que les graphiques en Highcharts.

Nous avons utilisé un minuteur (setInterval 5 secondes) pour effectuer 4 REST) permettant d'extraire les données du serveur principal connecté à Elasticsearch. Chaque graphique mis à jour à mesure que les données sont reçues par JQuery.post () .

Cela dit, pour les rapports hors ligne, je choisirais Highcharts car son API était plus flexible.

Il existe également des graphiques Zing qui prétendent utiliser SVG ou Canvas mais ne les ont pas consultés.

La toile doit être considérée lorsque les performances sont vraiment critiques. SVG pour la flexibilité. Ce n’est pas que les frameworks de canvas ne soient pas flexibles, mais cela demande beaucoup de travail pour obtenir la même fonctionnalité qu’un framework svg.

7
user432024

Vous pouvez également vous pencher sur Meteor Charts, qui s’appuie sur le cadre ultra rapide de KineticJS: http://meteorcharts.com/

3
Eric Rowell