2012-12-03 8 views
8

Ich habe ein kleines Testliniendiagramm mit D3 erstellt, aber da ich ziemlich neu in der Bibliothek bin, bin ich mir nicht sicher, wie ich am besten mehrere Zeilen hinzufügen könnte ein Diagramm, im Moment habe ich nur eine Zeile in diesem fiddle angezeigt.D3js - Erstellung und einfache Aktualisierung eines mehrzeiligen Diagramms

Ich möchte 2 Zeilen auf dem Diagramm anzeigen, aber ich bin mir nicht sicher, wie das ohne Kopieren Code zu erreichen, die ich bin sicher sehr ineffizient wäre, wie ich das Diagramm in regelmäßigen Abständen aktualisieren/animieren möchte basierend auf Benutzerauswahl.

Statt dessen,

var data = [12345,22345,32345,42345,52345,62345,72345,82345,92345,102345,112345,122345,132345,142345]; 

Ich mag würde, so etwas zeigen,

var data = [ 
      [12345,42345,3234,22345,72345,62345,32345,92345,52345,22345], // line one 
      [1234,4234,3234,2234,7234,6234,3234,9234,5234,2234] // line two 
      ]; 

Wäre das eine Möglichkeit? Wenn ja, wie könnte ich das am besten angehen, damit ich das Diagramm bei Bedarf einfach aktualisieren/animieren kann?

Hinweis: Ich versuche nur zu lernen und mich mit D3 Best Practices und der Bibliothek als Ganzes vertraut zu machen. Vielen Dank.

Antwort

12

Dies ist möglich und sinnvoll. Es gibt ein Tutorial, das sich an die D3 Nested Selection Tutorial nähert, die Verschachtelung von Daten beschreibt.

Unten ist Code, den ich von deiner Geige gehackt habe, um dies zu demonstrieren.

var data = [   
[12345,42345,3234,22345,72345,62345,32345,92345,52345,22345], 
[1234,4234,3234,2234,7234,6234,3234,9234,5234,2234] 
      ]; 

var width = 625, 
    height = 350; 

var x = d3.scale.linear() 
    .domain([0,data[0].length]) // Hack. Computing x-domain from 1st array 
    .range([0, width]); 

var y = d3.scale.linear() 
    .domain([0,d3.max(data[0])]) // Hack. Computing y-domain from 1st array 
    .range([height, 0]); 

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

var area = d3.svg.area() 
    .x(line.x()) 
    .y1(line.y()) 
    .y0(y(0)); 

var svg = d3.select("body").append("svg") 
    //.datum(data) 
    .attr("width", width) 
    .attr("height", height) 
    //.append("g"); 

var lines = svg.selectAll("g") 
    .data(data); // The data here is two arrays 

// for each array, create a 'g' line container 
var aLineContainer = lines 
    .enter().append("g"); 

/*svg.append("path") 
    .attr("class", "area") 
    .attr("d", area);*/ 

aLineContainer.append("path") 
    .attr("class", "area") 
    .attr("d", area); 

/*svg.append("path") 
    .attr("class", "line") 
    .attr("d", line);*/ 

aLineContainer.append("path") 
    .attr("class", "line") 
    .attr("d", line); 

/*svg.selectAll(".dot") 
    .data(data) 
    .enter().append("circle") 
    .attr("class", "dot") 
    .attr("cx", line.x()) 
    .attr("cy", line.y()) 
    .attr("r", 3.5);*/ 
// Access the nested data, which are values within the array here 
aLineContainer.selectAll(".dot") 
    .data(function(d, i) { return d; }) // This is the nested data call 
    .enter() 
    .append("circle") 
    .attr("class", "dot") 
    .attr("cx", line.x()) 
    .attr("cy", line.y()) 
    .attr("r", 3.5); 
​ 

Ein Nachteil ist, dass die I-Domäne für die x und y-Achsen berechnet die erste Anordnung aus, die eine Kerbe ist, aber genau auf Ihre Frage nicht relevant.

Sample of output image

+0

Perfekt! Danke, jetzt nur um eine wiederverwendbare Funktion zum Aktualisieren/Animieren des Diagramms zu erstellen. :) Ich habe es bis zu einem Punkt geschafft, wo ich ganz einfach eine einzelne Zeile aktualisieren/animieren kann, aber ein Diagramm wie dieses zu aktualisieren, muss ich noch herausfinden. – Odyss3us