D3.js tutorial - Partie 9 - Redimensionner les graphiques

Supposons que l'on veuille maintenant étendre notre graphique à la largeur de la page. Commençons par ajouter le style CSS suivant à notre division principale afin que celle-ci s'étende sur tout la largeur de la page :

#bar-chart { width:100%; background-color:grey; }

Voici le résultat :

Bien sûr, ce n'est pas le résultat escompté. Comme nous avons fixé la taille du conteneur SVG, celui-ci ne peut pas s'adapter à la division. Mais nous allons améliorer ça!

Obtenir la taille du parent

Pour adpater notre graphique à la taille du parent, nous avons besoin de connaître sa taille. Celle-ci peut être récupéré soit avec la fonction style(), soit avec la fonction getBoundingClientRect().

La fonction style() retourne la valeur d'une propriété CSS. La ligne suivante retourne la lrgeur de la division bar-chart :

var width = d3.select("#bar-chart").style('width');

Par exemple, dans mon cas, la fonction retourne 385px. Le problème avec cette fonction est l'unité px qu'il faut retirer de la chaîne de caractères pour obtenir un entier :

var width = d3.select("#bar-chart").style('width');
width = parseInt(width);

La seconde option est d'appeler la fonction getBoundingClientRect() :

var size = d3.select('#bar-chart').node().getBoundingClientRect();

La fonction retourne un objet JavaScript contenent toutes les propriétés de la boite englobante. Par exemple :

DOMRect {
    x: 8
    y: 116.875
    width: 385
    height: 0
    top: 116.875
    right: 393
    bottom: 116.875
    left: 8
}

En sélectionnant uniquement la clé width on obtient la largeur de la division :

var width = d3.select('#bar-chart').node().getBoundingClientRect().width;

Dans mon cas, la fonction retourne 385 qui est un entier.

Redimenssioner le SVG

Une fois que la largeur est connue, nous pouvons redimenssioner notre conteneur SVG. Jusqu'à présent, la largeur de notre graphique était deux fois plus grande que sa hauteur. Nous allons conserver ce ratio et adapter la taille de notre conteneur SVG en conséquence :

var width = d3.select('#bar-chart').node().getBoundingClientRect().width;
var height = width/2;

// Create our SVG container with grey background
var svg = d3.select("#bar-chart")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

Voici le résultat:

Le conteneur SVG est redimenssioné, mais pas les barres du diagramme.

Redimenssionner les barres

Pour résoudre le problème précédent, une solution consisterait à calculer les propriétés de chaque barre en fonction des dimensions du conteneur SVG :

// Bind data to chart, and create bars
bars.selectAll('rect')
    .data(dataset)
    .enter()    
    .append('rect')
    .attr('x', (d,i) => i*(width/dataset.length) )
    .attr('y', (d) => height-d*(height/100))
    .attr('width', 0.8*(width/dataset.length))
    .attr('height', (d) => d*(height/100) );

Cela fonctionne, mais ce n'est pas la meilleure solution. En effet, D3.js propose de meilleurs outils pour redimmensionner les graphiques.

Voir aussi


Dernière mise à jour : 29/01/2020