2012-10-16 6 views
21

Ich bin ein D3.js Neuling und ich lerne, wie man mit Daten herumspielt.D3.js ein Objekt an Daten binden und für jeden Schlüssel anhängen

Sagen wir, ich habe ein Objekt mit Namen als Schlüssel, und jede Taste hat eine Reihe von Zahlen wie folgt aus:

var userdata = { 
    'John' : [0, 1, 3, 9, 8, 7], 
    'Harry': [0, 10, 7, 1, 1, 11], 
    'Steve': [3, 1, 4, 4, 4, 17], 
    'Adam' : [4, 77, 2, 13, 11, 13] 
}; 

Für jeden Benutzer, würde Ich mag ein SVG-Objekt anhängen und dann die Linie zeichnen mit dem Array von Werten für diesen Benutzer.

Also hier ist meine Annahme, wie das auf Tutorials aussehen würde, aber ich weiß, dass es falsch ist. Das ist mein begrenztes Wissen zeigen und ein besseres Verständnis von dem, was ich tue:

Zuerst habe ich die Linie erstellen sollte

var line = d3.svg.line().interpolate('basis'); 

Dann möchte ich die Daten auf meinen Körper binden und ein svg Element anhängen für jeden Schlüssel:

d3.select('body') 
    .selectAll('svg') 
    .data(userdata) 
    .enter() 
    .append('svg') 
    .append(line) 
    .x(function(d, i) { return i; }) 
    .y(function(d) { return d[i]; }); 

Also bin ich nah ??

Antwort

31

Hier ist ein weiteres Beispiel ähnlich wie mbeasley: http://jsfiddle.net/2N2rt/15/, die Achse, Farben und flips das Diagramm mit der rechten Seite nach oben. Zuerst massierte ich deine Daten ein wenig. Funktioniert am besten, wenn Sie ein Array von Werten haben und ich verwendete Tasten, um zu den Eigenschaften name und values einfacher zu machen.

var data = [ 
    {name: 'John', values: [0,1,3,9, 8, 7]}, 
    {name: 'Harry', values: [0, 10, 7, 1, 1, 11]}, 
    {name: 'Steve', values: [3, 1, 4, 4, 4, 17]}, 
    {name: 'Adam', values: [4, 77, 2, 13, 11, 13]} 
]; 

Allgemeinen in d3 setzen Sie das Diagramm wie dieses oben, die die Größe des tatsächlichen Graphen und die umliegenden Ränder bestimmt.

var margin = {top: 20, right: 80, bottom: 30, left: 50}, 
    width = 640 - margin.left - margin.right, 
    height = 380 - margin.top - margin.bottom; 

Dann können Sie Ihre Waage basierend auf Ihren Daten erstellen. Obwohl Sie sie nicht erstellen müssen, erleichtern sie das Positionieren von Elementen auf dem Diagramm, indem Sie Werte in Punkte umwandeln. Die domain sind die Min- und Max-Werte, die Ihre Daten haben, während die range die Min- und Max-Werte der Größe Ihres Graphen ist. Beachten Sie, dass die range für die y axis umgekehrt wird, wodurch (0,0) in die untere linke Ecke gesetzt wird (normalerweise ist 0 für die y-Achse oben).

var x = d3.scale.linear() 
    .domain([0, d3.max(data, function(d) { return d.values.length - 1; })]) 
    .range([0, width]); 

var y = d3.scale.linear() 
    .domain([d3.min(data, function(d) { return d3.min(d.values); }), 
      d3.max(data, function(d) { return d3.max(d.values); })]) 
    .range([height, 0]); 

d3 hat ein paar Funktionen für Farbskalen für Sie automatisch erzeugt wird. Stellen Sie es einfach mit den Tasten, die Sie verwenden möchten, und der Anzahl der Farben (ich denke, es gibt 10 und 20 Farboptionen).

var color = d3.scale.category10() 
    .domain(d3.keys(data[0]).filter(function(key) { return key === "name"; })); 

Hier verwenden wir unsere Skalen zum Einrichten der X- und Y-Achse. Es gibt viele verschiedene Optionen für die Achsen. TickFormat ist praktisch, um zu ändern, wie die Ticks aussehen, d3.format hat viele verschiedene Optionen, so dass Sie selten einen benutzerdefinierten Formatierer erstellen müssen.

