web-dev-qa-db-fra.com

Comment limiter d3.svg.axis à des étiquettes entières?

Existe-t-il une possibilité de limiter le nombre d'étiquettes entières d3.svg.axis affichées sur le graphique? Prenons par exemple ce graphique. Il n'y a que 5 tailles ici: [0, 1, 2, 3, 4]. Cependant, les graduations sont également affichées pour .5, 1.5, 2.5 et 3.5.

enter image description here

39
Gajus

Vous devriez pouvoir utiliser d3.format au lieu d'écrire votre propre fonction de formatage pour cela.

d3.svg.axis()
    .tickFormat(d3.format("d"));

Vous pouvez également utiliser tickFormat sur votre échelle que l'axe utilisera automatiquement par défaut.

59
Bill

J'ai réalisé qu'il suffit de cacher ces valeurs, plutôt que de les exclure complètement. Cela peut être fait en utilisant le tickFormat (https://github.com/mbostock/d3/wiki/Formatting#wiki-d3_format) comme tel:

d3.svg.axis()
    .tickFormat(function(e){
        if(Math.floor(e) != e)
        {
            return;
        }

        return e;
    });
17
Gajus

L'utilisation de d3.format("d") comme tickFormat peut ne pas fonctionner dans tous les scénarios ( voir ce bogue ). Sur les appareils Windows Phone (et probablement d'autres), des calculs imprécis peuvent conduire à des situations où les graduations ne sont pas correctement détectées en tant que nombres entiers, i. e. une coche de "3" peut être stockée en interne sous la forme 2.9999999999997 qui pour d3.format("d") n'est pas un nombre entier.

Par conséquent, l'axe ne s'affiche pas du tout. Ce comportement devient particulièrement apparent dans les plages de tiques jusqu'à 10.

Une solution possible consiste à tolérer l'erreur machine en spécifiant une valeur epsilon. Les valeurs n'ont pas besoin d'être des entiers exacts de cette façon, mais peuvent différer de l'entier suivant jusqu'à la plage epsilon (qui devrait être bien inférieure à votre erreur de données):

var epsilon = Math.pow(10,-7);

var axis = d3.svg.axis().tickFormat(function(d) {
    if (((d - Math.floor(d)) > epsilon) && ((Math.ceil(d) -d) > epsilon))
        return;
    return d;
}

Une autre solution, qui est également mentionnée dans d'autres threads, consiste à spécifier un nombre de graduations fixe, puis à arrondir les graduations (qui devraient désormais être "presque" des entiers) à l'entier le plus proche. Vous devez connaître la valeur maximale de vos données pour que cela fonctionne:

var axis = d3.svg.axis().ticks(dataMax).tickFormat(d3.format(".0f"))
5
Marcus Krahl