2013-05-02 1 views
16

Ich habe eine externe CSV-Datei mit Daten in Spalten wie folgt:.Wie Maximalwert aus einem Array von Objekten in d3.scale.linear() nutzen, um Domain()

name, field_goal_attempts, field_goal_makes 

Ich versuche, eine lineare Skala zu verwenden, aber es fällt mir schwer, den Maximalwert für meine Domain zu bekommen.

var yScale = d3.scale.linear() 
       .domain(0, d3.max(... 

Ich bin verwirrt,:

1) Ob ich außerhalb der yScale Funktion oder innerhalb der

d3.csv("filename.csv", function(data) { 

Callback-Funktion setzen sollte; und

2) So erhalten Sie den maximalen Wert der Elemente in der Spalte field_goal_attempts, um dann in die yScale-Funktion einzufügen.

Hier ist mein Code derzeit:

var yScale = d3.scale.linear() 
    .domain([0, 4000]) //d3.max(data, function(d) {return d })]) 
    .range([0, 500]); 

d3.csv("test.csv", function (data) { 
    svg.selectAll("rect") 
     .data(data) 
     .enter() 
     .append("rect") 
     .attr("fill", "blue") 
     .attr("x", magic_number) // I'm not concerned about the magic numbers at this point :) 
     .attr("y", 0) 
     .attr("width", another_magic_number) 
     .attr("height", function (d) { 
      return d.field_goal_attempts 
     }) 
     .attr("id", function (d, i) { 
      return i 
     }); 
}); 

Antwort

28

Die Daten in Ihrer CSV-Datei werden in dem Rückruf sein, den Sie an die CSV-Funktion übergeben (in Ihrem Fall den Parameter "data"). Sie können also yScale außerhalb der csv-Funktion definieren, aber wenn Sie möchten, dass das Maximum datenabhängig ist, müssen Sie es innerhalb des Callbacks setzen.

Um das Maximum zu finden, akzeptieren viele D3-Funktionen, die auf Arrays funktionieren, optionale Accessor-Funktionen für genau Ihr Szenario. So Berechnung der max würde ich verwenden:

var max = d3.max(data, function(d) { return +d.field_goal_attempts;}); 

So könnte man es alle zusammen eine von zwei Möglichkeiten:

var yScale = d3.scale.linear().domain(0,100); 
d3.csv("test.csv", function(data){ 
    var max = d3.max(data, function(d) { return +d.field_goal_attempts;}); 
    yScale.domain([0,max]); 
    ... 
} 

oder

d3.csv("test.csv", function(data){ 
    var max = d3.max(data, function(d) { return +d.field_goal_attempts;}); 
    var yScale = d3.scale.linear().domain([0,max]); 
    ... 
} 

Wenn Sie sowohl max finden wollen und Dann schlage ich vor, d3.extent (...) zu verwenden, das auch eine Accessor-Funktion akzeptiert und ein Array der Länge 2 mit den Min- und Max-Werten zurückgibt.

+1

Danke für die Hilfe. Dies ist meine erste Frage und ich bin dankbar für die Hilfe und die freundliche Art und Weise, in der es geliefert wurde. Ich habe deine Antwort über Christopher Chiches angenommen, weil es sich "mehr d3" angefühlt hat, weil ich keine Schleife brauchte. Ich habe Ihre zweite Lösung implementiert, musste aber zwei Änderungen vornehmen, um es zum Laufen zu bringen, nämlich '+' vor d.field_goal_attempts zu verwenden, so dass max 2000 und nicht 600 zurückgegeben wurde und Werte in domain() in eckigen Klammern eingeschlossen wurden. Ich bin neu, also möchte ich deinen Code nicht ändern, falls ich falsch liege, aber dachte, es wäre gut, es dir zu sagen :). Danke noch einmal! – Emil

+0

Ja, Sie benötigen das '+' vor field_goal_attempts, wenn der Wert als String gespeichert ist. Und Sie haben absolut recht mit dem Argument, dass Domäne ein Array ist! Ich werde die Änderungen vornehmen. Froh, dass ich helfen konnte! – Superboggly

+0

Wow, nicht hinzufügen, dass + am Anfang gab mir so viele Probleme, Sie sind ein Lebensretter @Superboggly! –

1

1) Die yScale kann außerhalb der d3.csv() Funktion bleiben, solange Sie die Domäne aktualisieren, innerhalb der Funktion, wenn der max berechnet zu haben. Sie können beispielsweise die folgenden innerhalb von d3.csv() tun könnte:

yScale.domain([0, my_max]) 

2) die max zu berechnen, hier ist die Methode, die ich in der Regel verwenden:

//Create list containing only field_goal_attempts 
field_goal_attempts_list = data.forEach(function(d){return d.field_goal_attempts}) 

//Compute max using d3.max() function 
field_goal_attempts_max = d3.max(field_goal_attempts_list) 

Es ist wahr, dass eine solche Funktion zu d3.max() vorbei würde Großartig, aber so weit ich weiß, ist es nicht. Der Vorteil, zuerst die Liste zu berechnen und dann das Maximum zu berechnen, besteht darin, dass Sie weniger rechnen, wenn Sie das Minimum, den Mittelwert oder irgendetwas anderes berechnen wollen.

+0

Danke für die Hilfe. Dies ist meine erste Frage und ich bin dankbar für die Hilfe und die freundliche Art und Weise, in der es geliefert wurde. Ich würde deine Antwort ablehnen, aber ich scheue mich vor dem Ruf :(. Ich akzeptiere @ Superbogly's Antwort, weil es "mehr d3" fühlt, wenn ich die Notwendigkeit der forEach-Methode ignoriere - klingt schrecklich, nicht wahr? Jedenfalls beschuldige ich die Python-Menge für den Begriff "Pythonic" - ich bin neu sowohl mit der Programmierung als auch mit StackOverflow, daher möchte ich nur meine Wertschätzung für deine Antwort vermitteln.Danke :) – Emil

+0

Gern geschehen. Seine Antwort ist in der Tat besser als meine. Ich habe etwas Neues gelernt, indem ich es gelesen habe. –

Verwandte Themen