2012-06-28 31 views
7

Sto utilizzando D3.js e sto riscontrando problemi nell'impostare un layout impilato per un grafico ad area con più serie. Ho due possibili strutture dei miei dati (se questo aiuta). Uno è i dati grezzi alimentati allo script, in questa struttura:Area impilata in D3.js

var data = [{key: 'Group1', value: 37, date: '04/23/12'}, 
      {key: 'Group2', value: 12, date: '04/23/12'}, 
      {key: 'Group3', value: 46, date: '04/23/12'}, 
      {key: 'Group1', value: 32, date: '04/24/12'}, 
      {key: 'Group2', value: 19, date: '04/24/12'}, 
      {key: 'Group3', value: 42, date: '04/24/12'}, 
      {key: 'Group1', value: 45, date: '04/25/12'}, 
      {key: 'Group2', value: 16, date: '04/25/12'}, 
      {key: 'Group3', value: 44, date: '04/25/12'}, 
      {key: 'Group1', value: 24, date: '04/26/12'}, 
      {key: 'Group2', value: 52, date: '04/26/12'}, 
      {key: 'Group3', value: 64, date: '04/26/12'}] 

seconda è una struttura annidata, creato utilizzando questo codice:

pData = d3.nest() 
      .key(function(d) { return d.key; }) 
      .map(data); 

conseguente questa struttura:

pData = {Group1: [{date: 04/23/12, key: "Group1", value: 37}, 
        {date: 04/24/12, key: "Group1", value: 32}, 
        {date: 04/25/12, key: "Group1", value: 45}, 
        ...], 
     Group2: [{date: 04/23/12, key: "Group2", value: 12}, 
        {etc, etc, etc}], 
     GroupX: [...] } 

Le mie domande sono: Come faccio a configurare un generatore d3.layout.stack(), utilizzando una delle strutture di dati sopra (o qualche variazione), per creare uno str stacked ucture per i miei dati in modo tale che posso passare a un generatore di un'area simile a questo:

var areaGenerator = d3.svg.area() 
    .interpolate('monotone') 
    .x(function(d) { return x(d.date); }) 
    .y0(h) 
    .y1(function(d) { return y(d.value); }); 

risposta

12

Dovete alimentare una serie di strati al layout dello stack, quindi la prima cosa da cambiare è quella di utilizzare nest.entries piuttosto che nest.map . Ciò restituisce una matrice di oggetti con un campo key (come "Gruppo1") e un array values che contiene i record associati. Specificare quindi un accessorio stack.values in modo che il layout dello stack possa accedere all'array values per ogni livello.

Sarà inoltre necessario definire adatto x e y di accesso al layout dello stack in modo che possano capire i dati di input: il -accessor x dovrebbe restituire d.date, e il -accessor y dovrebbe restituire d.value. Dovrai inoltre convertire le stringhe di data in date; è possibile utilizzare d3.time.format per aiutare con questo. Per esempio:

var format = d3.time.format("%m/%d/%y"); 
data.forEach(function(d) { d.date = format.parse(d.date); }); 

Infine, modificare la definizione di zona in modo che la linea di base y0 è definito come y(d.y0) e la linea dorsale y1 è definito come y(d.y0 + d.y).

Ecco un esempio di lavoro:

+1

incredibilmente utile. Grazie per la risposta! – mbeasley

+0

Molto utile, grazie! Vale la pena sottolineare ai noobs di Javascript (come me!) Che il + prima del valore di d.valore (nel callback dei dati) converte in un numero - si veda [qui] (http://xkr.us/articles/javascript/unary -Inserisci/). Nella richiamata, come vengono assegnati i valori y0? Ho usato [questo] (http://pastebin.com/amjkBRYV) codice per ispezionare e ottenuto l'output [this] (http://i.imgur.com/lQFyJNL.png). Ogni oggetto viene registrato due volte, prima e dopo la modifica. Prima, contiene solo dati dal csv - dopo, ha un "y0 = 0", come ho impostato, ma (quando eseguivo il drill-down in Chrome) anche un y, e un non-zero y0. Cosa sta succedendo là? – scubbo

+0

(Per riferimento, sto cercando di manipolare il valore y0 in modo che il grafico mostri i totali cumulativi, piuttosto che i valori in ogni punto) Scusa se ricevi più notifiche per le mie modifiche precedenti, non utilizzate per lo stile StackOverflow, fatte alcune errori! – scubbo