Production Automatisée de
Graphiques, Statistiques et Documents
gilles.hunault "at" univ-angers.fr
-- prérequis : formats de fichiers et production automatisée de documents
Table des matières cliquable
1. Fichiers et formats de fichiers
2. Documents, tableaux et graphiques
3. Documents papier et pages Web
4. Outils logiciels pour la production automatisée de documents
1. Fichiers et formats de fichiers
Sans fichiers, l'informatique n'irait pas bien loin. Un fichier au format binaire brut (raw en anglais) est difficilement exploitable. On ne peut ni le lire ni le comprendre facilement. Un fichier au format texte est tout de suite accessible, interrogeable, éditable même s'il comporte plusieurs centaines ou plusieurs milliers de lignes.
Ainsi, le fichier listefichiers.sor.txt qui comporte 12600 lignes peut être consulté en ligne de commande avec des commandes comme ls, wc, head, tail, grep...
# informations système sur le fichier $gh> ls -al listefichiers.sor.txt -rw-rw-r-- 1 gh gh 464731 août 10 20:25 listefichiers.sor.txt # nombre de lignes dans le fichier $gh> wc -l listefichiers.sor.txt 12600 listefichiers.sor.txt # début du fichier $gh> head listefichiers.sor.txt 000001 . 000002 statgh.r.old 000003 valid.png 000004 css.gif 000005 internet 000006 internet/sen_valmax2.js 000007 internet/vertigo.gif 000008 internet/alien.jpg 000009 internet/diaporama_gen.php 000010 internet/jeudi5nov2009.php # fin du fichier (les 5 dernières lignes) $gh> tail -n 5 listefichiers.sor.txt 012596 Idas/leadb.txt 012597 Idas/anapred.mysql 012598 return.gif 012599 xhtml.png 012600 montresource.php # les lignes qui contiennent le mot guide $gh> grep guide listefichiers.sor.txt 008874 wstat/Eda/Stim/guide.php.old 008876 wstat/Eda/Stim/guide.php 009688 Pagsd/dotguide.pdf 010492 Idas/Wphylog/guidetree.pdfPour trouver des lignes dans ce fichier, à défaut de grep, il est possible d'éditer le fichier avec un simple éditeur de textes et d'utiliser le menu Edition/Rechercher.
Pour disposer de documents structurés, lisibles, mis en page, il faut recourir à Microsoft Office ou Open Office avec leurs formats DOC, XLS et plus récemment avec les formats DOCX, ODT, XLSX et ODS (qui sont des archives contenant des fichiers XML) mais l'édition au clavier et à la souris se révèle vite fastidieuse pour des documents importants. L'inclusion de fichiers-texte, par exemple issus de programmes informatiques, est un casse-tête avec ces logiciels alors que c'est un jeu d'enfants avec un navigateur ou avec un logiciel comme LaTeX.
Imaginez par exemple que vous vouliez mettre dans un document Microsoft Word le fichier resultats.txt qui est le résultat de l'exécution du programme calculs.php et obtenu par la commande
php calculs.php > resultats.txtOn peut soit faire un copier/coller du contenu du fichier soit utiliser une technique d'inclusion dans un document-maître. Ce n'est pas difficile. Mais si vous modifiez le programme, il est plus complexe de mettre à jour le document Microsoft Word : il faut sélectionner l'ancienne partie de document correspondant, la supprimer puis insérer le nouveau texte. Sans parler des manipulations s'il faut changer la police de caractères (par exemple pour utiliser une police non proportionnelle), ajouter la couleur, etc.
Lorsqu'on utilise HTML ou LaTeX, il n'y a pas lieu de refaire ce genre de manipulation parce que le rendu est assuré à la volée, au moment où on demande la visualisation (HTML) ou la composition (LaTeX) il s'agit donc d'un processus dynamique de mise en forme et de mise en page sans interaction clavier ou souris. La généralisation de formats-texte, de vérification et de transformation par programme s'est concrétisée depuis le début des années 2000 par l'installation progressive de XML et ses technologies DTD, XSD, XSL.
2. Documents, tableaux et graphiques
Si la notion de fichier est essentielle en informatique de programmation, celle de document est fondamentale en informatique de communication. Un document orienté communication est un fichier structuré, mis en page. Il inclut souvent des tableaux, des images, des informations et des commentaires ou des interprétations. Mettre en page un tableau en respectant les normes de l'édition ou de l'imprimerie comme la justification à droite des nombres et la justification à gauche pour les textes (comme dans l'affichage standard sous Microsoft Excel) n'est pas en soi compliqué : Microsoft Word sait le faire en automatique et fournit des menus et des icones pour le faire, HTML dispose d'attributs comme align ou de propriétés CSS comme text-align. Encore faut-il appliquer ces mises en forme sur tous les éléments.
C'est là où la programmation de tels documents prend tout son sens : il suffit de savoir programmer la lecture d'un fichier-texte qui contient les informations et l'écriture d'un fichier-texte qui ajoute les codes, marqueurs ou balises pour justifier les informations et le tour est joué !
Ainsi, le texte original qui suit (fichier logement.txt)
LIEU MI70 MX70 MI80 MX80 MI82 MX82 MI86 MX86 MI88 MX88 PARI 24.0 41.0 102.0 156 120 200 220 280 230 350 PA07 38.0 61.0 145.0 180 160 300 300 400 380 450 MARS 14.0 22.0 45.0 68 62 100 75 110 70 130 LYON 12.0 20.0 32.0 60 50 110 85 120 60 125 TOLO 12.0 25.0 35.0 62 39 108 65 120 95 125 NICE 20.0 47.0 60.0 140 71 200 75 300 65 300 NANT 9.5 28.0 34.0 70 49 93 65 120 55 120 STRA 12.0 28.0 48.0 72 55 90 55 115 56 130 BORD 15.0 17.0 45.0 70 45 80 60 100 65 140 MNTP 9.5 22.0 50.0 74 60 100 65 100 65 125 AIXP 14.0 17.5 59.0 90 47 114 55 130 55 145 NANC 12.5 19.0 39.0 70 50 95 45 100 60 115 PRPG 9.5 16.0 43.0 68 58 100 70 110 60 110 STLR 14.0 15.0 40.0 56 60 75 80 120 85 135 LROU 13.0 17.0 57.0 71 85 95 75 120 100 135 ANTB 15.0 25.0 50.0 100 82 217 90 300 90 300 CANN 15.0 39.0 75.0 270 130 370 80 500 80 450 STMX 15.0 24.0 60.0 85 90 160 80 170 70 160 AR/M 12.0 18.0 48.0 60 60 100 70 120 70 140 LGrM 12.0 25.0 35.0 90 56 122 75 130 80 140 Arca 18.0 22.0 57.0 107 65 156 90 165 95 165 Roya 15.0 20.0 50.0 90 62 138 90 160 100 150 BAUL 14.0 28.0 70.0 120 70 160 100 250 120 270 DEAU 14.0 20.0 55.0 100 71 120 65 160 70 160est illisible ou très peu lisible avec un rendu "brut" dans un navigateur :
Affichage brut :
LIEU MI70 MX70 MI80 MX80 MI82 MX82 MI86 MX86 MI88 MX88 PARI 24.0 41.0 102.0 156 120 200 220 280 230 350 PA07 38.0 61.0 145.0 180 160 300 300 400 380 450 MARS 14.0 22.0 45.0 68 62 100 75 110 70 130 LYON 12.0 20.0 32.0 60 50 110 85 120 60 125 TOLO 12.0 25.0 35.0 62 39 108 65 120 95 125 NICE 20.0 47.0 60.0 140 71 200 75 300 65 300 NANT 9.5 28.0 34.0 70 49 93 65 120 55 120 STRA 12.0 28.0 48.0 72 55 90 55 115 56 130 BORD 15.0 17.0 45.0 70 45 80 60 100 65 140 MNTP 9.5 22.0 50.0 74 60 100 65 100 65 125 AIXP 14.0 17.5 59.0 90 47 114 55 130 55 145 NANC 12.5 19.0 39.0 70 50 95 45 100 60 115 PRPG 9.5 16.0 43.0 68 58 100 70 110 60 110 STLR 14.0 15.0 40.0 56 60 75 80 120 85 135 LROU 13.0 17.0 57.0 71 85 95 75 120 100 135 ANTB 15.0 25.0 50.0 100 82 217 90 300 90 300 CANN 15.0 39.0 75.0 270 130 370 80 500 80 450 STMX 15.0 24.0 60.0 85 90 160 80 170 70 160 AR/M 12.0 18.0 48.0 60 60 100 70 120 70 140 LGrM 12.0 25.0 35.0 90 56 122 75 130 80 140 Arca 18.0 22.0 57.0 107 65 156 90 165 95 165 Roya 15.0 20.0 50.0 90 62 138 90 160 100 150 BAUL 14.0 28.0 70.0 120 70 160 100 250 120 270 DEAU 14.0 20.0 55.0 100 71 120 65 160 70 160
Un simple ajouts de marqueurs en PHP via les instructions du fichier logement.php suivant :
<?php error_reporting(E_ALL | E_NOTICE | E_STRICT) ; # chargement de fonctions usuelles pour le Web, # voir http://www.info.univ-angers.fr/~gh/internet/stdphp.php # pour plus de détails include_once("std.php") ; ####################################################################################### function tableauFichier($fn,$dec="") { ####################################################################################### # # cette fonction affiche sous forme de tableau HTML un fichier .dar # le paramètre $dec contient un codage pour chacune des colonnes : # L pour justification à gauche # C pour justification centrée # x (numérique) pour justification à droite avec x décimales if (!file_exists($fn)) { h3(" Fichier $fn non vu") ; } else { $fh = fopen($fn,"r") ; table(1,10,"collapse") ; echo"\n" ; $nbl = 0 ; while (!feof ($fh)) { $lig = fgets($fh, 4096) ; if (strlen(trim($lig))>0) { $nbl++ ; tr() ; if ($nbl==1) { $entete = preg_split("/\s+/",(trim($lig))) ; foreach ($entete as $idc) { th("C","","","",0) ; echo $idc ; finth() ; } ; # fin pour chaque } else { $lignorm = preg_split("/\s+/",(trim($lig))) ; $jdc = -1 ; foreach ($lignorm as $idc) { $jdc++ ; $cdf = substr($dec,$jdc,1) ; $mef = $cdf ; $vdc = $idc ; if (is_numeric($cdf)) { $mef = "R" ; $vdc = sprintf("%0.".$cdf."f",$idc) ; } ; # fin si cmt($mef) ; td($mef,"","","",0) ; echo $vdc ; fintd() ; } ; # fin pour chaque } ; # fin si fintr() ; } ; # fin si } ; # fin tant que fintable() ; } ; # fin si } ; # fin de fonction tableauFichier ####################################################################################### tableauFichier("logement.txt","L".copies("2",10)) ; ?>aboutit à un texte XHTML tout-à-fait lisible via son rendu dans un navigateur.
Code XHTML produit par la commande php logement.php > logement.html, soit le fichier logement.html (extrait) :
<table border="1" cellpadding="10" class='collapse' summary="?" > <tr> <tr> <th align='center'>LIEU</th> <th align='center'>MI70</th> <th align='center'>MX70</th> ... </tr> <tr> <td align='left'>PARI</td> <td align='right'>24.00</td> <td align='right'>41.00</td> ... </tr> </table>Rendu (extrait) :
LIEU MI70 MX70 MI80 MX80 MI82 MX82 MI86 MX86 MI88 MX88 PARI 24.00 41.00 102.00 156.00 120.00 200.00 220.00 280.00 230.00 350.00 PA07 38.00 61.00 145.00 180.00 160.00 300.00 300.00 400.00 380.00 450.00 MARS 14.00 22.00 45.00 68.00 62.00 100.00 75.00 110.00 70.00 130.00 ... BAUL 14.00 28.00 70.00 120.00 70.00 160.00 100.00 250.00 120.00 270.00 DEAU 14.00 20.00 55.00 100.00 71.00 120.00 65.00 160.00 70.00 160.00 De plus un document Web est accessible par programme. Ainsi le fichier logement2.html peut être interrogé et analysé par ce simple script R :
# chargement du package XML library(XML) # lecture de la table numéro 1 dans la page Web url <- "http://forge.info.univ-angers.fr/~gh/Pagsd/logement2.html" logement <- readHTMLTable(url,which=1,header=TRUE, colClasses = c("character", rep("integer", 10))) # moyennes par colonne, affichage avec une décimale cat("Moyennes par année, en min et max (unité=F)\n\n") round( apply(X=logement[,-1], MARGIN=2, FUN=mean) , 1 )pour produire les résultats suivants :
Moyennes par année, en min et max (unité=F) MI70 MX70 MI80 MX80 MI82 MX82 MI86 MX86 MI88 MX88 14.9 25.7 55.6 97.0 70.7 141.8 88.8 179.2 94.8 190.4Pour les graphiques, si PNG ext un bon format binaire d'export, SVG est un format-texte ouvert, programmable, interrogeable, animable via Javascript notamment. Vous pouvez par exemple cliquer sur le rectangle rouge ou le cercle vert et le déplacer à l'aide de la souris en tenant le bouton gauche dans le dessin ci-dessous (adapté de pilat[...]bouger) :
Codes-source : SVG ; Javascript.
Disposer des informations en format texte (quitte à ce que ce soit par exportation d'une base de données) laisse la possibilité de les analyser, de les visualiser. Le logiciel R est sans doute un excellent choix pour passer des données initiales à des statitiques résumés et à des graphiques de visualisation. Et si les données sont au départ au format XML, il suffit d'utiliser des transformations XSL pour obtenir un format texte, XML ou XHTML.
3. Documents papier et pages Web
La diffusion des documents avant les années 2000 se faisait presque exclusivement via des documents papier, que ce soit sous forme de livres ou de photocopies. La révolution du Web a modifié les modes de diffusion. En particulier les documents HTML ou "pages Web" ont inversé le schéma de distribution : au lieu de diffuser des contenus, on les met à disposition. C'est à l'utilisateur de venir les chercher.
La volonté de partager des documents modifiables entre collaborateurs avec des ordinateurs différents a débouché sur les formats portables RTF pour les documents Word et CSV pour les tableaux de données des feuilles Excel, sur la généralisation de HTML comme langage de traitement de textes et de mise en forme pour le Web, sur l'installation massive de systèmes AMP (Apache, Mysql Php) et de façon moins immédiate pour le grand public, de XML comme métalangage de formats ouverts pour tous les documents structurés.
Avec tous ces formats-textes, il est possible d'écire des documents en utilisant n'importe quel langage de programmation car il suffit d'écrire de codes, des marqueurs, des balises, voire juste des points-virgules pour fournir un fichier importable et convertible. MySQL lui-même sait exporter dans les formats HTML et XML comme on peut le voir sur cet extrait de sortie de l'aide de MySQL :
mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3 Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Usage: mysql [OPTIONS] [database] -H, --html Produce HTML output. -X, --xml Produce XML output.Produire des documents "informationnels" à l'aide de programmes informatiques est donc une activité assez simple qui demande seulement de savoir quels marqueurs programmer et où les insérer dans les fichiers-texte pour obtenir le rendu souhaité. Toutefois, les mettre à disposition sur le Web dans un format autre que PDF ou non imprimable directement mène à des changements notables dans les documents.
La première plus grande différence entre un document papier et un document Web est la notion de page. Une page physique, que ce soit au format letter US ou A4 impose des contraintes précises de mise en page alors qu'un document Web peut se contenter d'afficher en continu, sans limite de taille horizontale ou verticale. Les navigateurs Web sont devenus en quelque sorte des visualiseurs universels, capables d'afficher des fichiers-textes très longs comme ce fichier de 401 975 lignes. Ou encore cet autre fichier de 8002 colonnes. Bien configurés, les navigateurs affichent des textes, des images, des animations et viennent déléguer aux logiciels installés les fichiers plus techniques comme des documents Word ou des documents Excel.
La deuxième plus grande différence entre un document papier et un document Web est la notion d' interactivité. Ainsi, la programmation des pages Web permet de mettre en ligne des contenus issus de bases de données ou de programmes complexes dont les entrées sont lues dans des formulaires.
4. Outils logiciels pour la production automatisée de documents
4.1 Graphviz et dot
Pour produire des graphiques complexes mais structurés comme des graphes (au sens informatique du terme) dont des arbres informatiques, une suite logicielle comme Graphviz et en particulier son programme et langage dot suffit. L'écriture des fichiers associés, de type .dot ou, mieux, pour éviter un conflit avec les fichiers de modèles de Microsoft Word, de type .gv ou .gv.txt se fait soit avec un simple éditeur de textes soit en programmant les instructions de dot... N'importe quel langage de programmation convient pour cela, mais un langage de script est sans doute plus adapté qu'un langage compilé traditionnel.
Voici par exemple le texte d'un fichier DOT qui correspond à un graphe complet pour 3 sommets nommés A, B et C :
digraph triangle { A -> B B -> C C -> A }Et son rendu en PNG, sachant que c'est le logiciel DOT qui choisit les coordonnées de tracé :
Les options de DOT permettent une gestion fine du placement des noeuds :
digraph triangle { A -> B B -> C C -> A { rank=same ; B ; C ; } }4.2 SVG
Pour des graphiques plus généraux, un langage de description vectoriel 2D comme SVG est un bon choix. Technique mais simple car SVG est un format XML, on peut écrire du SVG avec un éditeur de textes, avec le logiciel Inkscape ou par programme. On peut animer du SVG avec Javascript comme on peut le voir ici.
Voici par exemple le texte d'un fichier SVG qui correspond à un mini-échiquier de 3x3 :
<?xml version="1.0" encoding="latin1" ?> <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" > <!-- le cadre --> <rect x="000" y="000" width="300" height="300" fill="white" stroke="black" stroke-width="10" /> <!-- la case en haut et à gauche est blanche, pas besoin de la tracer --> <!-- la case suivante à sa droite est noire --> <rect x="100" y="000" width="100" height="100" fill="black" stroke="black" stroke-width="1" /> <!-- deuxième ligne, deux cases noires --> <rect x="000" y="100" width="100" height="100" fill="black" stroke="black" stroke-width="1" /> <rect x="200" y="100" width="100" height="100" fill="black" stroke="black" stroke-width="1" /> <!-- troisème ligne, une seule case noire au milieu --> <rect x="100" y="200" width="100" height="100" fill="black" stroke="black" stroke-width="1" /> </svg>Et voici son rendu une fois exporté en PNG (le "vrai" SVG est ici) :
4.3 Le logiciel R
Pour réaliser des calculs statistiques et des graphiques statistiques, le logiciel R ou "CRAN software" et son langage de programmation est certainement l'outil le plus adapté.
Voici par exemple le texte d'un script R qui affiche l'histogramme des fréquences de codes-sexe :
codes.sexe <- factor( c(1,1,1,2,2),labels=c("hommes","femmes") ) barplot( table(codes.sexe), col="yellow", main="Répartition par genre")Et l'image produite :
Bien sûr rien n'empêche de produire un script R à la volée, par exemple via un script PHP comme dans la page LEADB.
Avec ses milliers de packages (plus de 5800 en juillet 2014), R permet aussi de traiter de nombreux calculs autant informatiques que statistiques. Voici en quatre instructions comment tracer le graphe complet précédent :
# chargement du package pour les graphes library(igraph) # création du graphe via ses arcs triangle <- graph( edges=c(1,2,2,3,3,1) ) # ajout du nom des sommets V(triangle)$names <- c("A","B","C") # tracé du graphe plot(triangle) # appel indirect de plot.igraphEt l'image produite :
4.4 LATEX
Pour des documents à imprimer ou à rendre sous un format PDF, le logiciel LaTeX est le meilleur outil. Utilisé au niveau professionnel dans l'imprimerie, il est assez technique à maitriser mais tellement complet qu'on ne peut pas lui en vouloir. Historiquement prévu pour écrire des documents mathématiques, on s'en sert aujourd'hui pour produire des documents de qualité.
Le code LaTeX suivant montre la formule de la correction relativiste. Le fichier PDF résultat est ici.
% # (gH) -_- unt.tex ; TimeStamp (unix) : 06 Août 2014 vers 12:45 \documentclass[12pt,a4paper]{article} %\usepackage[french]{babel} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage[dvips]{graphicx} \usepackage{amsmath} \usepackage[usenames,dvipsnames,svgnames,table]{xcolor}% mieux que \usepackage{color} \newcommand{\cmt}[1]{} \def\bs{\texttt{\symbol{'134}}}% pour écrire simplement backslash via \bs \parindent 0.0cm \parskip 0.25cm \definecolor{rougeGH}{HTML}{880000} \definecolor{vertGH}{HTML}{008800} \begin{document} \begin{center} {\Large Exemple de \textsc{CODE} pour \LaTeX}\\[3cm] \end{center} \section*{La correction relativiste} Au lieu de la formule $\textcolor[HTML]{000088}{\mathbf{E=mc^2}}$, il faut utiliser $$ \boxed{ E = \frac{mc^2}{\sqrt{1-v^2/c^2}} = \frac{mc^2}{\sqrt{1-\frac{v^2}{c^2}}} }% fin de boxed $$ sans doute \textbf{plus lisible} sous la forme $$ \displaystyle E = \frac{mc^2} {\textcolor{vertGH}{\sqrt{\displaystyle \mathbf{1-\frac{v^2}{c^2}}}}} = \frac{mc^2} {\textcolor{rougeGH}{\sqrt{\displaystyle \mathbf{1-\left(\frac{v}{c}\right)^2}}}} $$ \thispagestyle{empty} \end{document}Voici une copie-écran du rendu :
Le système de base de LaTeX est complété par de nombreux packages dont l'un des plus connus est PSTricks. Revoici le graphe complet sur les trois sommets A, B et C avec ce package :
% # (gH) -_- unt.tex ; TimeStamp (unix) : 06 Août 2014 vers 12:45 \documentclass[12pt,a4paper]{article} %\usepackage[french]{babel} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage[dvips]{graphicx} \usepackage{pstricks,pst-node,pst-text,pst-3d,pst-tree} \newcommand{\cmt}[1]{} \def\bs{\texttt{\symbol{'134}}}% pour écrire simplement backslash via \bs \parindent 0.0cm \parskip 0.25cm \definecolor{rougeGH}{HTML}{880000} \definecolor{vertGH}{HTML}{008800} \begin{document} \thispagestyle{empty} \begin{figure} \begin{center} \psset{arrows=->,mnode=circle} \psset{arrowscale=3} \begin{psmatrix} & [name=A,fillstyle=solid,fillcolor=orange] A \\[0.5cm] [name=B,fillstyle=solid,fillcolor=orange] B & & [name=C,fillstyle=solid,fillcolor=orange] C \\[0.5cm] \end{psmatrix} \ncline{A}{B} \ncline{B}{C} \ncline{C}{A} \end{center} \end{figure} \end{document}Et son rendu :
4.5 Sweave
Comme LaTeX dispose de commandes de programmation rudimentaires, le couplage de LaTeX et d'un langage de scripts se révèle en général très efficace. En particulier le couple LaTeX+R est un bon compromis pour pallier à la faiblesse des affichages de R. Ce couplage est notamment intégré dans Sweave. On trouve un exemple de "gros" manuel produit par Sweave à l'adresse leadb stats part 2. Voici un extrait du code correspondant qui montre bien le mélange LaTeX et R :
\documentclass[a4paper]{article} \def\ghversion{2.31} \usepackage{Sweave} \usepackage{etex} \begin{document} \SweaveOpts{concordance=FALSE,echo=FALSE,eps=TRUE,pdf=TRUE} \begin{center} {\LARGE MANUAL OF STATISTICAL ANALYSIS\\[0.5cm] \textsc{FOR THE LEADB PROTEINS} \\[0.5cm] \textsc{ } \\[0.5cm] \textsc{} \\[3cm] }% fin de LARGE \end{center} <<fig=FALSE,display=TRUE,labe=tout,results=tex>>= source("leaman.r") leamanual(1,1) @ \newpage <<fig=FALSE,display=TRUE,labe=tout,results=tex>>= leamanual(2,1) @ \newpage \end{document}4.6 PHP, Javascript et leurs bibliothèques de fonctions
Pour le Web, des outils de tracé à la volée sont disponibles, notamment via Javascript et PHP. Outre les bibliothèques généralistes comme jpgraph et raphael, deux bibliothèques basées sur le même concept de data driven documents sont, selon nous, à connaitre absolument : protovis et d3js.
Voici un exemple de tracé avec raphael (voir raphael.php pour les codes-source) :
Retour à la page principale de (gH)