Nella parte precedente di questo tutorial, abbiamo visto come iniziare con D3.js e abbiamo creato scale e assi dinamici per il nostro grafico di visualizzazione utilizzando un set di dati di esempio. In questa parte del tutorial, tracceremo il grafico utilizzando il set di dati di esempio.
Per iniziare, clonare il codice sorgente del tutorial precedente da GitHub.
git clone https://github.com/jay3dec/PythonD3jsMashup_Part2.git
Accedi alla directory dell'SDK di Google App Engine (GAE) e avvia il server.
./dev_appserver.py PythonD3jsMashup_Part2 /
Indirizza il tuo browser a http: // localhost: 8080 / displayChart e dovresti essere in grado di vedere gli assi X e Y che abbiamo creato nel tutorial precedente.
Prima di iniziare, crea un nuovo modello chiamato displayChart_3.html
che sarà lo stesso di displayChart.html
. Aggiungi anche un percorso per displayChart_3.html
. Questo è fatto solo per mantenere intatta la demo del tutorial precedente, dato che lo ospiterò sullo stesso URL.
class DisplayChart3 (webapp2.RequestHandler): def get (self): template_data = template_path = 'Modelli / displayChart_3.html' self.response.out.write (template.render (template_path, template_data)) application = webapp2.WSGIApplication ( [('/ chart', ShowChartPage), ('/ displayChart', DisplayChart), ('/ displayChart3', DisplayChart3), ('/', ShowHome),], debug = True)
Dal nostro set di dati campione, abbiamo un numero di contare
da tracciare attraverso un insieme di corrispondenti anno
.
var data = ["count": "202", "year": "1590", "count": "215", "year": "1592", "count": "179", " year ":" 1593 ", " count ":" 199 "," year ":" 1594 ", " count ":" 134 "," year ":" 1595 ", " count ":" 176 "," year ":" 1596 ", " count ":" 172 "," year ":" 1597 ", " count ":" 161 "," year ":" 1598 ", " count ":" 199 "," year ":" 1599 ", " count ":" 181 "," year ":" 1600 ", " count ":" 157 "," year ":" 1602 " , "count": "179", "year": "1603", "count": "150", "year": "1606", "count": "187", "year" : "1607", "count": "133", "year": "1608", "count": "190", "year": "1609", "count": "175" , "year": "1610", "count": "91", "year": "1611", "count": "150", "year": "1612"];
Rappresenteremo ciascuno dei punti dati come cerchi nel nostro grafico di visualizzazione. D3.js fornisce metodi API per creare varie forme e dimensioni.
Innanzitutto, utilizzeremo d3.selectAll per selezionare i cerchi all'interno dell'elemento di visualizzazione. Se non vengono trovati elementi, verrà restituito un segnaposto vuoto in cui possiamo aggiungere cerchi in un secondo momento.
var circles = vis.selectAll ("circle");
Successivamente, legheremo il nostro set di dati al cerchi
selezione.
var circles = vis.selectAll ("circle"). dati (dati);
Poiché la nostra selezione di cerchi esistente è vuota, utilizzeremo enter per creare nuove cerchie.
. Circles.enter () aggiungere ( "svg: cerchio")
Successivamente, definiremo determinate proprietà come la distanza dei centri dei cerchi dalla X (cx
) e Y (cy
) assi, il loro colore, il loro raggio, ecc. Per andare a prendere cx
e cy
, useremo xScale
e yScale
per trasformare l'anno e contare i dati nello spazio di tracciamento e disegnare il cerchio nell'area SVG. Ecco come apparirà il codice:
var circles = vis.selectAll ("circle"). dati (dati); circles.enter () .append ("svg: circle") .attr ("stroke", "black") // imposta il bordo del cerchio .attr ("r", 10) // imposta il raggio .attr ("cx ", function (d) // trasforma i dati dell'anno in modo che restituisca xScale (d.year); // può essere tracciato nello spazio svg) .attr (" cy ", function (d) // transforms i dati di conteggio in modo che ritorni yScale (d.count); // può essere tracciato nello spazio svg) .style ("fill", "red") // imposta il colore del cerchio
Salva le modifiche e aggiorna la tua pagina. Dovresti vedere l'immagine qui sotto:
Nella prima parte di questa serie, quando abbiamo recuperato i dati da BigQuery, abbiamo selezionato circa 1.000 parole.
SELEZIONA la parola FROM [publicdata: samples.shakespeare] LIMIT 1000
Abbiamo un set di dati che contiene un elenco di tutte le parole che appaiono in tutte le opere di Shakespeare. Quindi, per fare in modo che l'app di visualizzazione riveli alcune informazioni utili, modificheremo la nostra query per selezionare il numero di volte in cui una determinata parola, ad esempio Cesare
, appare nel lavoro di Shakespeare in diversi anni.
Quindi, accedi a Google BigQuery e avremo una schermata come quella mostrata di seguito:
Dopo aver effettuato l'accesso a Google BigQuery, avremo un'interfaccia in cui possiamo comporre e controllare le nostre query SQL. Vogliamo selezionare il numero di volte in cui una parola particolare appare in tutte le opere di Shakespeare.
Quindi la nostra query di base sarebbe simile a questa:
SELECT SUM (word_count) come WCount, corpus_date FROM [publicdata: samples.shakespeare] WHERE word = "Caesar" GROUP BY corpus_date ORDER BY WCount
La query sopra ci fornisce un set di risultati come mostrato di seguito:
Includiamo anche il gruppo di lavori corrispondente al Conteggio parole. Modifica la query come mostrato per includere il corpus:
SELECT SUM (word_count) come WCount, corpus_date, group_concat (corpus) come Work FROM [publicdata: samples.shakespeare] WHERE word = "Caesar" e corpus_date> 0 GROUP BY corpus_date ORDER BY WCount
Il set di risultati risultante è mostrato di seguito:
Avanti, aperto app.py
e creare una nuova classe chiamata GetChartData
. Al suo interno, includi la dichiarazione della query che abbiamo creato sopra.
queryData = 'query': 'SELECT SUM (word_count) come WCount, corpus_date, group_concat (corpus) come Work FROM "[publicdata: samples.shakespeare] WHERE word =" God "e corpus_date> 0 GROUP BY corpus_date ORDER BY WCount'
Quindi, crea un servizio BigQuery su cui eseguiremo il nostro queryData
.
tableData = bigquery_service.jobs ()
Adesso esegui il queryData
contro il servizio BigQuery e stampare il risultato sulla pagina.
dataList = tableData.query (projectId = PROJECT_NUMBER, body = queryData) .execute () self.response.out.write (dataList)
Includere anche un nuovo percorso per GetChartData
come mostrato.
application = webapp2.WSGIApplication ([('/ chart', ShowChartPage), ('/ displayChart', DisplayChart), ('/ displayChart3', DisplayChart3), ('/ getChartData', GetChartData), ('/', ShowHome) ,], debug = True)
Infine aggiorna il codice alla piattaforma GAE.
./appcfg.py update PythonD3jsMashup_Part2 /
Puntare il browser su http://YourAppspotUrl.com/getChartData che dovrebbe visualizzare i dati risultanti da BigQuery.
Successivamente, tenteremo di analizzare i dati ricevuti da Google BigQuery e convertirli in un oggetto dati JSON e trasferirli sul lato client per elaborare utilizzando D3.js.
Innanzitutto, controlleremo se ci sono delle righe in Datalist
restituito. Se non ci sono righe, imposteremo la risposta come nulla o zero.
if 'rows' in dataList: # parse dataList else: resp.append ('count': '0', 'year': '0', 'corpus': '0')
Successivamente, analizzeremo il Datalist
eseguendo il ciclo di ciascuna riga e rilevando il conteggio, l'anno e il corpus e creando il nostro oggetto JSON richiesto.
risp = [] se 'rows' in dataList: per riga in dataList ['rows']: per chiave, dict_list in row.iteritems (): count = dict_list [0] anno = dict_list [1] corpus = dict_list [2] resp.append ('count': count ['v'], 'year': year ['v'], 'corpus': corpus ['v']) else: resp.append ('count': '0', 'l'anno': '0', 'corpus': '0')
Dato che restituiremo i dati analizzati come JSON, importare la libreria JSON
importazione JSON
E restituire la risposta creata come risposta JSON.
self.response.headers ['Content-Type'] = 'application / json' self.response.out.write (json.dumps (resp))
Rendiamo anche dinamica la parola chiave di ricerca, in modo che possa essere passata come parametro.
inputData = self.request.get ("inputData") queryData = 'query': 'SELECT SUM (word_count) come WCount, corpus_date, group_concat (corpus) come Work FROM "[publicdata: samples.shakespeare] WHERE word ="' + inputData + '"e corpus_date> 0 GROUP BY corpus_date ORDER BY WCount'
Ecco come la classe GetChartData
finalmente guarda:
class GetChartData (webapp2.RequestHandler): def get (self): inputData = self.request.get ("inputData") queryData = 'query': 'SELECT SUM (word_count) come WCount, corpus_date, group_concat (corpus) as Work DA "[publicdata: samples.shakespeare] WHERE word =" '+ inputData +' "GROUP BY corpus_date ORDER BY WCount ' tableData = bigquery_service.jobs () dataList = tableData.query (projectId = PROJECT_NUMBER, body = queryData) .execute ( ) risp = [] se 'rows' in dataList: per riga in dataList ['rows']: per chiave, dict_list in row.iteritems (): count = dict_list [0] anno = dict_list [1] corpus = dict_list [2 ] resp.append ('count': count ['v'], 'year': year ['v'], 'corpus': corpus ['v']) else: resp.append ('count' : '0', 'year': '0', 'corpus': '0') self.response.headers ['Content-Type'] = 'application / json' self.response.out.write (json. discariche (resp))
Aggiorna l'app in GAE e indirizza il browser a http://YourAppspotUrl.com/getChartData e puoi visualizzare la risposta JSON restituita.
Successivamente, creeremo un'interfaccia per interrogare in modo dinamico il set di dati di Google BigQuery dalla nostra app. Aprire Modelli / displayChart_3.html
e includi una casella di input in cui inseriremo le parole chiave per interrogare il set di dati.
Includere uno script jQuery nella pagina e nell'evento DOM ready, faremo una query sul metodo Python GetChartData
sopra Tasto Invio
stampa.
$ (document) .ready (function () $ ("# txtKeyword"). keyup (function (event) if (event.keyCode == 13) // Se inserisci key premi DisplayChart ();); InitChart (); // Init Chart with Axis);
Crea un'altra funzione DisplayChart
dal lato client, all'interno del quale effettueremo una chiamata Ajax al Python GetChartData
metodo.
function DisplayChart () var keyword = $ ('# txtKeyword'). val (); $ .ajax (tipo: "GET", url: "/ getChartData", dati: inputData: parola chiave, dataType: "json", success: function (response) console.log (response);, errore: function (xhr, errorType, exception) console.log ('Errore occorso'););
Aggiorna il codice a GAE e indirizza il browser a http://YourAppspotUrl.com/displayChart3. Inserisci una parola chiave, ad esempio Cesare
, e premere accedere. Controlla la tua console del browser e dovresti vedere la risposta JSON restituita.
Quindi, tracciamo i cerchi usando la risposta restituita. Quindi creare un'altra funzione JavaScript chiamata CreateChart
. Questa funzione è simile a INITCHART
funzione ma i dati sarebbero passati come parametro. Ecco come appare:
function CreateChart (data) var vis = d3.select ("visualizzazione #"), WIDTH = 1000, HEIGHT = 500, MARGINS = top: 20, right: 20, bottom: 20, left: 50, xScale = d3 .scale.linear (). range ([MARGINS.left, WIDTH - MARGINS.right]). domain ([d3.min (data, function (d) return (parseInt (d.year, 10) - 5); ), d3.max (data, function (d) return parseInt (d.year, 10);)]), yScale = d3.scale.linear (). range ([HEIGHT - MARGINS.top, MARGINS. bottom]). domain ([d3.min (data, function (d) return (parseInt (d.count, 10) - 5);), d3.max (data, function (d) return parseInt (d .count, 10);)]), xAxis = d3.svg.axis () .scale (xScale), yAxis = d3.svg.axis () .scale (yScale) .orient ("left"); vis.append ("svg: g") .attr ("classe", "asse x") .attr ("transform", "translate (0," + (HEIGHT - MARGINS.bottom) + ")") .call (asseX); vis.append ("svg: g") .attr ("classe", "asse y") .attr ("transform", "translate (" + (MARGINS.left) + ", 0)") .call (yAxis ); var circles = vis.selectAll ("circle"). dati (dati); circles.enter () .append ("svg: circle") .attr ("stroke", "black") .attr ("r", 10) .attr ("cx", function (d) return xScale (d .year);) .attr ("cy", funzione (d) return yScale (d.count);) .style ("fill", "red")
Dal INITCHART
funzione, rimuovere la porzione di creazione del cerchio poiché non sarà richiesta ora. Ecco come INITCHART
sembra:
function InitChart () var data = ["count": "202", "year": "1590", "count": "215", "year": "1592", "count": "179", "year": "1593", "count": "199", "year": "1594", "count": "134", "year": "1595", "count": "176", "year": "1596", "count": "172", "year": "1597", "count": "161", "year": "1598 ", " count ":" 199 "," year ":" 1599 ", " count ":" 181 "," year ":" 1600 ", " count ":" 157 "," anno ":" 1602 ", " count ":" 179 "," year ":" 1603 ", " count ":" 150 "," year ":" 1606 ", " count ":" 187 "," year ":" 1607 ", " count ":" 133 "," year ":" 1608 ", " count ":" 190 "," year ":" 1609 ", " conteggio ":" 175 "," anno ":" 1610 ", " conteggio ":" 91 "," anno ":" 1611 ", " conteggio ":" 150 "," anno ":" 1612 " ]; var color = d3.scale.category20 (); var vis = d3.select ("visualizzazione #"), WIDTH = 1000, HEIGHT = 500, MARGINS = top: 20, right: 20, bottom: 20, left: 50, xScale = d3.scale.linear () .range ([MARGINS.left, WIDTH - MARGINS.right]). domain ([d3.min (data, function (d) return (parseInt (d.year, 10) - 5);), d3.max (data, function (d) return parseInt (d.year, 10);)]), yScale = d3.scale.linear (). range ([HEIGHT - MARGINS.top, MARGINS.bottom]). domain ( [d3.min (data, function (d) return (parseInt (d.count, 10) - 5);), d3.max (data, function (d) return parseInt (d.count, 10); )]), xAxis = d3.svg.axis () .scale (xScale), yAxis = d3.svg.axis () .scale (yScale) .orient ("left"); vis.append ("svg: g") .attr ("classe", "asse x") .attr ("transform", "translate (0," + (HEIGHT - MARGINS.bottom) + ")") .call (asseX); vis.append ("svg: g") .attr ("classe", "asse y") .attr ("transform", "translate (" + (MARGINS.left) + ", 0)") .call (yAxis );
Da ora in poi, quando carichiamo il / displayChart3
pagina, i cerchi non verranno visualizzati. Le cerchie appariranno solo dopo aver cercato la parola chiave. Quindi, sul callback di successo del DisplayChart
Chiamata Ajax, passare la risposta al CreateChart
funzione.
success: function (response) console.log (risposta); CreateChart (risposta);
Aggiorna il codice su GAE e prova a cercare la parola chiave Cesare
. OK, così ora possiamo vedere il risultato come cerchi sul grafico. Ma c'è un problema: entrambi gli assi vengono sovrascritti.
Quindi per evitare che controlleremo all'interno CreateChart
funzione se gli assi sono già lì o meno.
var hasAxis = vis.select ('. axis') [0] [0]; if (! hasAxis) vis.append ("svg: g") .attr ("classe", "asse x") .attr ("transform", "translate (0," + (HEIGHT - MARGINS.bottom) + ")") .call (xAxis); vis.append ("svg: g") .attr ("classe", "asse y") .attr ("transform", "translate (" + (MARGINS.left) + ", 0)") .call (yAxis );
Come puoi vedere, abbiamo appena controllato se l'elemento SVG ha assi, e se non li creiamo nuovamente. Aggiorna il codice su GAE e prova nuovamente a cercare la parola chiave, e dovresti vedere qualcosa di simile a questo:
Anche se tutto sembra a posto, ci sono ancora alcuni problemi che tratteremo nella prossima parte di questo tutorial. Introdurremo anche le transizioni di D3.js e alcune altre funzionalità nel nostro grafico D3.js e cercheremo di renderlo più interattivo.
Il codice sorgente di questo tutorial è disponibile su GitHub.