J'essaie de produire des tiques pour scaleLog().base(2). Il semble que cela ne fonctionne pas correctement. Par exemple, pour l'appel :

d3.scaleLog().base(2).domain([50,500]).ticks(10)

J'ai eu:

[ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500 ]

Qui ne sont que des tiques placées linéairement. Pour la base (10), cela fonctionne correctement.

d3.scaleLog().base(10).domain([50,500]).ticks(10)
[ 50, 60, 70, 80, 90, 100, 200, 300, 400, 500 ]

J'utilise d3.js version 6.1.1. il me manque quelque chose ?

0
Sergey Linev 2 nov. 2020 à 19:51

1 réponse

Meilleure réponse

Vous ne manquez rien, mais il y a cette ligne, à l'intérieur du code source :

if (z.length * 2 < n) z = ticks(u, v, n);

Ici, z est le tableau généré (dans ce cas [64, 128, 256]), n est le nombre requis de ticks (10), et u et v sont le domaine (50 et 500).

Comme le nombre de ticks générés est trop faible, d3 utilise par défaut une échelle linéaire. Essayez plutôt l'une des solutions suivantes :

console.log(d3.scaleLog().base(2).domain([50, 500]).ticks(6));
console.log(d3.scaleLog().base(2).domain([32, 512]).ticks(10));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.1/d3.min.js"></script>

Si tous les paramètres sont variables, vous pouvez calculer le nombre maximum de graduations possible et l'utiliser comme limite supérieure :

const domain = [50, 500];
const ticks = 100;

console.log(d3.scaleLog().base(2).domain(domain).ticks(ticks));

function getNTicks(domain, ticks) {
  const maxPossibleTicks = Math.floor(Math.log2(domain[1]) - Math.log2(domain[0]));
  return Math.min(ticks, maxPossibleTicks);
}

console.log(d3.scaleLog().base(2).domain(domain).ticks(getNTicks(domain, ticks)));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.1/d3.min.js"></script>
1
Ruben Helsloot 2 nov. 2020 à 17:34