2013-07-01 13 views
9

Sto usando d3.js per visualizzare le timeeries: dati inviati dal mio backend Python (tramite Websocket). La normale quantità di dati per un grafico è di circa 120 voci (2 ore di dati, 1 voce per minuto). Funziona bene, viene aggiornato ogni minuto.Grande grafico d3.js, rendering su tela o lato server?

Ma dovrebbe anche essere in grado di visualizzare i dati da un mese o più (potrebbe essere fino a un anno), anche in un intervallo di 1 minuto. Il rendering di una tale quantità di dati è troppo per SVG.

Sto pensando delle seguenti alternative:

  • rendering in una tela. È davvero molto più veloce?
  • Il passaggio a un'altra libreria come Highchart.js (visto una demo con ~ 50K voci)
  • rendering SVG/JPG/PNG sul server. Qualsiasi esperienza sul rendering di d3.js lato server con ad es. phantom.js? Mi piacerebbe riutilizzare i modelli grafici già scritti. Ma potrebbe anche essere qualsiasi altra libreria che è in grado di rendere i dati (generare i grafici con python)

Cosa raccomanderesti?

+0

Vorrei discutere con l'approccio super-cool [rendering di file SVG sul client] (http://net.tutsplus.com/tutorials/why-arent-you-using-svg/). – Droogans

+0

@Droogans Sì, lo sto già facendo per i piccoli grafici. Ma i miei problemi sono i grandi grafici (con un'enorme quantità di dati) .. – Beastcraft

+0

Hmmm ... d3 dovrebbe funzionare bene con 120 punti dati. Quali sono i problemi con la soluzione d3? La tela è ottima per presentare grafici che cambiano dal secondo al secondo - sì, è molto più veloce. Ma non è forte sull'interattività (come drill-down o note informative a comparsa). Se si dispone di grafici statici da presentare (grafici che sono stati salvati nell'immagine), la tela può iniziare presentando un'immagine statica all'interno dell'area di disegno e quindi aggiornando l'area di disegno secondo necessità con datapoint aggiornati (la riutilizzabilità che ha menzionato). – markE

risposta

3

Nota che d3 supporta l'uso di javascript buffered arrays. I grafici SVG con migliaia di punti di dati di serie temporali hanno funzionato correttamente nella mia esperienza (anche con più fonti di streaming di dati in tempo reale con aggiornamenti di 20ms tramite websocket).

Ad esempio se si comprimono tutti i dati in Python; si potrebbe non bisogno di fare questo nella vista dal vivo come la frequenza di aggiornamento è relativamente lento:

import struct 
# fake data point 
p = [56435367, 200, 1] 
# <=little endian, d=float64 (for time), d=float64 
msg_str = struct.pack('<' + 'd' * len(p), *p) 
print(msg_str) 
b'\x00\x00\x008\x15\xe9\x8aA\x00\x00\x00\x00\x00\[email protected]\x00\x00\x00\x00\x00\x00\xf0?' 

Poi tramite il vostro websocket che arriva a javascript, dove si può fare qualcosa di simile:

this.ws.onmessage = function(e){ 
    // Just pump the raw bytes straight into CircularBuffer 
    graph.databuffer.push(e.data); 
    ... 

E quando si desidera tracciare, assumendo g è il tuo riferimento al svg D3:

// Get a Float64Array containing all the values 
var series_data = graph.databuffer.get_array_stream(); 
g.attr("d", graph.line(d3.zip(time, series_data))); 

Naturalmente questo dovrebbe essere ancora più facile se si dispone di tutti i dati in anticipo. Stai forse tracciando punti invece di un singolo percorso? Ho trovato i browser che lottano con il disegno di decine di migliaia di cerchi individuali (specialmente se si spostano tutti ogni 20ms!) Ma possono gestire un percorso molto facilmente.