2012-09-22 14 views
10

Ho un grafico a linee molto semplice scritto utilizzando NVD3.js. Ho scritto un ridisegno semplice basata su timer, tirato dagli esempi che ho visto, ma ho l'erroreGrafico a linee NVD3 con dati in tempo reale

Uncaught TypeError: Impossibile leggere la proprietà 'y' undefined

Il JS è

var data = [{ 
     "key": "Long", 
     "values": getData() 
    }]; 
    var chart; 

    nv.addGraph(function() { 
      chart = nv.models.cumulativeLineChart() 
         .x(function (d) { return d[0] }) 
         .y(function (d) { return d[1]/100 }) 
         .color(d3.scale.category10().range()); 

     chart.xAxis 
      .tickFormat(function (d) { 
       return d3.time.format('%x')(new Date(d)) 
      }); 

     chart.yAxis 
      .tickFormat(d3.format(',.1%')); 

     d3.select('#chart svg') 
      .datum(data) 
      .transition().duration(500) 
      .call(chart); 

     nv.utils.windowResize(chart.update); 

     return chart; 
    }); 


    function redraw() { 
     d3.select('#chart svg') 
      .datum(data) 
      .transition().duration(500) 
      .call(chart); 
    } 

    function getData() { 
     var arr = []; 
     var theDate = new Date(2012, 01, 01, 0, 0, 0, 0); 
     for (var x = 0; x < 30; x++) { 
      arr.push([theDate.getTime(), Math.random() * 10]); 
      theDate.setDate(theDate.getDate() + 1); 
     } 
     return arr; 
    } 

    setInterval(function() { 
     var long = data[0].values; 
     var next = new Date(long[long.length - 1][0]); 
     next.setMonth(next.getMonth() + 1) 
     long.shift(); 
     long.push([next.getTime(), Math.random() * 100]); 
     redraw(); 
    }, 1500); 
+1

si può aggiungere un jsfiddle che dimostra il problema? –

+0

http://jsfiddle.net/khp9d/ –

+0

@JaimalChohan come hai risolto questo problema? – Sajeetharan

risposta

11

seconda risposta (dopo il commento)

ho guardato source for cumulativeLineChart. Puoi vedere la proprietà display.y che viene creata durante la creazione del grafico. Si basa su un metodo privato: "indicizza". Se qualche derivato di quel metodo è stato reso pubblico, forse potresti fare qualcosa come chart.reindexify() prima di ridisegnare.

Come soluzione temporanea, è possibile ricreare il grafico da zero su ogni aggiornamento. Se rimuovi la transizione, sembra funzionare bene. Esempio jsfiddle: http://jsfiddle.net/kaliatech/PGyKF/.

prima risposta

Credo che ci sia bug in cumulativeLineChart. Sembra che cumulativeLineChart aggiunga dinamicamente una proprietà "display.y" ai valori di dati della serie. Tuttavia, non rigenera questa proprietà quando vengono aggiunti nuovi valori alla serie per un ridisegno. Non so comunque di farlo, anche se sono nuovo di NVD3.

Avete davvero bisogno di un grafico di CumulativeLine o sarebbe sufficiente un normale grafico a linee? Se è così, ho dovuto fare le seguenti modifiche al tuo codice:

  • Passaggio da cumulativeLineChart a Linechart
  • Cambio di utilizzare le matrici 2 dimensione di dati, di utilizzare oggetti di dati (con x, y proprietà)
    • (io non sono abbastanza con NVD3 familiare a dire ciò che i formati di dati è aspetta. La matrice 2D funziona, ovviamente, per i carichi iniziali, ma penso che non riesce a lavorare per il ridisegno successive. Questo è probabilmente legato alla lo stesso problema che si ha con cumulativeLineChart dovrebbe cambiare a oggetti potrebbe risolvere cumulativeLineChart pure, ma non sembrava)

Ho cambiato anche quanto segue, anche se non così importante:.

  • Modificata la funzione getData a creare una nuova istanza di Data per evitare conseguenze impreviste della condivisione di un riferimento man mano che la data viene incrementata.

  • Modificata la funzione di intervallo di aggiornamento per generare nuovi dati in incrementi di giorni (non mesi) con valori y nello stesso intervallo della funzione getData.

Ecco un jsfiddle lavorare con questi cambiamenti:

+0

No, ha bisogno di essere un grafico a linee cumulativo, ho semplificato il mio jsfiddle per mostrare solo 1 linea per rendere il problema più facile da capire –

+1

ah. Beh, penso davvero che sia un bug di NVD3. Sono stato in grado di creare la funzione cumulativeLineChart senza generare errori aggiungendo manualmente una proprietà display: {y: ???} al punto dati. JSfiddle: http://jsfiddle.net/kaliatech/khp9d/30/. Ovviamente, il risultato non è corretto. Penso che il solo ricorso sia per esaminare la fonte e capire come ottenere quella proprietà generata/aggiornata sul redraw. – kaliatech

+0

In realtà preferisco il commento sopra come soluzione, in quanto quello proposto nella tua domanda risulta nel ridisegnare l'intero grafico. Oltre a un problema di interpolazione facilmente risolto, http://jsfiddle.net/kaliatech/khp9d/30/ è quello che stavo cercando –

0

Ho incontrato lo stesso problema. Ho cambiato la funzione y() sulle linee da

.y(function(d) { return d.display.y }) 

a

.y(function(d) { return d.display ? d.display.y : d.y }) 

Questo elimina l'errore. Ovviamente non visualizzerà il valore indicizzato (inesistente) nel caso di errore, ma nella mia esperienza, il grafico viene aggiornato di nuovo con la visualizzazione definita, e sembra corretto.

1

ho trovato quello che penso è una soluzione migliore. Il problema si verifica perché il grafico cumulativo imposta la funzione y durante l'elaborazione. Ogni volta che si desidera aggiornare il grafico, innanzitutto impostarlo su un valore predefinito che restituisce l'originale y corretto. Nella funzione di ridisegno fare questo prima di aggiornare:

chart.y(function (d) { return d.y; }); 

Ancora meglio sarebbe se il grafico cumulativo potrebbe farlo per se stesso (memorizzare la funzione di accesso originale prima di quello nuovo, e rimetterlo prima di ri-indicizzazione) . Se avrò la possibilità, proverò a spingere una soluzione.

Problemi correlati