Modifions les données que nous allons utiliser en considérant un tableau contenant des tableaux :


var tab=[[5,3],[15,4],[3,10],[8,5],[20,8]]
			

tab[0] correspond au tableau [5,3] (le premier élément du tableau tab est un tableau ([5,3])). tab[0][0] correspond à la valeur 5 alors que tab[0][1] correspond à la valeur 3.

À faire vous même 7.1

À quelle valeur correspond tab[2][1] ?


Chaque tableau contenu dans le tableau tab est un couple de valeur. Un couple de valeur peut être vu comme un point. Par exemple, tab[1] peut être considéré comme un point d'abscisse 15 et d'ordonnée 4.

D3 peut nous permettre d'afficher ces différents points (on parle de nuage de points).

À faire vous même 7.2

script.js


var tab=[[5,3],[15,4],[3,10],[8,5],[20,8]]
var body=d3.select("body");
var svg=body.append("svg");
svg.attr({"width":"400px","height":"400px"})
svg.style("border","1px solid black");
svg.selectAll("circle")
    .data(tab)
    .enter()
    .append("circle")
    .attr({"r":"3px","fill":"black","stroke":"black"})
    .attr("cx",function(d,i){
        return (d[0]);
    })
    .attr("cy",function(d,i){
        return (d[1]);
    });
        

Testez ce code.


Quelques remarques sur le code ci-dessus :

Vous devez bien comprendre que dans les deux fonctions anonymes (pour "cx" et "cy") d va prendre les différentes valeurs contenues dans le tableau tab : pour l'affichage du premier cercle d sera égal à [5,3], pour l'affichage du second cercle d sera égal à [15,4]...

Il est évident que cette représentation n'est pas satisfaisante, nous avons principalement deux problèmes :

Le second problème est très simple à résoudre : la fonction associée à l'attribut cy doit renvoyer 400-d[1] à la place de d[1] (400 étant la hauteur de la fenêtre en pixels).

À faire vous même 7.3

script.js


var tab=[[5,3],[15,4],[3,10],[8,5],[20,8]]
var body=d3.select("body");
var svg=body.append("svg");
svg.attr({"width":"400px","height":"400px"})
svg.style("border","1px solid black");
svg.selectAll("circle")
    .data(tab)
    .enter()
    .append("circle")
    .attr({"r":"3px","fill":"black","stroke":"black"})
    .attr("cx",function(d,i){
        return (d[0]);
    })
    .attr("cy",function(d,i){
        return (400-d[1]);
    });
        

Testez ce code.


L'autre problème est visiblement plus complexe à résoudre puisqu'il fait appel à la notion d'échelle (le choix des échelles à appliquer lors de la construction d'un graph sur papier, est, très souvent, un véritable problème pour beaucoup d'élèves).

Pour déterminer une échelle, il nous faut 2 informations :

Prenons un exemple : imaginons des valeurs comprises entre 0 et 200 et une feuille de 20 cm de largeur disponible. Dans ce cas le choix est relativement simple, nous prendrons 1 cm pour 10.

D3 vous permet d'automatiser tout cela.

Nous allons dans un premier temps définir une variable (qui sera en faite une fonction) qui sera égal à d3.scale.linear()


var echelle=d3.scale.linear();
        

Il faudra ensuite appliquer 2 méthodes à echelle :

Nous ne parlerons pas ici de "feuille" mais de "fenêtre svg". De même nous n'allons pas gérer des centimètres, mais plutôt des pixels.

Nous avons 2 axes, il nous faudra donc 2 échelles : une pour les ordonnées et l'autre pour les abscisses.

À faire vous même 7.4

script.js


var tab=[[5,3],[15,4],[3,10],[8,5],[20,8]]
var body=d3.select("body");
var echelleX=d3.scale.linear();
echelleX.domain([3,20]);
echelleX.range([30,370]);
var echelleY=d3.scale.linear();
echelleY.domain([3,10]);
echelleY.range([30,370]);
var svg=body.append("svg");
svg.attr({"width":"400px","height":"400px"})
svg.style("border","1px solid black");
svg.selectAll("circle")
    .data(tab)
    .enter()
    .append("circle")
    .attr({"r":"3px","fill":"black","stroke":"black"})
    .attr("cx",function(d,i){
        return (echelleX(d[0]));
    })
    .attr("cy",function(d,i){
        return (370-echelleY(d[1]));
    });
        

Testez ce code.


Afin d'éviter d'avoir des points "collés" sur les bords de la fenêtre (en haut, en bas, à droite et à gauche), nous avons limité la portion de fenêtre qui accueillera les points (range([30,370])) : nous trouverons des points uniquement entre l'abscisse 30 et l'abscisse 370 de notre fenêtre (même chose pour l'ordonnée).

Il est possible d'utiliser la notation pointée afin de réduire la taille du code :


var tab=[[5,3],[15,4],[3,10],[8,5],[20,8]]
var body=d3.select("body");
var echelleX=d3.scale.linear()
                .domain([3,20])
                .range([30,370]);
var echelleY=d3.scale.linear()
                .domain([3,10])
                .range([30,370]);
var svg=body.append("svg");
svg.attr({"width":"400px","height":"400px"})
svg.style("border","1px solid black");
svg.selectAll("circle")
    .data(tab)
    .enter()
    .append("circle")
    .attr({"r":"3px","fill":"black","stroke":"black"})
    .attr("cx",function(d,i){
        return (echelleX(d[0]));
    })
    .attr("cy",function(d,i){
        return (370-echelleY(d[1]));
    });
        

Il est possible d'éviter le 370-echelleY(d[1]) en mettant range([370,30]) à la place de range([30,370]) pour l'échelle y.