Hier erstellen wir eine wiederverwendbare Funktion, die weiß, wie man eine Linie zeichnet. Wir übergeben jeden Datenpunkt für jede Person später in die Linienfunktion. Beachten Sie, dass d den aktuellen Satz von Werten enthält, den wir grafisch darstellen, und i ist der Index der aktuellen Werte innerhalb unseres ursprünglichen Datenarrays.

var line = d3.svg.line() 
    .interpolate("basis") 
    .x(function(d, i) { return x(i); }) 
    .y(function(d, i) { return y(d); }); 

Endlich können wir beginnen, Dinge zu unserem Diagramm hinzuzufügen, zuerst das Haupt-SVG-Element zu erstellen und zu positionieren.

var svg = d3.select("#chart").append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

Dann Anhängen jeder Achse.

svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis); 

Wir fügen Sie eine Gruppe (g) für jede Person und die Daten mit der Gruppe in Verbindung bringen. Wir werden diese Daten verwenden, wenn wir die Linien zeichnen. Wir bieten eine class, so dass wir das Diagramm später stylen können, wenn wir wollen.

var people = svg.selectAll(".people") 
     .data(data) 
    .enter().append("g") 
     .attr("class", "people"); 

Dann zeichnen Sie schließlich die Linien für jede Person.

people.append("path") 
     .attr("class", "line") 
     .attr("d", function(d) { return line(d.values); }) 
     .style("stroke", function(d) { return color(d.name); }); 

Ich verwendete Ihre Daten, um eine andere Frage über das Zeichnen eines Gitters zu beantworten, wenn Sie negative Werte haben. Sie können dieses Diagramm unter http://jsfiddle.net/2y3er/2/ sehen.

+0

Dies ist ein ziemlich gutes Beispiel, wobei ich die generische Zeilengenerierung, die ich in meinem Beispiel hatte, ein ganzes Stück weiter entwickelte, um ein vollständig stilisiertes Diagramm zu erstellen. Gute Arbeit! – mbeasley

+0

Eine Sache, die ich bemerkte, ist, dass Sie das Layout meines Objekts ändern. Stattdessen haben Sie ein Array von 4 Objekten, während ich ein Objekt mit 4 Eigenschaften habe. Ich habe kurz nach dem Stellen dieser Frage ein Video angeschaut (http://vimeo.com/35005701) und es geht darum, meine Daten immer so zu platzieren. Ich denke, ich muss wiederholen, wie meine Funktion funktioniert. – frshca

+0

Auch, vielen Dank @Bill. Du hast jetzt 2 meiner Fragen zu D3.js beantwortet! Bis bald! – frshca

11

Ich würde sagen, Sie gehen in die richtige Richtung. Hier ist, was ich tun würde (aber weiß, dass es nicht nur ein Weg, dies zu tun):

// your user data 
var userdata = { 
    'John' : [0, 1, 3, 9, 8, 7], 
    'Harry': [0, 10, 7, 1, 1, 11], 
    'Steve': [3, 1, 4, 4, 4, 17], 
    'Adam' : [4, 77, 2, 13, 11, 13] 
}; 

// add your main SVG block 
var svg = d3.select('body') 
    .append('svg') 
    .attr('width', 400) 
    .attr('height', 200) 
    .attr('id', 'chart'); 

// add an SVG group element for each user 
var series = svg.selectAll('g.series') 
    .data(d3.keys(userdata)) 
    .enter() 
    .append('g') 
    .attr('class', 'series'); 

// create your line generator 
var line = d3.svg.line() 
    .interpolate('basis') 
    .x(function(d, i) { 
     return i*40; // *40 just to increase the chart size 
    }) 
    .y(function(d) { 
     return d*3; // *3 for the same reason 
    }); 

// add a line for each user using your SVG grouping 
var lineSVG = series.selectAll('.line') 
    .data(d3.keys(userdata)) 
    .enter() 
    .append('svg:path') 
    .attr('d', function(d) { 
     return line(userdata[d]); 
    }) 
    .attr('class','line'); 

Here's a demo des obigen Codes.

Ich empfehle auch sehr, dass Sie lesen this article, wie es wirklich hilft, die Art und Weise zu festigen, dass d3 funktioniert.

+0

danke für den Artikel, es scheint, als würden viele Leute empfehlen, diesen Artikel zu lesen. – frshca