var xScale = d3.scale.ordinal().domain([0, d3.max(data)]).rangeRoundBands([0, w], .1);
var yScale = d3.scale.linear().domain([0, data.length]).range([h, 0]);
Je ne sais pas quand utiliser l'échelle ordinale ou linéaire en D3.
Voici ce que j'ai découvert dans le document API, encore un peu perdu ... si quelqu'un peut aider, ce serait très apprécié.
Étant donné une valeur x dans le domaine d'entrée, renvoie la valeur correspondante dans la plage de sortie.
Si la plage a été spécifiée explicitement (comme par plage, mais pas par rangeBands, rangeRoundBands ou rangePoints), et que la valeur donnée x n'est pas dans le domaine de l'échelle, alors x est implicitement ajouté au domaine; les invocations ultérieures de l'échelle avec la même valeur x renverront la même valeur y de la plage.
Construit une nouvelle échelle linéaire avec le domaine par défaut [0,1] et la plage par défaut [0,1]. Ainsi, l'échelle linéaire par défaut est équivalente à la fonction d'identité pour les nombres; par exemple, linéaire (0,5) renvoie 0,5.
Quant à échelles ordinales :
Les échelles ordinales ont un domaine discret , tel qu'un ensemble de noms ou de catégories.
Les valeurs d'une échelle ordinale doivent être coercitives à une chaîne et la version chaîne de la valeur de domaine identifie de manière unique la valeur de plage correspondante.
Ainsi, à titre d'exemple, un domaine d'une échelle ordinale peut contenir des noms, comme ceci:
var ordinalScale = d3.scale.ordinal()
.domain(['Alice', 'Bob'])
.range([0, 100]);
ordinalScale('Alice'); // 0
ordinalScale('Bob'); // 100
Remarquez comment toutes les valeurs sont des chaînes. Ils ne peuvent pas être interpolés. Qu'est-ce qu'il y a entre 'Alice' et 'Bob'? Je ne sais pas. D3 non plus.
Maintenant, comme pour échelles quantitatives (par exemple échelles linéaires):
Les échelles quantitatives ont un domaine continu , comme l'ensemble des nombres réels ou des dates.
Par exemple, vous pouvez construire l'échelle suivante:
var linearScale = d3.scale.linear()
.domain([0, 10])
.range([0, 100]);
linearScale(0); // 0
linearScale(5); // 50
linearScale(10); // 100
Remarquez comment D3 est capable d'interpoler 5 même si nous ne l'avons pas spécifié explicitement dans le domaine.
Jetez un œil à this jsfiddle pour voir le code ci-dessus en action.
Dans D3.js, les échelles transforment un nombre du domaine en plage. Pour une échelle linéaire, le domaine sera une variable continue, avec une plage de valeurs illimitée, qui peut ensuite être transformée en une plage continue. Pour les échelles ordinales, il y aura un domaine discret, par exemple les mois de l'année où il y a une plage limitée de valeurs possibles qui peuvent être ordonnées mais qui ne sont pas continues. Les documents API sur Github peuvent probablement expliquer la différence mieux que moi
OK, nous pouvons commencer à l'apprendre en utilisant les deux avec les mêmes données pour voir les différences (j'utilise d3 v4), imaginez que nous avons les données ci-dessous en utilisant les échelles ordinal
et linear
:
const data = [1, 2, 3, 4, 5];
const scaleLinear = d3.scaleLinear()
.domain([0, Math.max(...data)]).range([1, 100]);
const scaleOrdinal = d3.scaleOrdinal()
.domain(data).range(['one', 'two', 'three', 'four', 'five']);
Maintenant, nous commençons à les appeler pour voir le résultat:
scaleLinear(1); //20
scaleOrdinal(1); //one
scaleLinear(2); //40
scaleOrdinal(2); //two
scaleLinear(5); //100
scaleOrdinal(5); //five
Regardez les fonctions et les résultats que nous obtenons, comme vous le voyez dans l'ordinal, nous mappons les données à notre plage, tandis que dans la linéaire, nous nous étendons à la plage, donc dans ces cas par exemple scaleLinear (1) renverra 2 ... notre domaine max est 100 et 100 divisé par 5 est égal à 20, donc scaleLinear (1) est 2 et scaleLinear (2) est 4 ...
Mais comme vous le voyez, scaleOrdinal (1) est mappé au tableau dans la plage, il est donc égal à one et scaleOrdinal (2) c'est égal à deux ...
Voilà comment vous pouvez utiliser ces échelles, scaleLinear est utile pour de nombreuses choses, y compris présenter l'échelle sur la page, mais scaleOrdinal plus utile pour mettre les données en ordre, c'est comme ça que c'est expliqué dans la documentation:
# d3.scaleLinear () <>
Construit une nouvelle échelle continue avec le domaine unitaire [0, 1], la plage unitaire [0, 1], l'interpolateur et le verrouillage par défaut désactivés. Les échelles linéaires sont un bon choix par défaut pour les données quantitatives continues car elles préservent les différences proportionnelles. Chaque valeur de plage y peut être exprimée en fonction de la valeur de domaine x: y = mx + b.
d3.scaleOrdinal ([plage]) <>
Construit une nouvelle échelle ordinale avec un domaine vide et la plage spécifiée. Si une plage n'est pas spécifiée, elle correspond par défaut au tableau vide; une échelle ordinale renvoie toujours undefined jusqu'à ce qu'une plage non vide soit définie.
C'est également un bon exemple de d3 en profondeur utilisant à la fois des échelles ordinales et linéaires:
var myData = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
var linearScale = d3.scaleLinear()
.domain([0, 11])
.range([0, 600]);
var ordinalScale = d3.scaleOrdinal()
.domain(myData)
.range(['black', '#ccc', '#ccc']);
d3.select('#wrapper')
.selectAll('text')
.data(myData)
.enter()
.append('text')
.attr('x', function(d, i) {
return linearScale(i);
})
.text(function(d) {
return d;
})
.style('fill', function(d) {
return ordinalScale(d);
});
body {
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 14px;
color: #333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<svg width="800" height="60">
<g id="wrapper" transform="translate(100, 40)">
</g>
</svg>