2013-01-11 18 views
7

Sto cercando di visualizzare i dati di collaborazione di squadra, in un modo simile a questo:Appiattire una gerarchia di oggetti creati con d3.js nidificazione

Chart that displays the share of the different collaboration artifact types for each team and week

diversi colori nella tabella sono diversi tipi di collaborazione artefatto.

I dati dall'origine aspetto:

var json = [ 
    { 
     "teamLabel": "Team 1", 
     "created_date": "2013-01-09", 
     "typeLabel": "Email" 
     "count": "5" 
    }, 
    { 
     "teamLabel": "Team 1", 
     "created_date": "2013-01-10", 
     "typeLabel": "Email" 
     "count": "7" 
    }, 
    /* and of course, a lot more data of this kind */ 
] 

Nota che i dati è dato per i singoli giorni. Quindi per la visualizzazione di cui sopra, ho bisogno di aggregare i dati in base alla settimana dell'anno prima. Il nome del team e il tipo di artefatto devono tuttavia essere preservati e utilizzati come attributi di raggruppamento. Ecco il codice:

// "2013-01-09" 
var dateFormat = d3.time.format.utc("%Y-%m-%d"); 

// "2013-02" for the 2nd week of the year 
var yearWeek = d3.time.format.utc("%Y-%W"); 

var data = d3.nest().key(function(d) { 
     return d.teamLabel; 
    }).key(function(d) { 
     var created_date = dateFormat.parse(d.created_date); 
     return yearWeek(created_date); 
    }) 
    .key(function(d) { 
     return d.typeLabel; 
    }).rollup(function(leaves) { 
     return d3.sum(leaves, function(d) { 
       return parseInt(d.count); // parse the integer 
      }); 
     } 
    ) 
    .map(json); 

Ciò determina una gerarchia di oggetti basata sulle chiavi di nidificazione. Non vedo come creare il grafico sopra da questo, quindi sono piuttosto alla ricerca di un modo per convertire data nella seguente struttura:

[ 
    // This list contains an element for each donut 
    { 
     "teamLabel": "Team 1", 
     "createdWeek": "2013-02", 
     "values": [ 
      // This list contains one element for each type we found 
      { 
       "typeLabel": "Email", 
       "count": 12 
      }, 
      { 
      ... 
      } 
     ] 
    }, 
    { 
    ... 
    } 
] 

In questo modo, posso usare createdWeek e teamLabel per il posizionamento su x - e y-Axis, rispettivamente, e le informazioni sotto values possono essere passate a d3.layout.pie().

C'è un modo pulito per eseguire questa trasformazione dei dati? Se avete bisogno di chiarimenti o ulteriori dettagli, fatemelo sapere.

+1

Hai mai scoprire come per fare questo? –

+0

@cyroxx Non sono sicuro di aver capito la tua domanda; ti piacerebbe convertire i dati 'json' che hai presentato nel nuovo formato di matrice raggruppati per squadra? – hitautodestruct

+0

Sono confuso perché si chiama questo appiattimento, quando sembra che si stiano aggiungendo strati a dati originariamente piatti. (Sto cercando di appiattire un set di dati nidificati.) – punstress

risposta

3

Ecco come si fa:

var flat = data.entries().map(function(d){ 
    return d.value.entries().map(function(e){ 
     return { 
      "teamLabel": d.key, 
      "createdWeek": e.key, 
      "values": e.value.entries().map(function(f){ 
       return {"typeLabel": f.key, "count": f.value} 
      }) 
     } 
    }) 
}).reduce(function(d1,d2){ return d1.concat(d2) },[]); 

Si noti che sto usando d3.map invece dello standard JavaScript Object, al fine di utilizzare le() funzione di supporto map.entries. Immagino che è quello che si è tentato a giudicare dal fatto che si sta utilizzando:

.map(json); // whereas I used .map(json, d3.map) 

invece di

.entries(json); 

collegamento jsFiddle qui:

http://jsfiddle.net/RFontana/KhX2n/

+1

il tuo link non mostra il json corretto? – thatOneGuy