2012-12-03 12 views
8

Ho creato un piccolo grafico a linee di test utilizzando D3, ma poiché sono abbastanza nuovo per la libreria non sono sicuro quale sia il modo migliore per aggiungere più righe a un grafico, al momento ho solo una linea visualizzata in questo fiddle.D3js - Creazione e aggiornamento di un grafico a più righe

Vorrei visualizzare 2 righe sul grafico, ma non sono sicuro di come ottenerlo senza copiare il codice incollato, che sono sicuro sarebbe molto inefficiente in quanto mi piacerebbe aggiornare/animare il grafico a intervalli regolari in base alla selezione dell'utente.

Invece di questo,

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

Vorrei visualizzare qualcosa di simile,

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

questo sarebbe una possibilità? In tal caso, quale sarebbe il modo migliore per avvicinarsi a questo, in modo da poter facilmente aggiornare/animare il grafico quando necessario?

Nota: Sto semplicemente cercando di imparare e di familiarizzare con le best practice D3 e la libreria nel suo complesso. Grazie.

risposta

12

Questo è possibile e ragionevole. Esiste un tutorial che si avvicina a questo allo D3 Nested Selection Tutorial che descrive l'annidamento dei dati.

Di seguito è riportato il codice che ho violato dal vostro violino per dimostrarlo.

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); 
​ 

Una carenza è che ho calcolato il dominio per il assi X e Y fuori la prima matrice, che è un hack, ma non pertinente alla domanda esattamente.

Sample of output image

+0

Perfetto! Grazie, ora solo per creare una funzione più riutilizzabile per aggiornare/animare il grafico. :) Ho raggiunto un punto in cui posso facilmente aggiornare/animare una singola riga, ma aggiornando un grafico come questo devo ancora capire. – Odyss3us

Problemi correlati