2015-04-21 6 views
24
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]); 

Ich bin verwirrt darüber, wann Ordnungs oder linear Skala in D3 zu verwenden.D3 Unterschied zwischen Ordnungs und linear skaliert

Unten ist, was ich von der API-Dokument entdeckt habe, noch etwas verloren ... wenn jemand helfen kann, würde es sehr geschätzt werden.

ordinal (x)

x ein Wert in der Eingabe Domäne Gegeben, kehrt den entsprechenden Wert im Leistungsbereich.

Wenn der Bereich explizit angegeben wurde (z. B. nach Bereich, aber nicht nach rangeBands, rangeRoundBands oder rangePoints) und der angegebene Wert x nicht in der Domäne der Skalierung enthalten ist, wird x implizit zur Domäne hinzugefügt. Nachfolgende Aufrufe der Skala mit demselben Wert x geben denselben Wert y aus dem Bereich zurück.

d3.scale.linear()

Konstruiert eine neue lineare Skala mit der Standarddomäne [0,1] und Standardbereich [0,1]. Die Standardlinearskala entspricht also der Identitätsfunktion für Zahlen. zum Beispiel gibt linear (0,5) 0,5 zurück.

+1

Die lineare Skala zwischen Eingangswerten interpoliert werden, wohingegen die ordinale Skala wird nicht. –

+0

@LarsKotthoff können Sie bitte ein Beispiel geben? – Bruce

+0

Es gibt tatsächlich ein Beispiel dafür in der Dokumentation, das 'lineare (0.5)'. –

Antwort

44

Was Ordinal Scales haben:

Ordinalskalen haben eine diskrete Domäne, wie zum Beispiel eine Reihe von Namen oder Kategorien.

Die Werte einer Ordinalskala müssen zu einer Zeichenfolge konvergierbar sein, und die stringifizierte Version des Domänenwerts identifiziert den entsprechenden Bereichswert eindeutig.

So, als Beispiel, eine Domäne eines Ordinalskala kann Namen enthalten, etwa so:

var ordinalScale = d3.scale.ordinal() 
     .domain(['Alice', 'Bob']) 
     .range([0, 100]); 

ordinalScale('Alice'); // 0 
ordinalScale('Bob'); // 100 

Beachten Sie, wie alle Werte Strings sind. Sie können nicht interpoliert werden. Was ist zwischen 'Alice' und 'Bob'? Ich weiß es nicht. Auch nicht D3.

Nun, wie für Quantitative Scales (z.B. Linearmaßstäbe):

Quantitative Skalen haben eine kontinuierliche Domäne, wie beispielsweise die Menge der reellen Zahlen oder Daten.

var linearScale = d3.scale.linear() 
     .domain([0, 10]) 
     .range([0, 100]); 

linearScale(0); // 0 
linearScale(5); // 50 
linearScale(10); // 100 

Beachten Sie, wie D3 5 zur Interpolation der Lage ist, auch wenn wir es nicht explizit in der Domäne angegeben haben:

Als Beispiel können Sie die folgende Skala konstruieren.

Werfen Sie einen Blick auf this jsfiddle, um den obigen Code in Aktion zu sehen.

+2

Omg ... du solltest das d3 API doc schreiben, brilliant, macht total Sinn. Vielen Dank :) – Bruce

+0

Wenn Sie mehr als 2 Objekte in Ihrer Domain haben, d. H. '['Alice', 'Bob', 'Carl']', dann müssen Sie 'rangePoints' anstelle von' range' verwenden. –

2

In D3.js skaliert eine Zahl von der Domäne in den Bereich. Für eine lineare Skala ist die Domäne eine kontinuierliche Variable mit einem unbegrenzten Bereich von Werten, die dann in einen kontinuierlichen Bereich transformiert werden können. Für Ordinalskalen wird es eine diskrete Domäne geben, zum Beispiel Monate des Jahres, in denen es eine begrenzte Auswahl möglicher Werte gibt, die zwar geordnet, aber nicht kontinuierlich sind. Die API docs on Github kann wahrscheinlich den Unterschied besser erklären als ich

0

OK, wir können sie anfangen zu lernen, mit der Verwendung sowohl mit den gleichen Daten Unterschiede zu sehen (ich verwende d3 v4), stellen wir die Daten unter Verwendung von mit ordinal und linear Skalen haben:

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']); 

jetzt beginnen wir fordern sie das Ergebnis zu sehen:

scaleLinear(1); //20 
scaleOrdinal(1); //one 

scaleLinear(2); //40 
scaleOrdinal(2); //two 

scaleLinear(5); //100 
scaleOrdinal(5); //five 

Blick auf die Funktionen und die Ergebnisse, die wir erhalten, wie Sie in der Ordnungs man sehen wir die Daten in unserem Bereich abzubilden, während im linearen man wir strecken der Bereich, so in diesen Fällen zum Beispiel scaleLinear (1) wird wieder 20 ... unsere Domain max 100 und 100 geteilt durch 5 ist gleich 20 ist, so scaleLinear (1) ist und scaleLinear (2) ist .. .

Aber wie Sie sehen, scaleOrdinal (1) ist Karte auf dem Feld im Bereich, es ist so gleich ein und scaleOrdinal (2) es ist gleich zwei ...

Also das ist, wie Sie diese Waage verwenden können, scaleLinear für viele Dinge nützlich ist, einschließlich vorhanden, um die Skala auf Seite, aber scaleOrdinal nützlicher für die Daten, um bekommen, das ist, wie es in der Dokumentation erklärt hat:

# d3.scaleLinear() <>

Konstruiert eine neue kontinuierliche Skala mit dem Einheitsbereich [0, 1], der Einheit Bereich [0, 1], das Standardwert-Interpolator und Klemm deaktiviert. Lineare Skalen sind eine gute Standardauswahl für kontinuierliche quantitative Daten, da sie proportionale Unterschiede beibehalten. Jeder Bereichswert y kann als eine Funktion des Domänenwerts x ausgedrückt werden: y = mx + b.


d3.scaleOrdinal ([Bereich]) <>

Konstruiert eine neue Ordinalskala mit einem leeren Bereich und dem angegebenen Bereich . Wenn kein Bereich angegeben ist, wird standardmäßig das leere Array verwendet. Eine Ordinalskala liefert immer undefined, bis ein nicht leerer Bereich definiert ist.

Auch dies ist ein gutes Beispiel von d3 in der Tiefen sowohl ordinal und lineare Skalen zur gleichen Zeit unter Verwendung von:

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"> 
 
    \t <g id="wrapper" transform="translate(100, 40)"> 
 
    \t </g> 
 
</svg>