În partea anterioară a acestui tutorial, am văzut cum să începem cu D3.js și am creat scale și axe dinamice pentru graficul de vizualizare utilizând un set de date de probă. În această parte a tutorialului, vom compila graficul utilizând setul de date de probă.
Pentru a începe, clonați codul sursă tutorial anterior din GitHub.
git clone https://github.com/jay3dec/PythonD3jsMashup_Part2.git
Navigați la directorul SDK Google App Engine (GAE) și porniți serverul.
./dev_appserver.py PythonD3jsMashup_Part2 /
Punctați browserul la http: // localhost: 8080 / displayChart și ar trebui să puteți vedea axele X și Y pe care le-am creat în tutorialul anterior.
Înainte de a începe, creați un nou șablon numit displayChart_3.html
care va fi la fel ca displayChart.html
. Adăugați, de asemenea, un traseu pentru displayChart_3.html
. Acest lucru este făcut doar pentru a menține demo-ul tutorialului anterior intact, deoarece îl voi găzdui pe același URL.
clasa DisplayChart3 (webapp2.RequestHandler): def get (auto): template_data = template_path = 'Templates / displayChart_3.html' auto.response.out.write (template.render (template_path, template_data)) application = webapp2.WSGIApplication ['/ displayChart3', DisplayChart3), ('/', ShowHome),], debug = Adevărat), ('/ chart', ShowChartPage)
Din setul nostru de date de probă, avem un număr de numara
care urmează să fie reprezentate pe un set corespunzător an
.
var 1592 ", " count ":" 179 "," "count": " 1595 ", " count ":" 1593 ", " count ":" 199 "," year " 176 "," anul ":" 1596 ", " contează ":" 172 "," anul ":" 1597 " numărătoarea: "160", "anul": "1602", "anul": "1599", , "count": "160", "count": "150", " : "1607", "contează": "1607", "numără": "133", "anul" , "anul": "1610", "număr": "91", "anul": "1611", "număr": "150", "anul";
Vom reprezenta fiecare dintre punctele de date ca cercuri în graficul nostru de vizualizare. D3.js oferă metode API pentru a crea diferite forme și dimensiuni.
În primul rând, vom folosi d3.selectAll pentru a selecta cercuri în interiorul elementului de vizualizare. Dacă nu se găsesc elemente, se va returna un înlocuitor gol unde putem adăuga cercuri mai târziu.
var cercuri = vis.selectAll ("cerc");
Apoi, vom lega setul nostru de date la cerc
selecţie.
var cercuri = vis.selectAll ("cerc") date (date);
Din moment ce selecția cercului existent este goală, vom folosi enter pentru a crea cercuri noi.
. Circles.enter () adăugați ( "SVG: cerc")
Apoi, vom defini anumite proprietăți, cum ar fi distanța dintre centrele de cercuri din X (cx
) și Y (cy
) axele, culoarea lor, raza lor, etc. Pentru preluare cx
și cy
, vom folosi XScale
și yScale
pentru a transforma anul și pentru a număra datele în spațiul de plotare și a trage cercul în zona SVG. Iata cum va arata codul:
var cercuri = vis.selectAll ("cerc") date (date); cerculeț (), .ettr ("r", "negru") // setați marginea cercului .attr ("r", 10) // stabilește raza .attr (" ", funcția (d) // transformă datele anului astfel încât să se întoarcă xScale (anul.d.); // poate fi reprezentat în spațiul svg) .attr (" cy ", funcția (d) // transformates numără datele astfel încât să returneze yScale (d.count); // poate fi reprezentat în spațiul svg). style ("fill", "red") // setează culoarea cercului
Salvați modificările și actualizați pagina. Ar trebui să vedeți imaginea de mai jos:
În prima parte a acestei serii, când am extras date de la BigQuery, am selectat aproximativ 1.000 de cuvinte.
SELECTARE cuvânt FROM [publicdata: samples.shakespeare] LIMIT 1000
Avem un set de date care conține o listă a tuturor cuvintelor care apar în toată lucrarea lui Shakespeare. Deci, pentru a face ca aplicația de vizualizare să dezvăluie câteva informații utile, vom modifica interogarea noastră pentru a selecta de câte ori un anumit cuvânt, de exemplu Cezar
, apare în lucrarea lui Shakespeare în anii diferiți.
Deci, conectați-vă la Google BigQuery și vom avea un ecran ca cel prezentat mai jos:
După ce ne-am conectat la Google BigQuery, vom avea o interfață în care să putem compune și verifica interogările SQL. Vrem să selectăm de câte ori apare un anumit cuvânt în toată lucrarea lui Shakespeare.
Deci interogarea de bază ar arăta astfel:
SELECT SUM (cuvânt_count) ca WCount, corpus_date FROM [publicdata: samples.shakespeare] WHERE cuvânt = "Caesar" GROUP BY corpus_date ORDIN DE WCount
Interogarea de mai sus ne dă un set de rezultate după cum se arată mai jos:
Să includeți, de asemenea, grupul de lucrări corespunzătoare numărului de cuvinte. Modificați interogarea după cum se arată pentru a include corpul:
SELECT SUM (word_count) ca WCount, corpus_date, group_concat (corpus) ca Lucrare FROM [publicdata: samples.shakespeare] WHERE cuvânt = "Caesar" și corpus_date> 0 GROUP BY corpus_date ORDER BY WCount
Setul de rezultate rezultat este prezentat mai jos:
În continuare, deschideți-vă app.py
și să creeze o nouă clasă numită GetChartData
. În interiorul acestuia, includeți instrucțiunea de interogare creată mai sus.
queryData = 'query': 'SELECT SUM (word_count) ca WCount, corpus_date, group_concat (corpus) ca WORK FROM "[publicdata: samples.shakespeare] WHERE word =" God "și corpus_date> 0 GROUP BY corpus_date ORDER BY WCount'
Apoi, creați un serviciu BigQuery împotriva căruia ne vom executa queryData
.
tableData = bigquery_service.jobs ()
Acum, executați queryData
împotriva serviciului BigQuery și tipăriți rezultatul pe pagină.
dataList = tableData.query (projectId = PROJECT_NUMBER, corp = interogareData) .execute () auto.response.out.write (dataList)
Include, de asemenea, o nouă rută pentru GetChartData
așa cum se arată.
aplicație = webapp2.WSGIApplication ('/ displayChart', DisplayChart), ('/ displayChart3', DisplayChart3) ,], debug = True)
În final, actualizați codul pe platforma GAE.
./appcfg.py actualizare PythonD3jsMashup_Part2 /
Punctați browser-ul dvs. la http://YourAppspotUrl.com/getChartData care ar trebui să afișeze datele rezultate din BigQuery.
Apoi, vom încerca să analizăm datele primite de la Google BigQuery și să le convertim într-un obiect de date JSON și să îl transmitem clientului pentru a procesa folosind D3.js.
În primul rând, vom verifica dacă există rânduri datalist
întors. Dacă nu există rânduri, vom seta răspunsul ca nul sau zero.
dacă 'rânduri' din dataList: # parse dataLista altceva: resp.append ('count': '0', 'year': '0', 'corpus': '0'
Apoi, vom analiza datalist
prin reluarea fiecărui rând și luarea numărului, anului și corpusului și crearea obiectului JSON necesar.
= = dict_list [1] corpus = dict_list [2] Dacă nu există o listă de date, resp.append ('count': count ['v'], 'year': year ['v'], 'corpus': corpus ['v' '0', 'an': '0', 'corpus': '0')
De când vom întoarce datele parsate ca JSON, importați biblioteca JSON
importați json
Și returnați răspunsul creat ca răspuns JSON.
auto.response.headers ['Content-Type'] = 'cerere / json' auto.response.out.write (json.dumps (resp))
Să facem, de asemenea, dinamic cuvântul cheie de căutare, astfel încât acesta să poată fi trecut ca parametru.
inputData = auto.request.get ("inputData") interogareData = 'query': 'SELECT SUM (word_count) ca WCount, corpus_date, group_concat (corpus) + inputData + '' și corpus_date> 0 GROUP BY corpus_date ORDER BY WCount '
Iată cum este clasa GetChartData
în cele din urmă arată:
clasa getChartData (webapp2.RequestHandler): def get (auto): inputData = auto.request.get ("inputData") queryData = 'query': SELECT SUM (word_count) ca WCount, corpus_date, FROM "[publicdata: samples.shakespeare] WHERE cuvântul =" '+ inputData + "" GROUP BY corpus_date ORDER BY WCount " tableData = bigquery_service.jobs () dataList = tableData.query (projectId = PROJECT_NUMBER, body = queryData) ) resp = [] dacă 'rânduri' în dataList: pentru rând în dataList ['rânduri']: pentru cheie, dict_list în row.iteritems (): count = dict_list [0] year = dict_list [1] corpus = ] resp.append ('count': count ['v'], 'year': year ['v'], 'corpus': corpus ['v' : '0', 'anul': '0', 'corpus': '0')) self.response.headers ['Content-Type'] = 'application / json' self.response.out.write (json. halde (resp))
Actualizați aplicația în GAE și îndreptați browserul spre http://YourAppspotUrl.com/getChartData și puteți vedea răspunsul returnat JSON.
Apoi, vom crea o interfață pentru interogarea dinamică a setului de date Google BigQuery din aplicația noastră. Deschide Template-uri / displayChart_3.html
și includeți o casetă de intrare în care vom introduce cuvinte cheie pentru a interoga setul de date.
Includeți un script jQuery în pagină și în evenimentul pregătit DOM, vom interoga metoda Python GetChartData
pe Introduce cheia
presa.
$ (document) .ready (functie () $ ("# txtKeyword") tasta (functie (eveniment) if (event.keyCode == 13) // Daca tasta enter apasati DisplayChart; InitChart (); / / Init Chart with Axis);
Creați o altă funcție DisplayChart
pe partea clientului, în care vom face un apel Ajax către Python GetChartData
metodă.
funcția DisplayChart () var cuvânt cheie = $ ('# txtKeyword') val (); $ .ajax (tip: "GET", url: "/ getChartData", date: inputData: keyword, dataType: "json" (xhr, errorType, excepție) console.log ("Eroare a apărut"););
Actualizați codul în GAE și indicați browserul dvs. la adresa http://YourAppspotUrl.com/displayChart3. Introduceți un cuvânt cheie, să zicem Cezar
, și apăsați introduce. Verificați consola browserului dvs. și ar trebui să vedeți răspunsul returnat JSON.
Apoi, să complotăm cercurile folosind răspunsul returnat. Deci, creați o altă funcție JavaScript numită CreateChart
. Această funcție este similară cu funcția InitChart
dar datele ar fi trecute ca parametru. Iată cum arată:
funcția CreateChart (date) var vis = d3.select ("# vizualizare"), WIDTH = 1000, HEIGHT = 500, MARGINS = top: 20, right: 20; .doc ([d3.min (date, functie (d) retur (parseInt (an., 10) - 5); ), d3.max (date, funcție (d) retur parseInt (an., 10);)]), yScale = d3.scale.linear () intervalul [HEIGHT - MARGINS.top, MARGINS. (date, functie (d) retur (parseInt (d.count, 10) - 5);), d3.max .count, 10);)), xAxis = d3.svg.axis () .scale (xScale), yAxis = d3.svg.axis () .scale (yScale) .orient ("stânga"); (0, "+ (HEIGHT - MARGINS.bottom) +") ") .call (" svg: g " (xAxis); ("+" ("+")) .attr ("class", "y axis" ); var cercuri = vis.selectAll ("cerc") date (date); ("r", "10") .attr ("cx", funcția (d) return xScale (d) ()).) () () ()) .attr ("cy", funcția (d) return yScale (d.count)
De la InitChart
, eliminați porțiunea de creare a cercului, deoarece nu va fi necesară acum. Iată cum InitChart
arată:
funcția InitChart () var data = ["count": "202", "anul": "1590", "count": "215" "1594", "count": "134", "year": "1595", "numărătoarea": "176", "anul": "1596", "contează": "172", "anul": "1597" "", "număr": "199", "anul": "1599", "număr": " "1602", "count": "179", "year": "1603", "count": "150", "year": " "," anul ":" 1607 ", " contează ":" 133 "," anul ":" 1608 " ":" 175 "," anul ":" 1610 ", " număr ":" 91 "," anul ":" 1611 "; ]; var culoare = d3.scale.category20 (); var = d3.select ("# vizualizare"), WIDTH = 1000, HEIGHT = 500, MARGINS = top: 20, right: 20, bottom: 20, left: 50, xScale = d3.scale.linear (d) (data, funcția (d) retur (parseInt (d.year, 10) - 5);), d3.max (date, functie (d) retur parseInt (an.year, 10);)), yScale = d3.scale.linear () domeniu ([HEIGHT - MARGINS.top, MARGINS.bottom] [d3.min (date, functie (d) retur (parseInt (d.count, 10) - 5);); d3.max (date, functie (d) returnare parseInt (d.count, 10); )), xAxis = d3.svg.axis () .scale (xScale), yAxis = d3.svg.axis () .scale (yScale) .orient ("stânga"); (0, "+ (HEIGHT - MARGINS.bottom) +") ") .call (" svg: g " (xAxis); ("+" ("+")) .attr ("class", "y axis" );
De acum înainte, când încărcăm / displayChart3
pagina, cercurile nu vor fi afișate. Cercurile vor apărea numai după ce cuvântul cheie a fost căutat. Deci, cu privire la apelul de succes al DisplayChart
Ajax apel, treci răspunsul la CreateChart
funcţie.
succes: funcția (răspunsul) console.log (răspuns); CreateChart (răspuns);
Actualizați codul la GAE și încercați să căutați cuvântul cheie Cezar
. OK, deci acum vedem rezultatul ca cercuri pe grafic. Dar există o problemă: ambele axe sunt suprascrise.
Deci, pentru a evita ca vom verifica în interiorul CreateChart
dacă axele sunt deja acolo sau nu.
var hasAxis = vis.select ("axă") [0] [0]; (0, "+ (HEIGHT - MARGINS.bottom) +"), dacă se are (! hasAxis) vis.append ("svg: g") .attr ("class" ")" .call (xAxis); ("+" ("+")) .attr ("class", "y axis" );
După cum puteți vedea, am verificat dacă elementul SVG are axe și dacă nu le creăm din nou. Actualizați codul la GAE și încercați să căutați din nou cuvântul cheie și ar trebui să vedeți ceva similar:
Deși toate arată bine acum, există încă câteva aspecte pe care le vom aborda în următoarea parte a acestui tutorial. De asemenea, vom introduce tranzițiile D3.js și câteva alte caracteristici ale graficului nostru D3.js și vom încerca să îl facem mai interactiv.
Codul sursă din acest tutorial este disponibil pe GitHub.