2014-07-23 11 views
16

Ho un grafico bar/grafico combinato. Per ogni riga del file di input, creo un gruppo che contiene più elementi (linee, rettangoli, testi):D3: aggiornamento dei dati con più elementi in un gruppo

var myGroups = svg.selectAll('g').data(myData) 
myGroups.enter().append('g') 
... 
myGroups.append('line') 
... 
myGroups.append('polygon') 
... 
myGroups.append('text') 
... 

Attualmente solo

svg.selectAll('*').remove() 

e creare tutto da zero ogni volta che i dati sono aggiornati. Tuttavia, mi piacerebbe avere una transizione graduale per tutti gli elementi.

Sono passato attraverso lo this tutorial diverse volte, ma ancora non capisco come posso farlo nel mio caso.

risposta

39

La chiave è quello di gestire tutte le selezioni, non solo la selezione inserire:

var myGroups = svg.selectAll('g').data(myData); 

// enter selection 
var myGroupsEnter = myGroups.enter().append("g"); 
myGroupsEnter.append("line"); 
myGroupsEnter.append("polygon"); 
// ... 

// update selection -- this will also contain the newly appended elements 
myGroups.select("line").attr(...); 
// ... 

// exit selection 
myGroups.exit().remove(); 

Ci sono due cose qui che meritano ulteriori spiegazioni. Innanzitutto, gli elementi nella selezione di inserimento che hanno aggiunto nuovi elementi vengono uniti nella selezione di aggiornamento. Cioè, non è necessario impostare gli attributi sugli elementi nella selezione di inserimento se la stessa cosa accade nella selezione di aggiornamento. Ciò consente di aggiungere nuovi elementi e aggiornare quelli esistenti senza duplicare il codice.

La seconda cosa diventa importante nelle chiamate successive con dati aggiornati. Poiché gli elementi a cui stai vincolando i dati non sono quelli effettivamente disegnati, i nuovi dati devono essere propagati a loro. Questo è ciò che fa .select(). Cioè, facendo myGroups.select("line"), stai propagando i nuovi dati legati agli elementi g ai loro elementi figli line. Quindi il codice per impostare gli attributi è lo stesso del caso di invio.

Ora è possibile aggiungere semplicemente le transizioni dove desiderato prima di impostare i nuovi attributi.

+4

Sei il vento sotto le mie ali! – Mikhail

+1

Secondo i documenti d3, 'select()' dovrebbe restituire un singolo elemento. Ma qui sembra selezionare tutti gli elementi della linea nella dichiarazione 'myGroups.select (" linea "). Attr (...);'. E nei miei esperimenti, 'selectAll()' non sembra funzionare. Potresti spiegare l'apparente discrepanza? – brainjam

+3

'myGroups' contiene più elementi e' .select() 'esegue la selezione per ognuno di essi. Cioè, stai selezionando un singolo elemento per più elementi. '.selectAll()' probabilmente non ha funzionato perché non aggiorna i dati. –

Problemi correlati