1.1
1.2
1.3
1.4
1.5
1.5.1
1.5.2
1.5.3
1.5.4
1.5.5
1.5.6
1.5.7
1.5.8
1.5.9
1.5.10
1.5.11
1.5.12
1.5.13
1.5.14
1.6
1.6.1
1.6.2
1.6.3
1.7
1.8
1.9
1.10
TableofContentsIntroduction
Abstract
Dankwoord
Inleiding
Gebruiktetechnologieën
PHP
JSON
MySQL
PostgreSQL
JavaScript
D3
NVD3
PostgreSQL
PGAdmin
Node
ReST
XQuery
Postman
Orbeon
Project
ProjectmetPHP
ProjectmetNode
ProjectmetScripturaEngage
Conclusie
Uitbreidingen
Appendices
Glossary
2
3
PostgreSQLdatavisualisationwithOrbeonandD3OnderstaandzaludescriptievanKennyEmbrechtskunnenlezen.DezeScriptieisgebaseerdophetwerkdatwerdgedaantijdensdestageperiodevan15februaritot31mei2016.
Introduction
4
AbstractHetdoelvanmijnstagewaseenmaniervindenomopeencorrecteenuniformemanierdatatelatenzien,dieeropelkmomenthetzelfdeuitziet,waardezedataookgetoondwordt.
Omdedatagrafischweertegeven2grafiekenbeschikbaar:
Eendynamische,dubbellaagsepie-chartdiemomenteelenkellokaalwerkt,omdatereenandereopbouwvandedatabaseisgemaaktdieInventiveDesignersnognietingebruikheeft(DitisdegrafiekwaarmomenteelnogaanverdergewerktmoetwordenomdatergezochtwordtnaareenmanierwaaropdeparentsenchildrendynamischwordenomgezetnaareenJSONdiedieperkangaandandemomentele2niveau's).
EentijdsgrafiekomdedatavanInventiveDesignersweertegeven.Dezetijdsgrafiekheeftdeoptieomeenviaeenkleineregrafiekeendeelvandezegrafiekteselecteren,enditdeelwordtdanvollediguitvergrootopdehoofdgrafiek.
Abstract
5
DankwoordIkzougraagmijnstagementorKurtSmolderenwillenbedankenvoordebegeleidingdoorheenmijnstage.Erwasnooiteenvraagteveelvoorhem,alsookwashetantwoordaltijdduidelijk.
OokInventiveDesignerswilikinhetalgemeenbedankenvoordekansopdezestage.Ikhoopdatzeoverhetalgemeentevredenzijn.
Dankwoord
6
StageInventiveDesignersInventiveDesignersiseensoftwarebedrijfdatgevestigtisinHoboken,Antwerpen.HetisgekendvoorzijnsoftwareScripturaEngage.
Inhetkantoorzelfzijndepersonenopgedeeldinploegen.Zezittenpercompetentiesamenaaneen'eiland'.Elkteamheeftookeenteamleider,die'smorgensdestand-upingoedebanenleidt.Iederteamdoetvanaf9uurzijnstand-up,dezeduurtongeveer15minuten.Tijdensdestand-upkomtiedereenbijelkaaromtevertellenwathijofzijgedaanheeftdevorigewerkdag,enwathijofzijvanplanisomvandaagtedoen.Indieniemandietsnodigheeftvaneencollegawordtditmeestalookhierevenaangehaald.Erwordtookverteldofereenmeetingisvooriemand,hoelanddezeduurtenwieerbijzalzijn.
OpdrachtDeactueleopdrachtbestaatuithettoevoegenvanextravisuelevormenaanhetbestaandeproductvanInventivedesigners.
Momenteelwordtdedataweergegevenopeenvrijsimplistischemanier.Ofweliserietssuccesvol,ofwelniet.Debedoelingisdusdatbvb.inhetgevalvan1000verstuurdemails,gezienkanwordenzienhoeveelersuccesvolwaren,enhoeveeleronsuccesvolwaren.Vandezeonsuccesvollemailswilmenwetenwaarhetnetisfoutgelopen.Zijndemailsnietaangekomendooreenfoutiefmailadres,foutindeserver,geennetwerk,...?
Dedatamoetpreciezerwordenvoorgesteld,opeenordelijkemanier.Zowelbij10waardenalsbij10000waarden.
ExtrauitlegTijdenshetlezenvandezescriptie,zalereenwegwordenbeschrevennaarhetactueleeindproduct.IkhadnognooitmetD3gewerkt,enhebduseenaantaltestprojectenengrafiekengemaakt.Dezewordendusookbeschreven,hoewelzetechnischnietsbijdragentotheteindproduct.
Inleiding
7
Inleiding
8
1.5TechnischIndeonderstaandepagina'swordendetechnologieën/programma'sbesprokendiegebruiktzijnomditprojecttemaken.
Indezepagina'sstaatenkelkortuitgelegdwatdetechnologie/hetprogrammadoetenhoeditgebruiktwordtinditproject.Depagina'szullendusnietalleinformatiegevendiejezalkunnenvindenaangaande:
PHPJSONMySQLPostgreSQLJavaScriptD3NVD3PostgreSQLPGAdminNodeReSTXQueryPostmanOrbeon
1.5.1PHP
PHPiseenprogrammeertaalontwikkeldomdynamischewebpagina'stemaken.Inditproject(enkelindeeersteweken)werdditgebruiktomdeback-endaantesprekeneneenlinktevormenvanfront-endnaardedatabase.PHPwerdhierdusgebruiktomdedatavanuitdedatabasenaardefront-endtesturen.
PHPwerdgebruikttotbleekdaterookeenReSTinterfacemoestwordengebruikt.VandaaruitiserovergeschakeldnaarnodeomdatdekennisvanNode.jsgroterisdanvanPHP.EenReSTinterfacevanNodeisaleensgebruiktgeweestineenanderprojectwaardoordatmakkelijkerteimplementerenisdandeReSTinterfacevanPHP.PHPheeftwelondersteuniningvoorReST.Erbestaanprogramma'szoalsLaravel,die
Gebruiktetechnologieën
9
kunnenhelpenomhetmakenvanReSTfulinterfacesinPHPtevergemakkelijken.BijdeinstallatievanLaravelinditprojectwarenerwelwatproblemen.Ookdiewordentoegelichtenuitgelegd.
1.5.2JSON
JSONofJavascriptObjectNotation,iseengestandaardiseerdgegevensformaat.JSONmaaktdataleesbaarvoordemens.Doorobjectentemakenmetattributenmeteenbijhorendewaarde,kanJSONonduidelijkeinformatieduidelijkergaanvoorstellen.Hetwordtgebruiktvooruitwisselingvandatatussenserverenwebapplicatie.
JSONishetformaatdat1vandegrafiekennodigheeftommeetewerken.HetJSONformaatisstandaardvoorD3,enalsjezelfjedatainhetjuisteformaatkankrijgen,kaneengrootdeelvandevoorbeeldcodevaneenaantalgrafiekenwordenovergenomen(mitshierendaareenkleineaanpassing).
1.5.3MySQL
MySQLiseenopen-sourcedatabasestructuurdiemetbehulpvanqueriesalledatauiteendatabasezalhalen.Ditwilzeggendatdedatauitdedatabasewordtgehaaldmetbehulpvanqueries.AangezienSQLveelgebruiktwordt,kanjemetbehulpvanfunctiesenormveelworkloadnaardeserveroverdragen.
MySQLwordtveelgebruiktmetPHP.Hetbestaatuiteenserverprogrammaeneencliëntprogrammaenwordtmomenteelveelgebruiktvoorwebsitesalsdatabase.Hetserverprogrammadraaitopdeserverzonderdatdegebruikerereigenlijkietsmeedoet.Hetcliëntprogrammawordtdangebruiktomtecommunicerenmetdeserver.Eenbekendefront-endvoorMySQLisphpMyAdmin.
1.5.4SequelPro
SequelProiseenGUIvoorMySQL.Dooreenvisuelelay-outkanergemakkelijkergewerktwordenindetabellen.DezeGUIisontwikkeldvoorMac.Erziteenqueryeditorin,zodatdedatabaseheeleenvoudigaangepastkunnenworden.Demogelijkheidvoordetoevoegingvanjedatabasesisookzeersimpel.
SequelProiszeermakkelijktegebruikenenteinstalleren.Jebenterookzeersnelmeeweg.
1.5.5JavaScript
Gebruiktetechnologieën
10
JavaScriptiseenobjectgeoriënteerdeprogrammeertaal.ZeisgrotendeelsgebaseerdopC++.
HetvoordeelvanJavaScriptisdatheteentaalisdienogaltijdgroeit,terwijlCdoorstandaardisatiealeenbeetjeisvastgeroest.
HetnadeeldaarentegenisdatJavatragerisbijhetcompilerenvandecode.
JavaScriptwintdelaatstejarenwelenormaanpopulariteitomdathetheelhandigisvoorHTMLwebsites.Hetheeftverschillendelibrariesmetcode(JQuery,Ajax,D3,...)enbiedtvoorelkprobleemeenoplossing.
1.5.6D3
D3iseenJavaScriptlibrarydiehettoelaatomdatategebruikendoormiddelvanHTML,SVGenCSS.OmdatD3weinigoverheadheeft,isheteenzeersnelframework.
ErzijntalvanvoorbeeldendietonenhoedegrafiekkanopgebouwdwordenmetD3.Nietalleeneengrafiekmaarooklandkaartenenanderedingenkunnengemaaktwordenmetdezelibrary.Hetiseenlibrarydiewordtondersteunddooreengigantischecommunitydieelkedagnieuwegrafiekenentechniekenlaatzien.
1.5.7NVD3
NVD3iseen'component'vanjavadiegebaseerdisopdeD3libraryvanJavaScript.DebedoelingisomdekrachtvanD3tegebruiken,enhieropeenfront-endtebouwendiededataveelbeterkanvisualiseren.
NVD3heeftookeengrotecommunity.DemeestemensendiesupportgevenrondD3doenditookrondNVD3.Hetmerendeelvanhetgebruikvandecodeisidentiekenisdaaromeenvoudigtegebruiken.
OmdathetuiteindelijkmaareenextensieisopD3zelf,isdedocumentatiewelbeperkt.Viastackoverflow,desourcecodedieNVD3beschikbaarsteltendeoptietothetlivemakenvaneenproject,zorgterwelvoordatbijeventueleproblemenaltijdergensterechtkan.
1.5.8PostgreSQL
Gebruiktetechnologieën
11
PostgreSQLiseendatabasestructuurdiemetbehulpvanqueriesalledatauiteendatabasezalhalen.DitissoortgelijkaanMySQL.HetisdestandaardDBapplicatievoorMacOSXservers.JSONVoordemacgebruikerishetdusaangeradenomPostgreSQLtegebruikeninplaatsvanMySQL.
PostgreSQLisookdedatabasevormdieInventiveDesignersgebruiktomalledataintezetten.AlsikmetMySQLzouwerken,zouikdusnietdevolleervaringkrijgenvanhetsysteemdatInventiveDesignersgebruikt.
1.5.9PGAdmin
PGAdminisvoorPostgreSQLwatSequelProvoorMySQLis.Hetiseenvisueleinterfacevoorhetmanagenvandebestaandedatabases.Omwillevandevisuelelay-outinplaatsvaneenterminalvensterisermeewerkenheeleenvoudig.Hetisvolledigopen-source,heeftondersteuningvoorLinux,Mac,Windows,FreeBSD,...
ViaPGAdminkunnenalledatabasesbekijkenmetallebijhorendetabellengeraadpleegtworden.Ookkunnenqueriesuitgevoerdworden,veldengewijzigdworden,...
1.5.10NodeJS
NodeJSiseenasynchrooneventdrivenframeworkdatzeersnelwerktenheelefficiëntis.NodeJSkanverschillendeconnectiesaanmetweinigoverhead.NodeJswerktopJavaScript,wateenvoordeelisomdatveelmensenJavaScriptkennen.Defront-endwerktmetjavascript,waardoorerminderproblemenzijnmethetdoorgevenvandatavandefront-endnaardeback-end.Omdatbeidesystemendezelfdetaalspreken,kandedataopdezelfdemanierverwerktworden.NodeJSlevertooknpmmee.DitiseenpacketmanagervoorNodeJswaardoorhetmakkelijkerwordtgemaaktomextramodulesteinstalleren.
1.5.11ReST
Ditiseensoftwarearchitectuurvanhetinternet.Hetismanieromwebsservicestemakenopbasisvandebestaandetechnologiëenvanhetinternet.ErwordtgebruikgemaaktvanURL'somadresseringtegebruikenendeHTTPmethodes(GET,POST,DELETEenPUT)omservicesaanteroepen.
HetprojectgebruikteenReSTstructuur(indenodeprojecten)omviaeenURLdedatatekrijgenuitdedatabase.Zowordenindefront-endgeenproblemenverkregenmethetophalenvandata.
Gebruiktetechnologieën
12
1.5.12XQuery
OmdatOrbeonnietwerktmetgewoneSQLqueries,moetenalleSQL-queries,herschrevenwordennaarXquery.
InprincipedoetXqueryhetzelfdealsSQL,alleenisXqueryspeciaalontwikkeldomdeXMLstructuurtegebruiken.XQuerygebruiktXPathomterefererennaareenspecifiekdeelineenXML-document.XqueryisontwikkelddoorW3C.
Hoewerkthet?
XQueryzelfwerktvanuit2syntaxis.VoorditprojectisdeFLWOR-synataxisgebruikt.FWLORrepresenteertde5instructiesdiejezoukunnengebruikeninjequery:For,Let,Where,Orderby,Return.
1.5.13Postman
PostmaniseenextensievanChromediegebruiktwordtomdeXQueriesgemakkelijktetesten.Vanzodradexquerygemaaktis,wordtinXMLformaatdeoutputvandequeryverkregen.DitisveelmakkelijkeromtedebuggenenechttetestenomdatandersviaOrbeonmeteendatamoetuitlezen.AangeziendeXQuerybijhetopbouwenredelijksnelverandert,zouelkekeerdeOrbeonpaginaookaangepastmoetenworden,omdemanierteveranderendiegebruiktwordtomdedatauittelezen.
1.5.14Orbeon
Orbeoniseenmanieromwebformsinjeapplicatietekunnensteken.HetwerktmetXMLengebruiktdestandaardvanW3Commetdezedataomtegaan.HetwerktvooralmetXMLenXHTML.
DeondersteuningdieOrbeonheeftvoorXQueryis(vanuithetstagebedrijfzovoorzien)minimaal.Erzijnredelijkveeldingendieunsupportedzijn(bvnestedforloops).
OrbeonmaaktgebruiktvanXPLenXSLfilesvoorstylingenformatting
Gebruiktetechnologieën
13
ProjectHetgemaakteprojectisopgesplitstin3delen.
1deelgemaaktmetPHPenHTML,datwerdgebruiktinhetbeginvandestage.DitprojectwaseenvoudigengebruiktePHPvoordedatabaseconnectieenHTML/JavaScriptomdeoutputtetonen/grafiekentetekenen.VanafdaterbekendwasdatReSTmoestgebruiktworden,iseroverschakeldnaarNodeJS.
1deelgemaaktmetNodeJS,datdeimplementatievaneenRestfulAPIondersteunde.ScripturazelfwerktookmetRestfulAPI'senzokwamendeprojectenalmeerovereen.MetNodeishetookeenvoudigerwerkenombepaaldedatasnellerenefficiënteruitdedatabasetekrijgen.Inhetandereprojectmoestvoorhetraadplegenvananderedataookdequerywordenaangepast.InnodekanbijkomendedataverkregenwordendooreenextraGETtemakenenviadezeGETeenanderequerytelatenuitvoeren.
1deelgemaaktmetScripturaEngage,waarinhetbestaandeprojectwerdgeïntegreerd.HierinwerdgewerktmetOrbeonenXQuery.
Project
14
6.Hetproject
6.1ProjectmetPHP/HTML
Omheteersteonderdeelvanhetprojecttedraaienisereigenlijknietsnodig.Ditzijnstatischepagina'sdiegewoonwathtmlcodebevattenomdedingentedoendiegedaanmoetenworden.Hetzijnalleprojectendiejekanvinden'Bachelorproef/InventiveDesigners/html'
DezeprojectenhaddennietstemakenmetheteindproductenwerdengemaaktomtelerenwerkenmetD3enzovoldoendekennisoptedoenomdebruikbaregrafiekentekunnenmaken.
PHPwerdinhetbegingebruiktomdeconnectienaardedatabasetevoorzien.DezeconnectiewerdlatervervangendoorroutesinNode.ViaPHPwerddedatadanuitdedatabasegehaald,ennaardefront-endinJavascriptdoorgestuurd.
InitiëelisergekozenvoorPHPomdatNodenietaangenaamontvangenwerdalsvoorstel.InPHPwashetooknogredelijkgemakkelijkomdedatavanuitdedatabasetehalen.
6.1.1Try-outs
Vienno
Deeersteprojectendiegemaaktzijngeweest,warengemaaktdoorhetvolgenvantutorials.Echtmoeilijkwarenzeniet,maarhetwasbeteromtebeginnenvanaf0enzekertezijndatallesgoedbegrepenwordt.Detutorialsdiegebruiktzijn,warenafkomstigvaneenkanaalvanyoutube.Dezetutorialsstartenvanafhetbeginvand3.daardoorwashetdusheeleenvoudigomdezelibraryteleren.
Dewaardendieinhetbegingebruiktwerdenomdegrafiekentemaken,warenallemaalhard-codedarrays.Zewarenpuurbedoeldomtekunnenspelenmetdedata.Zokoneenwaardewordenvermenigvuldigdmet100endeimpacthiervooropdegrafiekwordenaangegeven.Erwashiernoggeenenkeleconnectienaardedatabase.Hetwaslogischeromeerstmetfictievedataeengrafiektemakenomtecontrolerenofhetüberhauptmogelijkwas,daneerstdatauitdedatabasetehalenendanpastebeginnenmethetmakenvangrafieken.
ProjectmetPHP
15
1. 2. 3.
4. 5.
Hieronderdecodevande5degrafiekdieterverduidelijkingtoegelichtgaatworden.
varwidth=600,height=400,padding=50;
d3.csv("ages.csv",function(data){
varmap=data.map(function(i){returnparseInt(i.age)})
varhistogram=d3.layout.histogram().bins(8)(map)
varx=d3.scale.linear().domain([0,d3.max(map)])
ProjectmetPHP
16
.range([0,width]);
vary=d3.scale.linear().domain([0,d3.max(histogram.map(function(i){returni.length}))]).range([0,height]);
varxAxis=d3.svg.axis().scale(x).orient("bottom");
varcanvas=d3.select("body").append("svg").attr("width",width).attr("height",height+padding).append("g").attr("transform","translate(20,0)");
vargroup=canvas.append("g").attr("transform","translate(0,"+height+")").call(xAxis);
varbars=canvas.selectAll(".bar").data(histogram).enter().append("g");
bars.append("rect").attr("x",function(d){returnx(d.x);}).attr("y",function(d){returnheight-y(d.y);}).attr("width",function(d){returnx(d.dx);}).attr("height",function(d){returny(d.y);}).attr("fill","steelblue");
bars.append("text").attr("x",function(d){returnx(d.x);}).attr("y",function(d){returnheight-y(d.y);}).attr("dy","20px").attr("dx",function(d){returnx(d.dx)/2;}).attr("fill","#fff").attr("text-anchor","middle").text(function(d){returnd.y;});})
Dehoogteenbreedtevandegrafiekwerduiteraardgewoongegeven.Dedatavandegrafiekkwamuiteen.csvfile(hierondereenkleindeeltjevande.csvfile).Dedatakanonderdezeuitlegwordenbekeken.
ProjectmetPHP
17
name,"age"Max,11Max,22Max,44Max,21Max,21Max,1Max,4Max,7Max,9Max,18
Dedatawerduitgelezenengekopiëerdineenvariabele.Dezevariabeleheeftnudeleeftijdvanelkobjectinde.csvfile.
Eenhistogramwashiereengoedekeuzealsgrafiek.Voordatawaarveelverschillendewaardenzijnisditeengoedegrafiek.Dewaardenkunnengegroepeerdwordenomzoeenietsduidelijkeregrafiektecreëren.
Deassenwerdengemaaktdoord3.scale.linearaanteroepen.Ditiseenfunctievanuitd3diewordtgebruiktomautomatischeenasstemaken.Dedatakonmeegegevenwordenvia.domain([0,d3.max(histogram.map(function(i){returni.length}))]))zodatdeasszelfhetminimumenhetmaximumkanbepalen.Met.rangewordtaangegevenhoehoogofhoebreeddeassis.Alsdeze2wordengecombineerd,weetdeasbv.datalser100pixelsbeschikbaarzijnen0en100deuiterstewaardenzijn,datwaarde50,50pixelsinbeslagzalnemen.
Hetelementcanvaswashetelementdatwerdtoegevoegdaandebodyvandepagina.Inhetcanvasvoegtd3alleelemententoe,zodatopheteinde1elementkanworden'geappend'.
Degroupstaatvoorhetfeitdatdebarsnietperwaardemaarpergegroepeerdewaardengetoondzoudenworden.
Bars.append("rect")voegtpergegroepeerdewaarde,eenrechthoektoevandejuistebreedteenhoogte(debreedteendehoogtesdeassenditberekenden)
Bars.append("text")voegtperbardeteksttoemetdecorrectehoeveelheidwaardendieindegegroepeerdestaafvoorkwamen.
Eenvolgendprobleemdatmeteentebinnenschoot.Watalsineenstaafdiagram,2waardesaanwezigzijndieenormveruitelkaarliggen?1staafmet10miljoenalswaardeen1met20.Debedoelingwasdusdatjein1oogopslagkonzien,datde
ProjectmetPHP
18
waardevandeenestaafenormveelgroterwasdandeanderestaaf.
Bovenstaandefototoontlineaireschalingopeenstaafdiagram.Hoegroterdewaardevaneenstaaf,hoegroterdezezalzijnalsjedezestaafvergelijktmetanderestaven.
Bijdeeerstepogingwasditalredelijkinorde.Dewaardenzijnzichtbaargroterofkleiner.Maarhetprobleemhierbijwasdatbijeentegrotewaarde,detekstvandekleinerewaardenindestaafdiagrammennietmeerzichtbaarwas.
Eenoplossinghiervoorisbestaaterindetekstonderdegrafiektezetteninplaatsvanopdestaaf.Zelfsalsdestaafmaareenwaardevan1heeft,isdezenogperfectleesbaar.
Omdewaardentochextraduidelijktetonen,isereenmouseovereventtoegevoegd.Dezemouseovertoontbijeenmouseover,eentooltip.Dezetooltipzalallewaardentonenvandestaven,alsermetdemuisovereenstaafwordtgegaan,volgttooltipookdepositievandemuis.
ProjectmetPHP
19
Alleoefeningenkanuhiervinden.
Nahetmakenvandezeoefeningen,waseraleenbasisgelegd.Dezebasisgingenwegebruiken,incombinatiemetactueledata.
6.1.2PHPcode
Onderstaandecodewasdecodedieervoorzorgtdatdedatawordtuitgelezen.Zoalsindecodeweergegeven,selecteerthetprogrammaenkelde__statevandetabel.Dezewaardenwordenineenarraygeduwd.
//MakeconnectiontoPostgreSQLserver$conn=pg_pconnect("host=localhostport=5432dbname=FullDBuser=postgres");$result=array();
//Readallstatesfromcommtable$result=pg_query($conn,"SELECT__stateFROMcomm");$values=array();
//Aslongastherearevaluesin$result,keepreadingandputreadrowin$values//$resultistoorawforjsontostringifywhile($row=pg_fetch_row($result)){$values[]=$row;}
echojson_encode(array_values($values));
DeSQLqueryopdatmomentwas:SELECT__stateFROMcommWeselecterenallestatesvanallerijenindecommtabel.Ditisredelijkinefficiënt.Alsereentabelvan10miljoenrijenaandezecodewordtgekoppeld,daniseenstandaardlaptop3uurbezig
ProjectmetPHP
20
omenkeldequeryuittevoeren(wordtlaternogeensaangehaald).
Omdedatawerkbaartemaken,moeterietsgebeurenmetdePHPoutputdata.ViaJSONzaldedatain1grotestring-arraygegotenworden.
DezestringwerdnaarJavaScriptgestuurd.Nuommetdatatewerken,kondezenietineenstringblijven.
ProjectmetPHP
21
functioncalculate(){dataset.sort();
varprevious="";varcount=0;varprevCount=0;for(vari=0;i<dataset.length;i++){if(dataset[i].toString()!=previous.toString()){//tellen++;if(count!=0){state.push(previous.toString());amount.push((count+1)-prevCount);b.key=previous.toString();b.recurrence=(count+1)-prevCount.toString();prevCount=count;console.log("Push"+(a.length+1)+":"+b.key+":"+b.recurrence);a.push(b);}varb={"key":"","recurrence":""};}else{count++;}previous=dataset[i];}state.push(previous.toString());amount.push((count+1)-prevCount);b.key=previous.toString();b.recurrence=(count+1)-prevCount.toString();prevCount=count;console.log("Push"+(a.length+1)+":"+b.key+":"+b.recurrence);a.push(b);console.log(a);//console.log("Wat?"+a.length);for(vari=0;i<a.length;i++){console.log("Waarde"+(i+1)+""+a[i].key+"komtintotaal"+a[i].recurrence+"keervoor.");}};
ProjectmetPHP
22
Bovenstaandecodeishetprototypedatwerdgebruiktomdedatainobjectentekrijgen.Metdezeobjectenwashetvlotwerken.AchterafisgeblekendathetefficiënterwasgeweestdezeobjectenrechtstreeksinJSONtegebruiken.
Zoalszichtbaatindecode,wasdecliëntsideverantwoordelijkvoorhetsorterenvandedata.Bijdatabasesvantienduizendenofmiljoenenrijen,zoudeworkloadechteronhandelbaarzijnvooreengewonecomputeroflaptop.
6.1.3SQL
Zoalseerdervermeld,wasdeeersteSQLquerynietefficiënt.Dezemoestdusherwerktworden.Inplaatsvanhetsorterenaandecliëntsidetedoen,konditwordengedaanaandekantvandeserver.Deserverisoverhetalgemeeneenveelkrachtigere'PC'.Dezeserverdusgeenmoeitemogenhebbenmetdequery.Tochwerddequeryvernieuwdomdekwaliteitvanhetprojectoptekrikken.
Nieuwequery:
"Select__state,Count(__state)FROMcommGROUPBY__state"
Deworkloadwordtnubijdeservergelegdwaardoordecliëntzichnietsmeermoetaantrekkenvanhetverwerkenvandedata.
6.1.4Kleuren
Eenvanderedenenwaaromditprojectwerdopgestartisdatdemomenteleoplossingnietuniformis.Debedoelingisdathetgeenwordtafgeleverduniformiteitlevert.Dekleurenmoetentenallentijdehetzelfdezijn.
Omdittedoen,werdereenarraygecreëertmetde__statesvandetabelin.Zokunnenweeenkleurindexgevenaanelkewaardeindearrayenzalvoorelketabeldezelfdekleurenarraywordengebruikt.Dezekleurenarrayverandertnietenzovoorzienwedusuniformiteitinhetproject.
6.1.5Doorklikken
Devolgendestapinhetprojectwashetdoorklikkenvandegrafieken.
Zoalsgekendzijneronderverdelingenindedatabase
ProjectmetPHP
23
Mailbatch-print.generation.started,no-archive-generation,no-email-generation,no-mypension-generationMailTestbatch-print.delivery.waiting,no-archive,no-email,no-mypension
SocialTwitterFacebookLinkedInGoogle+
FilePDFFiletest
DebedoelingisomeerstMail,SocialenFiletelatenzien,endaarnaasthetaantalkeerdatdezevoorkomen.
Momenteelwerktditnogmaarzeerrudimentair.Hetprobleemisdatdequerynietopnieuwverzondenkanwordenomnieuwedatatekrijgen.
Problemenmetdezemethodevanwerken
VanuitdejavascriptfilekannietterugwordengegaannaardeHTMLfileomdeSQLaantepassen...Hierdoorwordtergeennieuwegrafiekgetoondvandemedia,tenzijeropeenbepaaldemediawordtgekliktomhiervoordeSQLaantepassen,endanallekanalenvanditmediagaantonenineenvernieuwdetabel.AlswedePHPcodeineenafzonderlijkefilestekenkrijgjedezenietmeeruitdevariabelediewordtgegeven,waardoorergeenmogelijkheidmeerisomvanuitdejavascriptfiledePHPfileaanteroepen.DeSQLkannietwordenaangepastdathijoutputtoontzoalseenaccessdatabasetabeldatdoet.Ditisdemediatonen,hoeveelaantallenvandezemediaendandekanalenmethunhoeveelheden.Bijdetallozelinksdieerbeschikbaarzijnophetinternetendeontelbaretutorialsofhow-to'soverdequeries,subqueries,...iserniemanddieprobeertwaterinditprojectgeprobeerdwordt,ofaangeeftdathetmogelijkis.
6.1.6Nieuwequeries
ProjectmetPHP
24
Omhetwerkwattevergemakkelijkenwerdenerterugnieuwequeriesopgebouwd.Dezequerieswareneffectieverdandevorigeomdatzedenaamgevingenkunnenveranderdenenfilteringomeenbepaaldkanaalmogelijkmaken.
SQL's;SELECTMedia,Count(Media)FROMcommGROUPBYMedia;SELECTMedia,Count(state),stateFROMcommGROUPBYMedia,__state;
SELECTMedia,Count(state),stateasRecurrencesFROMcommwhereMedia='SocialMedia'
Zokanbv.vanalleSocialMedia,allesubkanalenoproepenenaangevenhoeveelkeerdezevoorkwamen.Ditwasaleenkleinevoorbereidingvoordevolgendestapinhetproject,namelijkhettoevoegenvaneenReSTfulAPI.
ProjectmetPHP
25
6.2ProjectmetNode
Omhettweededeellokaaltedraaien,meteeneigendatabase(watredelijkmoeilijkzouzijndoordevoorgedefiniëerdekleurcodes)moetenkelnodegeïnstalleerd(ensupervisorvooroptevolgenoferaldannietveranderingistoegebrachtindecode).
ViadezelinkkomjeterechtopsitevanNode.
6.2.1ReST
DevolgendestapishetimplenterenvanReST.
ReSTiseigenlijkeenmaniervanwerkendieervoorzorgtdatjemetsimpeleHTTP-protocollendatavandeserverkanwordengehaald.MengebruiktdeCRUDoperaties(Create,Read,UpdateenDelete)omaanpassingentedoennaardeservertoe(ofomsimpelwegdatatekunnenlezen).
DebedoelingisdathetprojectwerdherwerktzodatJavaScriptnietsvandatamoetdoorsturenmaaralleskantenklaarkrijgt.Alsdeserverallesverwerktendedatamoetdoorsturenzaldeclientnietveelvandeverwerkingmoetendoen.
6.2.2SQL
OmdewerkingvanhetReSTprojecttevergemakkelijken(enomdatdevorigeoplossingniet100%correctwas)zijndeSQLqueriesopnieuwverandert.
Omtebeginnenisereeneentabeltoegevoegdindedatabase.Hierdoorkonheteerdertoegevoegdextraveldwordengeëlimineerd.Hetishandigeromdezetabeltoetevoegenmet9rijen,daneenextraveldtoetevoegenaaneendatabasemeteentabeldiemisschienweleenmiljoenrijenbevat.Dezetabelbiedtookveelmogelijkhedenquauitbreidingnaardetoekomst.Momenteelheeftdetabel3hoofdkanalenen10subkanalen,maarnukaneensubkanaaleen'hoofdkanaal'wordenmetzijneigensubkanalen.
NadezeaanpassingkunnenwedeSQLquerygaanaanpassen.Omdatermet2verschillendetabellenwordtgewerktmoeteenjointoegepastwordenoponzequery.Detabellencomm(waardedatainstaat)enchannels(waardeverschillendekanalen,metcorresponderendesubkanalen,instaan)moetenmetelkaarverbondenwordenomzodehoofkanalenendesubkanalenaanelkaartekunnenlinken,metdebijpassendedata.
ProjectmetNode
26
SELECT__stateasstate,count(__state),chanFROMcomm,channelsWHEREchannels.com=comm.__state;
NustuurdedeSQLeenlijstdoormetallestates,dehoeveelheidvandezestatesenhetbehorendehoodkanaal,waarbijdestate(subkanalen)gelijkstaataaneensubkanaalvaneenhoodkanaal.Zowordteenlijstverkregenmetallehoofkanalen,methieronderdesubkanalenmethunhoeveelheid.
OmdatnumetReSTwordtgewerkt,kunnenerGETrequestswordengedaannaarverschillendepagina's.Dezepagina'sgingendusJSONdataterugsturennaardejavascriptfilewaardeGETrequestwerdgedaan.
ErwareneenpaargedefiniëerdeGETs.DeGETsgingenkijkennaarwelkepaginaerwerdgesurfteneencorresponderendequerylanceren.NadatdequerywasuitgevoerdwerddedatanaarNodegestuurd.Nodeontvingdedata,verwerktedeze,zodatalledataineenarrayzat,enstuurdedezearraydandoordepaginawaardeGETrequestwerduitgevoerd.Opdiewijzekonjevoorelkhoofdkanaal/subkanaalofalledatategelijkeenGETrequestwordenuitgevoerdendejuistedataverkregen.
Deandere.JSfileszijnookherwerkt.DeformatvandedataoutputiswatveranderdaangeziennumetReSTwordtgewerktenondertussenzijndequeriesookeensveranderd.
6.2.3Tabellen
Piechart1
DeeerstepogingtotgrafiekenmetdeReSTdata,waseendubbelepiechart.Dezecharthad2cirkels,eenbinnencirkelmetdehoofdkanaleneneenbuitencirkelmetdesubkanalen.Omdegrafiekinhetgeheelwatduidelijkertemaken,werderookeenpaddingvoorzientussenalledelenvandegrafiek.Zokanerexactwordengezientotwelkekanalendesubkanalenbehoren.
Hetprobleemmetdezegrafiekwasdater2apartequeriesen2apartefunctieswarenomdegrafiektetekenen.Ditzorgdevoorveeldubbelecodeenisdusnietefficiënt.Ermoest2keereenGET-requestgedaanworden,waardoordedata2xwerdontvangen,2xverwerkten2xgetekend.
ProjectmetNode
27
Nahetherbekijkenvandemomenteledatastructuurendegewenstedatastructuur,werderbeslistomdedatastructuurteherwerken.IndiendestructuurwerdnagebouwtdieD3gebruikt,konhetprojectgebruikmakenvaneenaantalvoorgemaaktegrafiekenmitseenpaaraanpassingenaandecode.
Piechart2(BiLevelPartition)
Nahetmakenvandevorigegrafiek,kwamdestagebegeleidermeteengoedidee.Inplaatsvandedegrafiekentetekenenaandehandvandedatadieweontvangen,washetmisschienbeterommeertijddestekeninhetontvangenvandedata,dezedataomtevormennaareengangbarevormdiewordtgebruiktinD3voorbeeldenomzoeenaantalgrafiekenhuncode(oftocheendeelervan)tekunnengebruiken.
EenmakkelijkemanierwasomgewooneenaantalarraysaanttemakendienadienineenJSONlikestringwordengezet.
MasterArrayDearraywaaraldehoofdkanaleninbewaardwerden
ChildrenArrayDearraywaaraldesubkanaleninbewaardwerden
CheckArrayDearraywaaraldegebruiktewaardeninbewaardwerden
Onderstaandecodecontroleerde,inderesultatenvandequery,voorelkewaarde,ofdezewaardenalindearraygebruiktwaren(hiergebeurdeeencontroleofdewaardealindecheckArraystaat).Zonietwordt,voorallesubkanalennagegaan^,ofzebijhetmomentelehoofdkanaalbehoorden.Indiendithetgevalis,wordendezewaardeninmijnchildrenArraygezet,alsookindecheckArray.
AlslaatstewerdindemasterArrayhethoofkanaalgepushed,samenmetallewaardendieindechildrenArrayzatenmaarwelrelevantzijnvoorhethuidigekanaal(Socialmediaontvangtdusalschildren:Facebook,Google+,Twitter,...)
ProjectmetNode
28
Hetprobleemmetbovenstaandecodewas,datereenArraytoekomtinhetproject.Voordeéénofdeandereredenkondegrafieknietwordengetekendmeteenarraywaarallesinzit.
Ditwerdopgelostdoorinplaatsvaneenarraytesturen,dearrayineenoverkoepelendobjecttesteken.Ditobjectwordtteruggestuurdterugnaaronzefilediegebruiktwordtomdegrafiektetekenenenklaar!
ProjectmetNode
29
Deonderstaandegrafiekzieteruitalsdevorigegrafiek,methetgroteverschildatdezegrafiekdeinteractiviteitheeftvanhetvoorbeeldvanMikeBostock.Hetisgeluktomdedatadieuitdequerykomtinhetcorrecteformaattekrijgenomhiermeetewerken.
Decodevoordekleurenvandegrafiek,waseigenlijkonveranderd.Dezekondusgerecupereerdwordenendezecodekongeherimplanteerdwordeninhetproject.
Bovenstaandegrafiekiseengrafiekdiezekergebruiktkanwordeninhetbestaandesysteem.Nuzouhetmooizijnomdepositievelijndoortetrekkenenmeerderegrafiekentekunnenontwikkelen.
Linechart
Delinechartdiehetprojectginggebruiken,waseenlijngrafiekdiedex-asgebruiktd.m.veentijdsaanduidingendex-asalswaardeaanduiding.Ditwildezeggendatdedatabasezoalsdienubeschikbaarwas,nietvoldeedaandeeisen.Dedatabasewasgevuldmetwaardenzondertijdsveld.Ermoestduseentijdsveldwordentoegevoegdaandezerijendiehetnogniethadden.Aangezienheteenspecialeformaatbetrof,gingditnietmakkelijkzijn.Hetformaatwas'timestampwithtimezone'maarhetprojectkongeengebruikmakenvanrandomdatums.Dedatumsmoestenongeveerbijelkaarliggenomzomakkelijkeraandebuggingtekunnendoen.
ProjectmetNode
30
$(document).ready(function(){$('#changeText').click(function(){for(vari=0;i<10000;i++){div.innerHTML=div.innerHTML+"('2016-"+03+"-"+getRandomDay()+"09:57:35.281+01'),";}
});});
Bovenstaandecodeiscodeuiteenjsfiddle.Dezefiddlegaat10000waardengevenindemaandmaart,lopendvandeeerstemaarttotdeachtstemaart.Viaeenupdatequerykondendezewaarden,opdecorrectewijzen,indetabelwordentoegevoegd.
Hetvolgendeprobleemwasdatdedatawordtontvangenopeenmanierdienietwerkbaarisvooreenlinechart.Viaeenparservand3kondedatumnaarhetcorrecteformaatomgezetworden.
Eenanderprobleemwasdatdemeestemensendielinechartsgebruiken,ofweleen.tsvfilegebruikenofweldexenycoördinatenmeegevenaandedataindeJSON.
Ditwerdopgelostdoorinplaatsvanzeteplaatsenmetwerkelijkexenycoördinaten,dezecoördinatentevervangendoordeplaatsopdetijdlijnenhunplaatsopdewaardelijn.hoegroterdewaarde,hoegroterdey-waarde.Hoelaterindetijd,hoegroterdex-waarde.
Onderstaandstaateenscreenshotvanhetprojectnahetproberentekenenvandeassen.Detijds-aszaggoeduitmaarerwarennogproblemenmetdewaardenvandey-as
ProjectmetNode
31
Erwarennogproblemenmethetvindenvandeminimumendemaximumwaardenindearray...Demeldingkwamsteedsweerdatdewaardendiegebruiktmoetenworden'undefined'zijn.
Metdecodedied3voorzietomminimumenmaximumtezoeken,kreeghetprogrammaonderstaandewaardenvandefuncties.Hoewelerietstezienwas,warendezegegevensnietechtcorrect.Hetminimumenmaximumzatongeveertussen15en700.Ditwashelemaalnietincorrect.Erzalzelfeenmaniergevondenmoetenwordenomdezewaardentezoeken.
ProjectmetNode
32
Naeenfunctietehebbengeïmplementeerdomhetprojectzelfhetminimumenmaximumtelatenzoeken,kreegdegrafiekdevolgendeas.Dewaardenbegonnenaleenbeetjemeertegelijkenopdewaardendieverwachtkondenworden,maarzewarenooknogeensomgedraaid...Aangeziendewaardennualbeterwarendanvoordien,zaterwaarschijnlijkeenprobleemindevergelijking.
Zoalsverwachtzathetprobleemindevergelijking.Hetprogrammacontroleerdedewaardeindearraymethetmomenteelminimumofmaximum.Erwerdvergelekenofdemomentelewaardegroterofkleinerwasdanhetminimumofmaximum.Demomentelewaardewerdenkelalstekstopgeslagen,duswerdookdetekstgecontroleerd(alsdewaardediedetekstheeftindeASCII-tabel).Nadewaardevandearrayteconverterennaareeninteger,werdendejuistewaardenwelgevonden,enwarenhetminimumenhetmaximumdusgevonden.
ProjectmetNode
33
Aangeziendeassennuinordewaren,konergewerktwordenmetdedata.Hettonenvanpuntenopdegrafiekwasdevolgendestap.
Omtelerenwerkenmettijdsgrafieken,washetlogischeromeersteenkleinetutorialtevolgenomeengrafiektemakendiemet'simpeledata'werkt.
ProjectmetNode
34
Nawataanpassingenindedata,toondehetprogrammaonderstaandresultaat.Hoewelernuallijnenstonden,werdenzeverkeerdgetekend.Inplaatsvantetekenenvandeeerstedagnaardelaatstedag,wordtergetekendvandehoogstewaardenaardelaagstewaarde.Opzoekingenophetinternetleverdengeenbruikbaarresultaarop.Alslaatsteredmiddelisereenpostopdecommunitystackoverflowgeplaatst.Deinputvanstackoverflowzalhopelijkhetcorrecteantwoordgeven.
Naverdereopzoekingenophetinternetbleekdatdemaniervansorterenindequerynietcorrectwas.Watergesorteerdwerdopzichwasgoed,enkeldevolgordewasnietcorrect.Nahetaanpassenvandequery,isdegrafiekwelcorrect.
ProjectmetNode
35
SELECT__stateasstate,creation_mdateasdate,count(__state)FROMcomm,channelsWHEREchannels.com=comm.__stateGROUPBYstate,chan,dateORDERBYchan,date;
Omdathetbekijkenvandewaardenineengrafiek,vooraldeze,tochmoeilijkwas,washeteengoedplanom'pointsofintrest'toetevoegen.Ditzijnpunten,bvbophetbeginvaneendag,waarmetdemuisoverkanworden'gehovered'.Hierdoorwordtdetooltipverkregendieeerervermeldisgeweestenkangezienwordenhoeveelkeereenbepaaldsubkanaalisgebruikt.
Kleuren
Nadienishetkleurenprobleemookopgelost.Hetprobleemwasdatvoorelkegroepindearray(10groepenindearray),elkewaardeinelkegroepwerdgecontroleerdopeencorresponderendenaam.Omdatelkewaardewerdgecontroleerd,werdelkekeereenpositieveoutputgegeven,enwordtduselkekeerdezelfdekleurgebruikt.Ditisopgelostdoorbovenliggendindeforeachloop,dekeyvandedegroepmeetegeven(destatevaneensubkanaal).
Legende
Bijdegrafiekwordtookeenlegendevermeld.Debedoelinghiervanis,datalsdegrafiektedrukoverkomt,ergekliktkanwordenopeenbepaaldsubkanaal.Dezelijnzaldanverdwijnenopdegrafiek.Zokandegrafieknauwkeurigerbekekenworden.
Debugdiehierbijkwamkijkenwaswelhardnekkig.Erkonop6vande10subkanalengekliktworden,endanverdweendecorresponderendelijnindegrafiek.Bij4subkanalengebeurdeditniet.NublijktdatdeSelectAllfunctievanjavascriptproblemenheeftmetallenietalfa-numeriekekarakters.Hetgevolghiervanisdatallekomma's,spaties,punten,enzovoortsproblemengaven.DenaamgevingvandeID'swasdusdeoutputvandequery.Hierinzatennietalfa-nummeriekekaraktersinenditgafdusproblemen.Deoplossing:bijhettoevoegenvandeID'swordenallenietalfa-nummeriekekaraktersdoor'niets'vervangen,waardoordeID'sgewoon1langestringzijn.Hetisnietvolgensderegels,maarhetwerktendenaamgevingwasooknogredelijkduidelijk.
Brush
ProjectmetNode
36
Hetvolgendeonderdeelwaseenbrush.Ditiseenonderdeelvandegrafiek,waaropeenselecterdeelvandegrafiekkangeselecteerdworden.Meestalisditeengrafiekwaarermettijdwordtgewerkt.Inditgevalisdebrusheenkleineversievandegrafiek.Dezegrafiekgeeftdemogelijkheidomeendeelteselecteren.Hetdeeldatgeselecteerdis,zalopdegrotegrafiekwordenuitvergroot.Zokanjemetbehulpvandebrush,degrotegrafiekindetailbekijken.
Opditmomentzittenernogeenaantalbugsindefunctionaliteitvandebrush.Deminiatuurgrafiekendemogelijkheidomeendeelteselecterenwerktperfect,maaralsdegrotegrafiekditnaderwiltbekijken,danwordtdebreedteplotsgroterenverdwijnendekleurenopnieuw.Alsnadienopdelegendewordtgekliktomdelijnentelatenverdwijnen,werkteditnogwelmaarwordendelijnenindefoutievekleurenweergegeven.
Meeting
NaeentussentijdseevaluatiewerdergezegddathetprojectgeïntegreerdwordtmetOrbeon.Ondanksdatsommigedingennogfunctioneelwaren,werdbeslistomdezestapalingangzetten.
Debugsdienoginhetprojectzaten,werdennadezeintegratiewelverwijderddoordejavascriptfilesaantepassenwaarmeedegrafiekenmeewordengemaakt.
AlsalleswerdgeïntegreerdmetOrbeonzullenerwelwatproblemendekopopsteken.VermitsOrbeoneenanderemanierheeftomqueryresultatenteoutputtenzalditzouweleenswatproblemenkunnengeven...
ProjectmetNode
37
ProjectmetNode
38
6.3ProjectmetScripturaEngage
Voorhetderdedeelhebjeeenscripturainstallatienodig.DitisteverkrijgenvanuitInventiveDesigner.AllesdraaitoplokaleScripturaserverswaardoorjevolledigonafhankelijkvaneenanderapparaatkanwerken.ScripturazelfwerktmetOrbeon.OrbeonwordtgebruiktvoorsecurityenookomdathetwerktmetXML.
DeScripturainstallatiediegeïnstalleerdwerdvoorditprojectwasvolledigclean.ErstaatnietsopbehalvedestandaarddingendiemeegeleverdwordenmetScriptura.Depagina'sdieBavoheeftgebruikt,gaanwelbeschikbaarwordengesteldzodatdecodeenmaniervanwerkeneensbekekenkanworden.
WatisScripturaEngage?
ScripturaEngageishetprogrammaontwikkelddoorInventiveDesigners.Hetiseensoftwareplatformdatwekunnenverdelenineenaantaldelen.DezedelennemenelkeencomponentvanScripturaEngagevoorhunrekening.
Design&compose
DetemplatedesignerisgemaaktzodatdeklantenvanInventiveDesignerstemplateskunnenontwikkelendieeraltijdhetzelfdeuitzien(oftochzogoedmogelijk).Zekunnenereenstijlaantoevoegen,herbruikbareobjectenvoormakenenerisondersteuningvoormeerderetalen.
Dedocumentflowdesigneriseentooldieisontwikkeldomvanuiteenbepaaldemap,naarwelkend-pointook(printers,mails,websites,PDF's),datateoutputten.Erzijnbepaaldecomponentendiejekantoevoegenomdeoutputnogbetertemaken,enwanneerdedocumentflowdesignerinwerkingtreedtkanookzelfgekozenworden(Schedule,hotfolder,webinput,...)
Correspondencemanagement
LiveDocsisontwikkeldomsnel,maartochpersoonlijkcontacttezoekenmetklanten.Jekanparagrafenmakenenkiezenomdezewelofnietineenbepaalddocumentintesluiten,datalateninvoegenenzoveelmeer.
WebForms
ProjectmetScripturaEngage
39
Ditzorgtervoordatdeklanteneenwebformulierkunnenmakendathunklantendanweerkunneninvullen.DezekunnengemaaktwordenviadeTemplateDesigner.Erisinputvalidation,SOAPondersteuning,verschillendeondersteundedatatypes,...
Mobile
MobileondersteundzorgtervoordatjeScripturacomponentenenserviceskangebruikenoptabletsentelefoons.Opdiewijzekunnenpushnotificationsnaartablets&telefoonsenmobiledatacaptureverstuurdworden,zodatdeformulierenrechtstreeksdigitaaluitgevoerdkunnenworden(bvb.terplekkebijeenklant).
Multichanneldelivery
Ditgeeftdemogelijkheidomdata-outputopallemanierenbijdeklantenteverkrijgen.bv.eenmailsturen,eengeprintfactuur,eenpdf,...Dezedingenkunnenookgecombineerdworden.Bv.eenmailsturenenna3softbouncestochopterenvooreengeprinteversie.Ditzorgtervoordatdeklantenaltijddegewenstecommunicatiezullenontvangen.
Communicationcenter
Ditisdecomponentwaarvoorhetprojectbedoeldis.Ditisde'website'diescripturaaanbiedt,gevuldmetdedatavandedatabase.Hiervoorwordtdegrafiekgemaaktenkanalledatabekekenwordendieinjedatabasezit.Hierkanjeallecommunicatiesbekijken,alledetailsvanmislukteofgeluktemails,allemailsdiegelinktzijnaan1job,...Degrafiekendiegemaaktwordenzullendezedataopeenmooiereenpraktischeremaniermoetenweergeven.
6.3.1Orbeon
Orbeonwerdgebruiktvooralvoorde'veiligheid'vanhetproject.HetblijktdatOrbeonallesecurity/uservalidationopzichneemt.Ditzorgtervoordatjejenietmoetbezighoudenmettokensrefreshen,altijdcredentialsopgeven,...
OrbeonkonookgeengebruikmakenvannormaleSQLqueries.Watwilzeggendatdequeryeenanderformaatmoetaannemen,namelijkXQuery.XQueryiseigenlijkhetzelfdealsSQLmaargeeftdedatateruginXMLformaat.DitformaatisvoorOrbeonideaalomuittelezenenmeetewerken.
6.3.2Xquery
ProjectmetScripturaEngage
40
ZoalseerdervermeldgebruiktOrbeonechtergeenSQLqueriesmaarXQueries.
InprincipedoetXqueryhetzelfdealsSQL,alleenisXqueryspeciaalontwikkeldomdeXMLstructuurtegebruiken.XQuerygebruiktXPathomterefererennaareenspecifiekdeelineenXML-document.XqueryisontwikkelddoorW3C.
SQLgebruiktdevolgordeSELECT,FROM,WHERE,...DevolgordevanXQueryisFor,Let,Where,OrderBy,Return.Dezecomponentenmoetennietallemaalgebruiktworden.Let,WhereenOrderbykunnenuitdeXquerywordengelaten..
Forwordtgebruiktomaanteduidenwatjeuitdedatabasewilthalenfor$nin//comm
Ditzalallerijen,metalleattributenselecterenindetabelcommLetgebruikjeomvariabelenaantemaken
let$communication:=//comm/@stateWherespreektuiteraardvoorzichOrderbyspreektuiteraardvoorzichReturnisdewaardediedezequeryzalteruggevennaardeinstantievanuitwaarhijisaangeroepen
Return$communication
6.3.2.1Postman
Omalleswatmakkelijkertelatenverlopen,werddequeryopgebouwdinPostman.PostmaniseenextensievanGoogleChromediejekandownloadenviadeWebstore.PostmanstaathettoeomHTTPrequeststedoenenmeteenoutputtekunnenbekijken.DaarditmetOrbeonnietzoevidentwas,washetdusbeteromdequeryinPostmanoptebouwenendezelatergewoontekopiërennaardeOrbeonpagina.
Postmanmoestweleenvormvanauthenticatiehebbenomdequerytemogenuitvoeren.JemoestduseentokenhebbenomtekunneninloggenviaScriptura,enzodedatabasetekunnenaanspreken.DezetokenmoetjedannaardeheadervandeGETrequestgekopiëerdworden,zodatScripturatoegangverleendtotdedatabase.
ViaScripturamoesterduseenclientvoorzienworden.Indeadminpaginavandescripturaserver,inhettabbladOAuth2.0werdeenclienttoegevoegd.HetIDvandezeclientenzijngegenereerdwachtwoordwerddusinpostmangestokenalscredentials.DaaropwerdereenPOSTgedaannaarlocalhost:13342/OAuth/access_token(localhost:13342ishetadreswaaropdeservervanScripturadraait).HieropverstuurdeScripturaeenantwoordmeteentokendiekongebruiktwordenomtoegangtekrijgentotdedatabase.
ProjectmetScripturaEngage
41
Omdequerytetesten,werdinpostmaneenPOSTverstuurdnaarlocalhost:13542/tracking/v1/concepts.Ditishetadreswaareenquerynaartoekonverstuurdworden,enindiendequerygeenerrorsgeeft,zalscripturadedatainXMLformaatteruggeven.OmtoegangtekrijgentotdezedatabasemoestdetokendieScripturagegevenhad,indeheadervandezePOSTaangebrachtworden.Hetprobleemwasdatdetokensmaar10minutengeldigwaren,enpertabbladdatdetokennodigheeft,detokenzalgekopiëerdmoestenwordenindeheadervandesbetreffendtabblad.
Hiervoorbestaateenwork-around.Postmanheefteen'functie'omenvironmentvariabelenaantemaken.Dezevariabelenkunnengebruiktwordenomoveralletabbladengedeeldevariabelentegebruiken.AlsScripturaeenantwoordgeeftopdePOSTdieweversturenvooreenaccesstoken,kanPostmanindebodyvanhetantwoord,zoekennaardezetoken,detokenineenvariabelekopiëren,endezevariabeleindeheadersvandePOSTgebruikendieverstuurdgaatwordenomdequerytetesten.
vardata=JSON.parse(responseBody);postman.setEnvironmentVariable("Access_Token",data.access_token);
Voordequerywordtopgebouwd,moetenereerstconceptenvoordetrackingwordeningesteld.Momenteeldraaitereen'clean'installationvanScriptura.Dezeinstallatiehadechterweinigconfiguratievoordetrackingvandedata,endaardetrackingvolledigeigentechnologievanInventiveDesignerswas,hadikhulpnodigvanBavoomdezetrackingconcepteninordetekrijgen(zonderdetrackingconceptenzougeenvandetabellenofattributenherkendwordenbijhetconverterenvandeXQuerynaarSQLquery).
for$nin//channelsorderby$n/@chanreturnelementresult{$n,count(//comm[$n/@com=@state])}
6.3.3Orbeon
BovenstaandkanudeXquerybekijkendiewerdgebruikt.AangeziendeXquerywerkte,washetdebedoelingomOrbeondezeXquerytelatenuitvoeren.Hetwaseenbeetjeontcijferenhoeditnugebeurt.Erzijnveelinstances,variabelenendoorverwijzingen
ProjectmetScripturaEngage
42
naaranderepagina's.Debedoelingwastebegrijpenhoededatanuvandedatabasewerdgehaald,endankonermanierwordengezochtdiehetopquasidezelfdemanierdoet,zonderiemandvanInventiveDesignerstemoetenraadplegen.
DeOrbeonpagina'szelfwerdengemaaktviade.xhtmlstandaard.Detagswarenduslichtverschillenddandievan.html,alsookdexformstagswerdenhierondersteund.DexformstagszorgdenervoordatdedatavanuitdedatabaseuitgelezenkonwordeninonzeOrbeonpagina.
6.3.3.1Instances
Eeninstanceiseensoortcontainerwaardatainkangeplaatstworden.Dezeinstanceswerdengebruiktinditprojectomdedatadieteruggestuurdwerdvandedatabase,optevangenenbeschikbaartemakenvoorderestvandepagina.
Momenteelzijner2instancesdiewordengebruikt.
i-request-partition-datai-partition-data
6.3.3.1.1i-request-partition-data
Dezeinstanceisdeinstancediedequeryverstuurtendedataopvangt.Dequeryzitineenenveloppeindepagina.
<xf:instanceid="i-request-partition-data"><envelope><query>for$nin//channelsorderby$n/@chanreturnelementresult{$n,count(//comm[$n/@com=@state])}</query><sessiontracking-session-alias="TrackingSession"concept-definition-alias="secc"></session><resultformat="sequence"></result></envelope></xf:instance>
Desessiontagszorgenervoordathetprojectdeconcept-definitionskent.Ditwilzeggendatdeattributenvandetabelkenbaarwordengemaaktvoordequery.
6.3.3.1.2i-partitiondata
ProjectmetScripturaEngage
43
<xf:instanceid="i-partition-results"><dummy></dummy></xf:instance>
Dezeinstancesdiendenerenkelenalleenvooromdedatate'stockeren'.DedummytagswarenerookenkelomdatOrbeoneeninstancenietkanmakenalsergeentagsindeinstancezitten.Dezeinstancewasspecifiekgemaaktomalledatavandepartitionchartbijtehouden.Erzatgeenanderedatain,behalvededatadiedequeryterugheeftgegevendiezonetisuitgevoerd.
Onderstaandkanueendeelvandeoutputziendedezequerygaf.
<result:element><result><channelschan="File"com="PDF"id="id-2"/>1600</result></result:element><result:element><result><channelschan="File"com="FileTesting"id="id-5"/>100</result></result:element><result:element><result><channelschan="File"com="PPT"id="id-10"/>2000</result></result:element>
6.3.3.2Partitionchart
Omdatermomenteelgeenanderemanierisomdedatateoutputten,wordtdedataineendivgezetwaarde'visibility'op'hidden'stond.Zokanviajavascript,dedivaangesprokenwordenmetdecorrecteid,enzodedatauitdedivhalen(ditisoverigensdemanierdiewordtvoorgestelddoorIventiveDesigners.DekansbestaatnatuurlijkdatjevanuitOrbeoneenvariabelekanmeesturennaareenjavascriptfile,maarditwasdebesteoplossing).
ProjectmetScripturaEngage
44
<divid="data-container"style="visibility:hidden"><xf:repeatnodeset="instance('i-partition-results')/result:element"><xf:outputvalue="concat('{','"','state','"',':','"',./result/channels/@com,'",','"','count','"',':','"',.,'",','"','chan','"',':','"',./result/channels/@chan,'"},')"></xf:output><br></br></xf:repeat></div>
DewerkingvanbovenstaandstukcodegelijktsterkopderepeatvanNodeJS.
Hetnodesetattribuutlinktderepeataandeinstancewaardedatainzit.IndeinstanceziteenXMLstructuurdiealledatabevat.VolgensdequerywordtelkeoutputwaardeineenresulttaggestokenDezetagkongebruiktwordenomtenodesetoptebinden.
De'value'vandeoutputzelfwordtzoopgebouwddatdeoutputdieOrbeonzalgevende(bijna)correcteoutputisdiegeconverteerdkanwordennaarJSON.DaarhetprojectnogaltijdgebruikmaaktvanJSONomdegrafiekentemaken,wasditdandebesteaanpak.
Dejavascriptfilesaansprekenwasnietgemakkelijk.Gewoonhetscripttoevoegenineentagbleekniettevoldoen.HetoriginelepadwaarOrbeongaatzoekennaarjavascriptfilesblijktnietde'home'directoryvandefiletezijnwaarhetscriptwordtaangeroepen.NickheeftgeholpenomOrbeonopdejuistelocatietegaanzoeken.Nickheeftopgezochthoeditexactwerkteenheeftookmijnscripturainstallatiein'development'gezet.Zowordenallejavascriptfilesnietin1filegegotenenishetmakkelijktedebuggenalsereenfoutzitinhetprogramma(Alseeninstallatiein'Product'staat,wordenallejavascriptfilesgemergednaar1file.Ditzorgtervoordatmaar1maaldefileendeheaderswordengedownload.Waardoordaterveelminderdataheenenweermoetwordengestuurd).
Probleem
Tijdenshetmakenvanditproject,crashtemijnmacwaarschijnlijkomdatScripturaEngage.Scripturaplots60gigaanvrijeruimtevolmetlograpportenschreef.Dithadalsgevolgdatalmijn'swap-memory'volzat.Mijnmacheeftnoggeprobeerdomdittereddendoorwatgeheugenvrijtemakenmaar5minutenlaterwasereenscreenfreezeeneencrash.
ProjectmetScripturaEngage
45
NahetbootenvandelaptopbleekdatScripturaalleverbindingenverbrokenhadmetdedatabase.ZoweldegebruikerominteloggenophetadmingedeeltevanscripturaalsmijnclientID'sdiedetokensbeschikbaarsteldenvoorPostmanblekennietmeerbeschikbaar.Deconnectie(zoalsingesteldindeconfigurationfiles)bleeknoginorde.TochkreegScripturageenverbindingmeer.DeoplossingwasomScripturatelatengelovendatdeinitiëleconfiguratienietwasgebeurd.Zomoestdeconfiguratievolledigopnieuwwordengedaanenkondedatabaseconnectiewordenhersteld.
6.3.3.2.1XBL
XBLofXenogamousBindingLanguageiseencomponentvanOrbeon,meteigenhandlers,CSS,enscripts.Ditiseencomponentdiekanopgeroepenwordeninorbeonpagina'somtelkensexacthetzelfdetedoenvoorverschillendepagina's.AlsdezeXBLwerkte,konInventiveDesignersdusinelkepaginadiedezecomponentnodigzouheeft,deXBLaanroepen,endanwordtvervolgensopdezepaginaeengrafiekgetekend.
Debestaande.xhtmlpaginamoetineenXBLfilewordenaangebracht.DezeXBLzorgdeereigenlijkvoordathetprojectherbruikbaarwordtvoormeerderepagina's.Quastructuurwasditookhelemaalanders,detagszijnandersopgebouwdendedatawordthiernietopgevraagd,maarwelmeegestuurtvanuitde.xhtmlpagina.
<idc:partitiondata="instance('i-partition-results')"id="partitionChart"data-width="500"data-height="400"style="height:auto;max-width:500px;margin:auto;"/>
DitstukcodeactiveertdeXBL-component.DezeXBLcomponentzorgterdusvoordatdecodenietalleenherbruikbaar,maarookopgesplitstenduidelijkwerd.Erisookteziendathet'data'attribuut,dedatameestuurtdieindeinstancezatnahetuitvoerenvandequery.
Omdatdevorigeoutputmethodenietwerkteindepagina,moestenweeennieuwemanierontwerpenvoorhetoutputtenvandezedata.
ProjectmetScripturaEngage
46
<xhtml:divstyle="display:none;"><xf:groupxxbl:scope="inner"><xhtml:divclass="data-width"><xf:outputref="{@data-width}"/></xhtml:div><xhtml:divclass="data-height"><xf:outputref="{@data-height}"/></xhtml:div><xxf:variablename="data"><xxf:sequenceselect="{@data}"xxbl:scope="outer"/></xxf:variable><xhtml:divid="partition-data-container"><xf:repeatref="data/result:element">{"state":<xf:outputvalue="concat('"',./result/channels/@com,'"')"></xf:output>,"count":<xf:outputvalue="concat('"',.,'"')"></xf:output>,"chan":<xf:outputvalue="concat('"',./result/channels/@chan,'"')"></xf:output>},</xf:repeat></xhtml:div></xf:group></xhtml:div>
(Hetdollartekenvandata/result:elementisweggelatenomdatandersdeopmaakvande.mdfileproblemenveroorzaakt)
Ditsegmentcodeontvangtdedatadiewetoegestuurdkregenvandexhtmlpagina.Hetmaakteeendivaanmetdeid'idpartition-data-container'enzalhierinvoorelkelementindeontvangendataeenrepeatdoen.DezerepeatwaszoopgebouwddathetJSONformaatnogaltijdwordtgehandhaafd.Hetisweliets'onordelijker'danvoordien.Inde.xhtmlhaddenwe1outputtagdieviade'concat'functie1stringkonmakenperelement.Nuiserdusperelement,3xdezetagomdatdevorigemanierhierdusnietmeerwerkte.
6.3.3.2.2Javascript
Nahetoutputtenvandedata,wordtnudejavascriptfilesaangeroependiededatagaangebruikenomdegrafiekentetekenen.
ProjectmetScripturaEngage
47
<xbl:scriptsrc="/xbl/idc/js/d3/d3.min.js"/><xbl:scriptsrc="/xbl/idc/js/partition.js"/><xbl:scriptsrc="/xbl/idc/js/prepareJS.js"/>
<xbl:handlers><xbl:handlerevent="makeChart"phase="target"><xxf:script>partitionChart();</xxf:script></xbl:handler></xbl:handlers><xbl:implementation><xf:actionev:event="xforms-ready"><xf:dispatchname="makeChart"target="idc-partition"/></xf:action></xbl:implementation>
Zoalsisweergegevenindecode,heeftdeXBLpaginaeenhandlerdiedecorrectejavascriptfunctiezalaanroepen.Dezefunctiewordtaangeroepenwanneerdepaginavolledigklaarismetalzijncomponententeladen(NadedatadusisdoorgestuurdnaardeXBLcomponent).
functionpartitionChart(){varvalues="["+String(document.getElementById('partitionChart≡partition-data-container').textContent).replace(//g,"").slice(0,-1)+"]";values=values.slice(0,-29)+"]";values=JSON.parse(values);console.log(values);makeCorrectFormat(values)}
Bovenstaandefunctiegaatdedatauitde.xhtmlpaginahalen.Momenteelisergeenanderemanieromvanuitde.xhtmlpaginadedatameetesturennaarhetjavascriptgedeeltevanhetproject.Omditdusweltekunnendoen,zetdeXBLcomponentdedataineendivmetdeIDpartition-data-container.Dezecontainerbevatdedatainverschillende'span'tagsdieevenredigzijnaanhoeveelresultatenmijnqueryteruggeeft.Zijnerbv.10resultaten,danzittener10overheersendespansindecontainer,met1spandiedetemplateweergeeftomdedatatetonen(de3outputtagsmetdetekstdiehierbijhoort).Deeerste'slice'diegebeurt,wasomdelaatstekommawegtewerken.De2deslicegebeurtomdespanmetbijhorendetemplatewegtewerken(onafhankelijkvandedatadiewordtmeegestuurd,isditaltijd29karakters).
ProjectmetScripturaEngage
48
OmdatdedatanuenkelJSONis,enniethetexacteformaatdatnodigisomdegrafiektelatenwerken,wordtdezeinhetcorrecte'formaat'gezet.DitformaatisduseenJSONformatdiegebruikmaaktvanchildrenenparents.
functionmakeCorrectFormat(results){varmasterArray=[];varchildrenArray=[];varcheckArray=[];varObject={"name":"","children":masterArray};varcount=0;varprevCount=0;for(vari=0;i<results.length;i++){if(checkArray.indexOf(results[i].chan)==-1){for(varj=0;j<results.length;j++){if(results[j].chan==results[i].chan){checkArray.push(results[j].state);childrenArray.push({"name":results[j].state,"size":results[j].count});count++;}}checkArray.push(results[i].chan);masterArray.push({"name":results[i].chan,"children":childrenArray.slice(prevCount,prevCount+count)});prevCount=count;}}Object.name="flare";Object.children=masterArray//console.log(Object);drawChart(Object);}
Dezefunctiecontroleertofdewaardenindearraydiewordenmeegestuurt,childrenofparentsmoetenzijn.Nahetmakenvandezecorrecteformatkandegrafiekgetekendworden.
ProjectmetScripturaEngage
49
Ditgebeurtdoorhetaanroepenvandeeerdergemaaktecodeinhetnode.jsproject.Aangezienhetformaatvandedatanuexacthetzelfdeis,moeterenkelgezorgdwordendatdenieuwedatawordtgelinktaandegrafiek,endezegrafiekisklaar.
6.3.3.3Timechart
DeintegratievandeeerstegrafiekinOrbeonmetsuccesafgerond.Nukonerdusbegonnenordeaande2degrafiek,enhiervoormoestdeSQLqueryterugomgevormdwordentoteenXQuery.DezeXQuerywasnietzomakkelijkoptebouwenomdatergegroepeerdwerdperpersubkanaalperdag.AangeziendegroupbycomponentvanXQuerynietondersteundwordt,zalerduseenandereoplossinggezochtmoetenworden.
SELECT__stateasstate,creation_mdateasdate,count(__state)FROMcomm,channelsWHEREchannels.com=comm.__stateGROUPBYstate,chan,dateORDERBYchan,date;
BovenstaandkanjedeSQLqueryziendiemoestomgevormdwordennaardeXQuery.
for&nindistinct-values(//comm/@creation-date)returnelementresult{elementdate{&n},for&sin//channels/@comreturnelementdata{&s,count(//comm[@creation-date=&n][@state=&s])}}
(Wegenopmaakproblemenhebikalledollartekensvervagendoor'&')
DezeXQueryiswatingewikkelderdandevorigeomdathijdedatagegroepeerdmoetteruggeven.Evenwatmeeruitlegrondde'return'lijn.
'returnelementresult'wiltzeggendatper'value'diedeXQueryterugkrijgt,hijeenresulttagzalmaken.Indezeresulttagzitteneenaantalvalues.Detag'date'zaldedatumweergevenopwelkedagerbepaaldesubkanalenzijngebruikt.
devolgendeforloopzorgtervoordatpersubkanaaleennieuwedatatagwordtgemaaktwaardenaamendehoeveelheidvanhetsubkanaalvanbovenvernoemdedatumzalwordengetoond.
ProjectmetScripturaEngage
50
<result:element><result>2016-03-01T00:00:00.000+01:00<datacom="Google+">543</data><datacom="PDF">168</data><datacom="Facebook">137</data><datacom="batch-print.delivery.waiting,no-archive,no-email,no-mypension">288</data><datacom="FileTesting">11</data><datacom="Twitter">104</data><datacom="batch-print.generation.started,no-archive-generation,no-email-generation,no-mypension-generation">20</data><datacom="Mailtesting">30</data><datacom="LinkedIn">52</data><datacom="PPT">207</data></result></result:element>
Bovenstaandis1tagvandeoutputdiedequerylevert.Jezietdusperdag(1maart)allesubkanalenenhetaantalkerendatzegebruiktzijnopdezedag.
<idc:time-chartdata="instance('i-time-results')"id="timeChart"data-width="500"data-height="400"style="height:auto;max-width:500px;margin:auto;"/>
BovenstaandkanjedecodezienwerdgebruiktomdeXBLfileaanteroepen.DezeXBLfilewordtopexactdezelfdewijzegedaanalsdepartitionchart.Jekanhierookziendatdedatauitdeinstance'i-time-results'wordtmeegegevenaandeXBL.
6.3.3.3.1XBL
DitzorgdeeruiteraardvoordatdemanierhoededatawordtuitgelezeninOrbeonookwateringewikkelderwordt.ErwerdineensgewerktvanuithetXBL-formaat.
ProjectmetScripturaEngage
51
<xhtml:divstyle="display:none"><xf:groupxxbl:scope="inner"><xhtml:divclass="data-width"><xf:outputref="{@data-width}"/></xhtml:div><xhtml:divclass="data-height"><xf:outputref="{@data-height}"/></xhtml:div><xxf:variablename="data"><xxf:sequenceselect="{@data}"xxbl:scope="outer"/></xxf:variable><xhtml:divid="time-data-container"><xf:repeatref="data/result:element/result"><xf:repeatnodeset="./data">{"state":<xf:outputvalue="concat('"',@com,'"')"></xf:output>,"date":<xf:outputvalue="concat('"',../date,'"')"></xf:output>,"count":<xf:outputvalue="concat('"',.,'"')"></xf:output>},</xf:repeat></xf:repeat></xhtml:div></xf:group></xhtml:div>
Omdatjeindequerymet2forloopszit,hebjeinOrbeonook2repeats.Jehebteenrepeatnodigvoorelkedatumdieindetabelaanwezigis,maarookeenrepeatvoorelksubkanaaldataanwezigisperdatum.Hetnodesetattribuutlinktderepeatdusaandeelementeninde2deforlus.Ditzorgtervoordatjeopeenmakkelijkemanieraandedatakuntdiehierinzit.'../date'gaatdan1levelnaarbovenomdedatumtekunnentonen.Alsjeditdancombineertkrijgjeeenoutputzoalsdieuithetprojectkomtdatmetnode.jswasgemaakt.
6.3.3.3.2Javascript
Nahetoutputtenvandedatawordtookhierdejavascriptfunctieaangeroepen.Ditgebeurt,uiteraard,opdezelfdemanieralsbijdepartitionchart.
ProjectmetScripturaEngage
52
<xbl:resources><xbl:stylesrc="/xbl/idc/css/d3-custom.css"/><xbl:stylesrc="/xbl/idc/css/chart.css"/></xbl:resources><!--==============================================--><!--handlers(create,update,...)--><!--==============================================-->
<xbl:handlers><xbl:handlerevent="makeChart"phase="target"><xxf:script>timeChart();</xxf:script></xbl:handler></xbl:handlers><xbl:implementation><xf:actionev:event="xforms-ready"><xf:dispatchname="makeChart"target="idc-time"/></xf:action></xbl:implementation>
functiontimeChart(){varvalues="["+String(document.getElementById('timeChart≡time-data-container').textContent).replace(//g,"").slice(0,-1)+"]";values=JSON.parse(values.slice(0,-29)+"]");drawMainChart(values);}
NadatdefunctiewerdaangeroepenwerdopdezelfdemanierdedatauitdeOrbeonpaginagehaald.Omdatdezedataindejuisteformattoekwam,moestenkelhetlaatstesegmentdata(dedatatemplatevanOrbeon)geslicedworden.Nadienkondeoriginelefunctiewordenaangeroepen.
Problemen
Bijhetgebruikenvandedata,kwamenereenpaarprobleempjesmee.Zoalsjekanzienoponderstaandescreenshot,ontbrakenereenpaarlijnenenkleurenindelegende.Hetzagernaaruitdatdezeproblemenenkelvoorkwamenbijstateswaarbijeenspatieinvoorkwam.Bijdeomvormingenenvergelijkingenvandenamenvoornaamgevingenenkleurtoewijzingenzalerweleenprobleembijgekomenzijn.
ProjectmetScripturaEngage
53
Nahetoplossenvanditprobleem,zagdegrafiekeralveelbeteruit.
Hetvolgendeprobleem,warendebugsdiealbestondenvoordeintegratienaarOrbeongebeurde.Erwasnualcssstylingvoordelijnen,maarbijhethertekenenvandehoofdgrafiek,verdwenendezekleurenweerenwerdendelijnenterugelksgekleurdin1kleur.
ProjectmetScripturaEngage
54
Ookkwamenervoordebrushwatproblemennaarboven.Erwasblijkbaarstylingindevorigehtmlpaginavoorziendiehiernognietaanwezigwas.Nadezeterugtoetevoegenwasookditopgelost.
Naeenontledingvanhetprojectmomenteel,kwamdeoorzaakvanhetprobleemaanthetlicht.Bijhetmakenvanhetpadvandelijnen,looptedecodedoordevolledigedataGroup.VoorelkelementindezedataGroup,voegded3eenelement'path'toeaanhetmomentelehoofdkanaal.Hetprobleemhierwasdaternietvoorelkelementeen'path"moestwordentoegevoegd,maarenkelvoorhetmeehetkanaalcorresponderendeelement.Ditzorgdeervoordatervoorelkkanaaleenelementwas.Delaatstaangemaakte'path'zorgdebijhetveranderenvanhetdomaindusvoordekleurvanallelijnen.Lietjeditelementverdwijnendoormiddelvandelegende,kregenallelijnendekleurvanhetvoorlaatsteaangemaakteelement,enz...
Ditwerdopgelostdoordemaniervanhettekenenvandelijnenoptelossen.
ProjectmetScripturaEngage
55
6.3.3.4Partitionchart
NahetvervolledigenvandeTijdsgrafiek,washetdebedoelingomhetprojectwatdynamischertemaken.Decodedieernuwas,waseropvoorzienomeenJSONstringteaanvaarden,zonderdathetuitmaaktehoeveelchildreneenparenthad,hoeveelniveau'sereventueelwaren.HetprobleemwasdanweldatmijnmaniervandeJSONmakenniettoereikendwas.Decodezoalszenubestondwasmaartoereikendvoor2niveau's.Mitseenaantalaanpassingenkonditopgelostworden.
6.3.3.4.1Database
ProjectmetScripturaEngage
56
Omditmogelijktemakenwerddedatabaseaangepast.Erwerdeentabeltoegevoegddieeenparent/childrelationomschreef.Hiergebruiktedetabeldeeerdergegevenid'svoorvandehoofd-ensubkanalen.
Nukunnenweindezetabelbekijken,welkekanalenwelkechildrenhebben.Zokanjedeid'sgebruikenzowelalsvoorparentsalsvoorchild.
6.3.3.4.1XQuery
NadeaanpassingvandedatabasevolgdeeennieuweXQuery.DezeXQuerymaaktegebruikvandenieuwetabelomdeparent/childrelationteomschrijven.
for$retin//relationsreturnelementrelation{$ret/@parent_id,$ret/@child_id,//channels[@id=$ret/@child_id]/@com,count(//comm[@state=collection()/channels[@id=$ret/@child_id]/@com])}
Voorelkelementinderelationstabel,werddeparentid,childid,naamvanhetchild+dehoeveelheiddatditchildvoorkomtuitdetabelgehaald.DitzorgdeervoordatjeinJavascriptderelatietussenparentenchildkanachterhalen.Indienditlukte,konjedeJSONstringopbouwen,endechildrentoevoegenaandecorrecteparent.
Stage
ProjectmetScripturaEngage
57
Helaasvondhierheteindevandestageplaats.Ikgazekernogproberenditlaatstedeelnogaftewerken.Demanierwaaropdegrafiekwordtopgebouwdisvoorzienopeenoneindigaantalchildren.VanafdatdemanierwaaropdeJSONstringwordtopgebouwdvollediginordeis,zoudegrafiekvolledigmoetenwerken.
ProjectmetScripturaEngage
58
ConclusieDeD3bibliotheekbiedtzoveelmogelijkhedendatheteindezekernognietinzichtis.HetiszekernietsimpelomzomaartebeginnenmetD3,maargelukkigisdecommunityzeergrootendedocumentatieheelduidelijk.
Deopdrachtzelfwasinmijnogennietzosimpel.Degrafiekenopzichwarenmakkelijktemakenmaardeextrafeaturesdieerbijkwamenkijken(denkaandebrushenfocusfunctionaliteitbijdelinechart)zijnnietzomaareventeimplementeren.OrbeonenXQuerywarenooknietsimpelomevenoptepikken.Ookwashetlastigomdatikeenweekaanhetwerkenwas,ennademeetingkwamerdevolgendestapaanbodwaarbijdandehelftvanhetwerkdatiknethadgedaaneigenlijknietechtnodigwas
OokhetlerenwerkenmetOrbeonendeeigentechnologievanInventiveDesignerswasnietsimpel.VoorbijnaelkprobleemmoestiknaarSteven,BavoofKurtomdatersomsbijnanietstevindenisophetinternetwaaromhetnunetfoutging.WaserietsdatwaargeensupportvoorwasvanuitInventiveDesigners,washeteentypfout,...Hetisnietleukvoormijomdingentevragenomdatjejedanafhankelijkvoeltvananderenenomdatikanderemensendanvanhunwerkmoethouden.
Erzitzekerpotentieelinhetproject,mitshetnogwatwordtopgevolgdenvervolledigddooriemandmetmeerkundeenkennis.
Deopdrachtwaszeerleerrijk,zowelopgebiedvanvisualisatiealsopgebiedvanJavaScript.Ikhebdankzijdezeopdrachtmijnkenniskunnenuitbreidenoverdatavisualisatie.
Puntjevankritiek
Hierendaarhebikredelijkwattijdverlorenomdatikelkeweeknieuweinformatiekreegomtrenthetproject.Alsikbvb.vanhetbeginwistdatikmetReSTmoestwerken(watikeigenlijkookalnietmoestdoen,omdatScripturaditzelfdoet)hadiknooitvoorPHPgekozen,omdatiknietweethoeReSThierwerkt.Insommigegevallenkonik25%vanmijnwerkvanvorigeweekweggooienomdathetnietzougewerkthebbenaandehandvandeinformatiedieikineennieuweweekkreeg.
Conclusie
59
UibreidingenDeenigeuitbreidingdieikernoginwilstekeniszoalseerdergezegd,denieuwemaniervanJSONstringopbouwen.Alsditwerkt,ishetprojectvolledigdynamischzolangdedatabasecorrecteoutputgeeft.
Uitbreidingen
60
AppendicesHierkanjedevolledigebestandendieikhebgemaakt.
Werkendeversies
query(FirstVersion).xhtml
<htmlxmlns="http://www.w3.org/1999/xhtml"xmlns:xhtml="http://www.w3.org/1999/xhtml"xmlns:ev="http://www.w3.org/2001/xml-events"xmlns:xf="http://www.w3.org/2002/xforms"xmlns:xxf="http://orbeon.org/oxf/xml/xforms"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:idc="http://www.inventivedesigners.com/xbl"xmlns:idf="http://uris.inventivedesigners.com/orbeon/functions"xmlns:fn="http://www.w3.org/2005/xpath-functions"xmlns:exf="http://www.exforms.org/exf/1-0"xmlns:result="http://uris.inventivedesigners.com/scriptura/tracking/result">
<xhtml:head><xhtml:title>Query</xhtml:title><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/BiLevelPartition.js"/><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/d3.js"/><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/centralJS.js"/><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/prepareJS.js"/><xf:modelid="m-query"><xf:instanceid="i-request-data"><envelope><query>for$nin//channelsorderby$n/@chanreturnelementresult{$n,count(//comm[$n/@com=@state])}</query><sessiontracking-session-alias="TrackingSession"concept-definition-alias="secc"></session><resultformat="sequence"></result></envelope></xf:instance><xf:instanceid="i-results"><dummy></dummy></xf:instance><xxf:variablename="query-chart-url">http://localhost:13542/tracking/v1/concepts
Appendices
61
</xxf:variable><xf:submissionid="s-get-data"ref="instance('i-request-data')"instance="i-results"replace="instance"resource="{$query-chart-url}"method="post">
</xf:submission><xf:actionev:event="xforms-model-construct-done"><xf:sendsubmission="s-get-data"></xf:send><xxf:script>chart();</xxf:script></xf:action></xf:model>
</xhtml:head><body>
<divclass="id-app-scroller"><divid="testtest"/><!--<fr:xforms-inspectorxmlns:fr="http://orbeon.org/oxf/xml/form-runner"/>--><divid="data-container"style="visibility:hidden">
<xf:repeatnodeset="instance('i-results')/result:element"><xf:outputvalue="concat('{','"','state','"',':','"',./result/channels/@com,'",','"','count','"',':','"',.,'",','"','chan','"',':','"',./result/channels/@chan,'"},')"></xf:output><br></br></xf:repeat>
<!--<xf:repeatnodeset="instance('i-results')/result:element"><xf:outputvalue="concat(./result/channels/@com,'#')"></xf:output><xf:outputvalue="concat(.,'#')"></xf:output><xf:outputvalue="concat(./result/channels/@chan,'#')"></xf:output><br></br></xf:repeat>--></div></div>
</body></html>
partition(FirstVersion).js
functionpartitionChart(){varvalues="["+String(document.getElementById('partitionChart≡partition-data-container').textContent).replace(//g,"").slice(0,-1)+"]";values=JSON.parse(values.slice(0,-29)+"]");console.log(values);makeCorrectFormat(values)
}functionmakeCorrectFormat(results)
Appendices
62
{varmasterArray=[];varchildrenArray=[];varcheckArray=[];varObject={"name":"","children":masterArray};varcount=0;varprevCount=0;for(vari=0;i<results.length;i++){if(checkArray.indexOf(results[i].chan)==-1){for(varj=0;j<results.length;j++){if(results[j].chan==results[i].chan){checkArray.push(results[j].state);childrenArray.push({"name":results[j].state,"size":results[j].count});count++;}}checkArray.push(results[i].chan);masterArray.push({"name":results[i].chan,"children":childrenArray.slice(prevCount,prevCount+count)});prevCount=count;}}Object.name="flare";Object.children=masterArray//console.log(Object);drawChart(Object);}functiondrawChart(gekregenArray){//vardata=$.ajax({type:"GET",url:"data",async:false}).responseJSON;
varradius=200/*Math.min(margin.top,margin.right,margin.bottom,margin.left)-10;*/varmargin={top:radius+10,right:radius+10,bottom:radius+10,left:radius+10}varhue=d3.scale.category10();
varluminance=d3.scale.sqrt().domain([0,1e6]).clamp(true).range([90,20]);varsvg=d3.select(".id-app-scroller").append("svg").attr("width",margin.left+margin.right).attr("height",margin.top+margin.bottom)
Appendices
63
.append("g").attr("transform","translate("+margin.left+","+margin.top+")");
varpartition=d3.layout.partition().sort(function(a,b){returnd3.ascending(a.name,b.name);}).size([2*Math.PI,radius]);
vararc=d3.svg.arc().startAngle(function(d){returnd.x;}).endAngle(function(d){returnd.x+d.dx;}).padAngle(.01).padRadius(radius/3).innerRadius(function(d){returnradius/3*d.depth;}).outerRadius(function(d){returnradius/3*(d.depth+1)-1;});
vartooltip=d3.select("body").append("div").style("position","absolute").style("font","10pxsans-serif").style("z-index","10").style("visibility","hidden").style("background-color","white").style("-webkit-border-radius","10px").style("border-radius","10px").style("padding","10px").style("opacity","0.9").style("box-shadow","4px4px10pxrbga(0,0,0,0.4)pointer-events:none");//d3.json("/data",function(error,root){root=gekregenArray;console.log(root);//Computetheinitiallayoutontheentiretreetosumsizes.//Alsocomputethefullnameandfillcolorforeachnode,//andstashthechildrensotheycanberestoredaswedescend.partition.value(function(d){returnd.size;}).nodes(root).forEach(function(d){d._children=d.children;d.sum=d.value;d.key=key(d);d.fill=fill(d);});
//Nowredefinethevaluefunctiontousethepreviously-computedsum.partition.children(function(d,depth){returndepth<2?d._children:null;}).value(function(d){returnd.sum;});
varcenter=svg.append("circle").attr("r",radius/3).on("click",zoomOut).style("fill","#FFFFFF")
Appendices
64
center.append("title").text("zoomout");
varpath=svg.selectAll("path").data(partition.nodes(root).slice(1)).enter().append("path").attr("d",arc).style("fill",function(d,i){varcolorI=0;for(vari=0;i<kleurenArray.length;i++){if(kleurenArray[i].State.toString().replace(//g,"").toLowerCase()==d.name.toString().replace(//g,"").toLowerCase()){//console.log(d.name.toString().toLowerCase());returnlocalColorScale[kleurenArray[i].color];}}
//returnd.fill;}).each(function(d){this._current=updateArc(d);}).on("click",zoomIn).on("mouseover",function(d){returntooltip.style("visibility","visible");}).on("mousemove",function(d,i){returntooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").text(d.name+":"+d.value);}).on("mouseout",function(d){returntooltip.style("visibility","hidden");});
functionzoomIn(p){if(p.depth>1)p=p.parent;if(!p.children)return;zoom(p,p);}
functionzoomOut(p){if(!p.parent)return;zoom(p.parent,p);}
//Zoomtothespecifiednewroot.functionzoom(root,p){if(document.documentElement.__transition__)return;
//Rescaleoutsideanglestomatchthenewlayout.varenterArc,exitArc,outsideAngle=d3.scale.linear().domain([0,2*Math.PI]);
Appendices
65
functioninsideArc(d){returnp.key>d.key?{depth:d.depth-1,x:0,dx:0}:p.key<d.key?{depth:d.depth-1,x:2*Math.PI,dx:0}:{depth:0,x:0,dx:2*Math.PI};}
functionoutsideArc(d){return{depth:d.depth+1,x:outsideAngle(d.x),dx:outsideAngle(d.x+d.dx)-outsideAngle(d.x)};}
center.datum(root);
//Whenzoomingin,arcsenterfromtheoutsideandexittotheinside.//Enteringoutsidearcsstartfromtheoldlayout.if(root===p)enterArc=outsideArc,exitArc=insideArc,outsideAngle.range([p.x,p.x+p.dx]);path=path.data(partition.nodes(root).slice(1),function(d){returnd.key;});//Whenzoomingout,arcsenterfromtheinsideandexittotheoutside.//Exitingoutsidearcstransitiontothenewlayout.if(root!==p)enterArc=insideArc,exitArc=outsideArc,outsideAngle.range([p.x,p.x+p.dx]);
d3.transition().duration(d3.event.altKey?7500:750).each(function(){path.exit().transition().style("fill-opacity",function(d){returnd.depth===1+(root===p)?1:0;}).attrTween("d",function(d){returnarcTween.call(this,exitArc(d));}).remove();
path.enter().append("path").style("fill-opacity",function(d){returnd.depth===2-(root===p)?1:0;}).style("fill",function(d){varcolorI=0;for(vari=0;i<kleurenArray.length;i++){if(kleurenArray[i].State.toString().replace(//g,"").toLowerCase()==d.name.toString().replace(//g,"").toLowerCase()){
returnlocalColorScale[kleurenArray[i].color];}}}).on("click",zoomIn).each(function(d){this._current=enterArc(d);}).on("mouseover",function(d){returntooltip.style("visibility","visible");}).on("mousemove",function(d,i){returntooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").text(d.name+":"+d.value);}).on("mouseout",function(d){returntooltip.style("visibility","hidden");});
Appendices
66
path.transition().style("fill-opacity",1).attrTween("d",function(d){returnarcTween.call(this,updateArc(d));});});};
functionkey(d){vark=[],p=d;while(p.depth)k.push(p.name),p=p.parent;returnk.reverse().join(".");}
functionfill(d){varp=d;while(p.depth>1)p=p.parent;varc=d3.lab(hue(p.name));c.l=luminance(d.sum);returnc;}
functionarcTween(b){vari=d3.interpolate(this._current,b);this._current=i(0);returnfunction(t){returnarc(i(t));};}
functionupdateArc(d){return{depth:d.depth,x:d.x,dx:d.dx};}
d3.select(self.frameElement).style("height",margin.top+margin.bottom+"px");};
partition(FirstVersion).xbl
<xbl:xblxmlns:xhtml="http://www.w3.org/1999/xhtml"xmlns:xf="http://www.w3.org/2002/xforms"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:ev="http://www.w3.org/2001/xml-events"xmlns:xxf="http://orbeon.org/oxf/xml/xforms"xmlns:fr="http://orbeon.org/oxf/xml/form-runner"xmlns:xbl="http://www.w3.org/ns/xbl"xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"xmlns:sld="http://www.inventivedesigners.com/livedocs"xmlns:idc="http://www.inventivedesigners.com/xbl"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:oxf="http://www.orbeon.com/oxf/processors"
Appendices
67
xmlns:result="http://uris.inventivedesigners.com/scriptura/tracking/result">
<!--=================================================================================--><!--XBLfiletocreateachartwithd3library--><!--=================================================================================-->
<xbl:scriptsrc="/xbl/idc/js/d3/d3.min.js"/><xbl:scriptsrc="/xbl/idc/js/partition.js"/><xbl:scriptsrc="/xbl/idc/js/prepareJS.js"/>
<xbl:bindingelement="idc|partition"id="idc-partition"xxf:external-events="makeChart">
<xbl:resources><xbl:stylesrc="/xbl/idc/css/d3-custom.css"/></xbl:resources>
<!--==============================================--><!--handlers(create,update,...)--><!--==============================================-->
<xbl:handlers><xbl:handlerevent="makeChart"phase="target"><xxf:script>partitionChart();</xxf:script></xbl:handler></xbl:handlers><xbl:implementation><xf:actionev:event="xforms-ready"><xf:dispatchname="makeChart"target="idc-partition"/></xf:action></xbl:implementation>
<!--==============================================--><!--thegraph--><!--==============================================-->
<xbl:templatexxbl:transform="oxf:xslt"><xsl:transformversion="2.0"><xsl:templatematch="/*"><xhtml:divstyle="display:none;"><xf:groupxxbl:scope="inner"><xhtml:divclass="data-width"><xf:outputref="{@data-width}"/></xhtml:div><xhtml:divclass="data-height"><xf:outputref="{@data-height}"/></xhtml:div><xxf:variablename="data">
Appendices
68
<xxf:sequenceselect="{@data}"xxbl:scope="outer"/></xxf:variable>
<xhtml:divid="partition-data-container"><xf:repeatref="$data/result:element">{"state":<xf:outputvalue="concat('"',./result/channels/@com,'"')"></xf:output>,"count":<xf:outputvalue="concat('"',.,'"')"></xf:output>,"chan":<xf:outputvalue="concat('"',./result/channels/@chan,'"')"></xf:output>},</xf:repeat></xhtml:div></xf:group></xhtml:div></xsl:template></xsl:transform></xbl:template>
</xbl:binding></xbl:xbl>
timechart.js
varx,xAxis;functiontimeChart(){varvalues="["+String(document.getElementById('timeChart≡time-data-container').textContent).replace(//g,"").slice(0,-1)+"]";values=JSON.parse(values.slice(0,-29)+"]");console.log(values);drawMainChart(values);}functiondrawMainChart(values){varmarginFocus={top:20,right:130,bottom:250,left:40},marginContext={top:430,right:30,bottom:170,left:40},width=960,chartWidth=width-marginFocus.right;heightFocus=650-marginFocus.top-marginFocus.bottom,heightContext=650-marginContext.top-marginContext.bottom;
varparseDate=d3.time.format("%Y%M%D").parse;
//Focusisdehoofdgrafiek,contextisdekleinegrafiekvarxFocus=d3.time.scale().range([0,chartWidth]),xContext=d3.time.scale().range([0,chartWidth]),
Appendices
69
yFocus=d3.scale.linear().range([heightFocus,0]),yContext=d3.scale.linear().range([heightContext,0]);
vardata=values;findMinMax(data);//console.log(data);data.forEach(function(d){d.date=Date.parse(d.date);xFocus.domain(d3.extent(data,function(d){returnd.date;}));});
vartooltip=d3.select("body").append("div").style("position","absolute").style("font","20pxsans-serif").style("z-index","10").style("visibility","hidden").style("color","black").style("background-color","white").style("-webkit-border-radius","10px").style("border-radius","10px").style("padding","5px").style("opacity","0.9").style("box-shadow","4px4px10pxrbga(0,0,0,0.4)pointer-events:none");
xContext.domain(xFocus.domain());yFocus.domain([min,max*1.1]);yContext.domain([min,max]);
varyAxis=d3.svg.axis().scale(yFocus).orient("left")
xAxisFocus=d3.svg.axis().scale(xFocus).orient("bottom").ticks(8),xAxisContext=d3.svg.axis().scale(xContext).orient("bottom");
varline=d3.svg.line().y(function(d){returnyFocus(d.count)}).x(function(d,i){returnxFocus(d.date)}).interpolate("cardinal")
varline2=d3.svg.line().y(function(d){returnyContext(d.count)}).x(function(d,i){returnxContext(d.date)})
Appendices
70
.interpolate("cardinal")
varsvg=d3.select(".id-app-scroller").append("svg").attr("width",width).attr("height",heightFocus+marginFocus.top+marginFocus.bottom).append("g")
svg.append("clipPath").attr("id","clip").append("rect").attr("width",chartWidth).attr("height",heightFocus)
varbrush=d3.svg.brush().x(xContext).on("brush",brushed);varContext=svg.append("g").attr("class","context").attr("transform","translate("+marginContext.left+","+marginContext.top+")");
varFocus=svg.append("g").attr("class","Focus").attr("transform","translate("+marginFocus.left+","+marginFocus.top+")");
Context.append("a").attr("class","xaxis").attr("transform","translate(0,"+heightContext+")").call(xAxisContext);
Context.append("a").attr("class","xbrush").call(brush).selectAll("rect").attr("y",-6)//.attr("x",-50).attr("height",heightContext+7);
Focus.append("g").attr("class","yaxis").call(yAxis).append("text").attr("transform","rotate(-90)").attr("y",6).attr("dy",".71em").style("text-anchor","end").text("Values");
Appendices
71
Focus.append("g").attr("class","xaxis").attr("transform","translate(0,"+(heightFocus)+")").call(xAxisFocus);
varLegend=svg.append("g").attr("class","legend")
functionbrushed(){
xFocus.domain(brush.empty()?xContext.domain():brush.extent());svg.selectAll("circle").remove();Focus.selectAll("path.lijn").attr("d",function(d){returnline(d.values);;});//Focus.selectAll("circle.cirkel").attr("d",function(d){returnline(d.values);;});Focus.select(".x.axis").call(xAxisFocus);}
vardataGroup=d3.nest().key(function(d){returnd.state;}).entries(data);
varchannel=Focus.selectAll(".channel").data(dataGroup).enter().append("g").attr("class","channel")//Allnonnormalcharactersneedtobegone.Otherwiseerrorswilloccurandlineswillnotvanish.attr("id",function(d,i){returndataGroup[i].key.replace(/\W+/g,"").replace(//g,"").toLowerCase()}).append('svg:path').attr("class","lijn").attr("clip-path","url(#clip)").attr("d",function(d,i){returnline(d.values);})/*line(dataGroup[i].values))*/
varchannel2=Context.selectAll(".channel").data(dataGroup).enter().append("g").attr("class","channel")//Allnonnormalcharactersneedtobegone.Otherwiseerrorswilloccurandlineswillnotvanish.attr("id",function(d,i){returndataGroup[i].key.replace(/\W+/g,"").replace(//g,"").toLowerCase()}).append('svg:path').attr("class","lijn2").attr("d",function(d,i){returnline2(d.values);})/*line(dataGroup[i].values))*/
Focus.selectAll("dot")
Appendices
72
.data(data).enter().append("circle").attr("class","cirkel").attr('id',function(d){returnd.state.replace(/\W+/g,"").replace(//g,"").toLowerCase()}).attr("r",2.5).attr("cx",function(d){returnxFocus(d.date);}).attr("cy",function(d){returnyFocus(d.count);}).on("mouseover",function(d){returntooltip.style("visibility","visible");}).on("mousemove",function(d,i){returntooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").text(d.state+":"+d.count);}).on("mouseout",function(d){returntooltip.style("visibility","hidden");});
legend();
functionlegend(){dataGroup.forEach(function(d,i){//AddtheLegendverticallynexttochartvarlegendSpace=heightFocus/dataGroup.length;varkey=d.key;Legend.append("text").attr("x",width-marginFocus.right+marginFocus.left)//spacelegend.attr("y",legendSpace/1.5+i*legendSpace/1.5).attr("class","item")//stylethelegend.style("font","15pxsans-serif").style("fill",function(){//Addthecoloursdynamicallyfor(varr=0;r<kleurenArray.length;r++){if(kleurenArray[r].State.toString().replace(//g,"").toLowerCase()==key.toString().toLowerCase()){returnlocalColorScale[kleurenArray[r].color];}}}).on("click",function(){//Determineifcurrentlineisvisiblevaractive=d.active?false:true,newOpacity=active?0:1;d3.selectAll("#"+d.key.replace(/\W+/g,"").replace(//g,"").toLowerCase()).style("visibility",function(){if(newOpacity==false){return'hidden';}else{return'visible';}});
//Updatewhetherornottheelementsareactived.active=active;}).text(d.key.substring(0,12));})}
Appendices
73
}
functionfindMinMax(data){min=parseInt(data[0].count);max=parseInt(data[0].count);for(vari=0;i<data.length;i++){if(parseInt(data[i].count)<min){min=data[i].count;}elseif(parseInt(data[i].count)>max){max=data[i].count;}}}
time-chart.xbl
<xbl:xblxmlns:xhtml="http://www.w3.org/1999/xhtml"xmlns:xf="http://www.w3.org/2002/xforms"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:ev="http://www.w3.org/2001/xml-events"xmlns:xxf="http://orbeon.org/oxf/xml/xforms"xmlns:fr="http://orbeon.org/oxf/xml/form-runner"xmlns:xbl="http://www.w3.org/ns/xbl"xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"xmlns:sld="http://www.inventivedesigners.com/livedocs"xmlns:idc="http://www.inventivedesigners.com/xbl"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:oxf="http://www.orbeon.com/oxf/processors"xmlns:result="http://uris.inventivedesigners.com/scriptura/tracking/result">
<!--=================================================================================--><!--XBLfiletocreateachartwithd3library--><!--=================================================================================-->
<xbl:scriptsrc="/xbl/idc/js/d3/d3.min.js"/><xbl:scriptsrc="/xbl/idc/js/time-chart.js"/><xbl:scriptsrc="/xbl/idc/js/prepareJS.js"/><xhtml:linkrel="stylesheet"href="/apps/sms/css/chart.css"type="text/css"media="all"/>
<xbl:bindingelement="idc|time-chart"id="idc-time"xxf:external-events="makeChart"><xbl:resources><xbl:stylesrc="/xbl/idc/css/d3-custom.css"/>
Appendices
74
<xbl:stylesrc="/xbl/idc/css/chart.css"/></xbl:resources><!--==============================================--><!--handlers(create,update,...)--><!--==============================================-->
<xbl:handlers><xbl:handlerevent="makeChart"phase="target"><xxf:script>timeChart();</xxf:script></xbl:handler></xbl:handlers><xbl:implementation><xf:actionev:event="xforms-ready"><xf:dispatchname="makeChart"target="idc-time"/></xf:action></xbl:implementation>
<!--==============================================--><!--thegraph--><!--==============================================-->
<xbl:templatexxbl:transform="oxf:xslt"><xsl:transformversion="2.0"><xsl:templatematch="/*"><xhtml:divstyle="display:none"><xf:groupxxbl:scope="inner"><xhtml:divclass="data-width"><xf:outputref="{@data-width}"/></xhtml:div><xhtml:divclass="data-height"><xf:outputref="{@data-height}"/></xhtml:div><xxf:variablename="data"><xxf:sequenceselect="{@data}"xxbl:scope="outer"/></xxf:variable><xhtml:divid="time-data-container"><xf:repeatref="$data/result:element/result"><xf:repeatnodeset="./data">{"state":<xf:outputvalue="concat('"',@com,'"')"></xf:output>,"date":<xf:outputvalue="concat('"',../date,'"')"></xf:output>,"count":<xf:outputvalue="concat('"',.,'"')"></xf:output>},</xf:repeat></xf:repeat></xhtml:div></xf:group>
Appendices
75
</xhtml:div>
</xsl:template></xsl:transform></xbl:template>
</xbl:binding></xbl:xbl>
WorkInProgress
Aandezedocumentenwordtvoordelaatsteaanpassingnogaangesleuteld,maarikzetzeeralwelbij.
query(WorkInProgress).xhtml
<htmlxmlns="http://www.w3.org/1999/xhtml"xmlns:xhtml="http://www.w3.org/1999/xhtml"xmlns:ev="http://www.w3.org/2001/xml-events"xmlns:xf="http://www.w3.org/2002/xforms"xmlns:xxf="http://orbeon.org/oxf/xml/xforms"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:idc="http://www.inventivedesigners.com/xbl"xmlns:idf="http://uris.inventivedesigners.com/orbeon/functions"xmlns:fn="http://www.w3.org/2005/xpath-functions"xmlns:exf="http://www.exforms.org/exf/1-0"xmlns:result="http://uris.inventivedesigners.com/scriptura/tracking/result">
<xhtml:head><styletype="text/css">
#facebook{stroke:#6baed6;}#mailtesting{stroke:#e6550d;}#twitter{stroke:#9ecae1;}#linkedin{stroke:#c6dbef;}
Appendices
76
#batchprintdeliverywaitingnoarchivenoemailnomypension{stroke:#c6220d;}#batchprintgenerationstartednoarchivegenerationnoemailgenerationnomypensiongeneration{stroke:#cd8d3c;}#pdf{stroke:#22AA22;}#filetesting{stroke:#00DD00;}#google{stroke:#3182bd;}#ppt{stroke:#55FF55;}body{font:10pxsans-serif;}
.axispath,
.axisline{fill:none;stroke:#000;shape-rendering:crispEdges;}
.line{fill:none;stroke:steelblue;stroke-width:1.5px;}.grid-background{fill:#ddd;}
.gridline,
.gridpath{fill:none;stroke:#fff;shape-rendering:crispEdges;}
Appendices
77
.grid.minor.tickline{stroke-opacity:.5;}
.brush.extent{fill:#BBFFBB;stroke:#000;fill-opacity:.5;shape-rendering:crispEdges;}.area{fill:steelblue;clip-path:url(#clip);}</style><xhtml:title>Query</xhtml:title><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/d3.js"/><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/centralJS.js"/><xhtml:scripttype="text/javascript"src="/apps/sms/javascripts/prepareJS.js"/><xf:modelid="m-query"><xf:instanceid="i-request-partition-data"><envelope><query>for$retin//relationsreturnelementrelation{$ret/@parent_id,$ret/@child_id,//channels[@id=$ret/@child_id]/@com,count(//comm[@state=collection()/channels[@id=$ret/@child_id]/@com])}</query><sessiontracking-session-alias="TrackingSession"concept-definition-alias="secc"></session><resultformat="sequence"></result></envelope></xf:instance><xf:instanceid="i-request-time-data"><envelope><query>for$nindistinct-values(//comm/@creation-date)returnelementresult{elementdate{$n},for$sin//channels/@comreturnelementdata{$s,count(//comm[@creation-date=$n][@state=$s])}}</query><sessiontracking-session-alias="TrackingSession"concept-definition-alias="secc"></session><resultformat="sequence"></result>
Appendices
78
</envelope></xf:instance><xf:instanceid="i-partition-results"><dummy></dummy></xf:instance><xf:instanceid="i-time-results"><dummy></dummy></xf:instance><xxf:variablename="query-chart-url">http://localhost:13542/tracking/v1/concepts</xxf:variable><xf:submissionid="s-get-partition-data"ref="instance('i-request-partition-data')"instance="i-partition-results"replace="instance"resource="{$query-chart-url}"method="post">
</xf:submission><xf:submissionid="s-get-time-data"ref="instance('i-request-time-data')"instance="i-time-results"replace="instance"resource="{$query-chart-url}"method="post">
</xf:submission><xf:actionev:event="xforms-model-construct-done"><xf:sendsubmission="s-get-partition-data"></xf:send><xxf:script>partitionChart()</xxf:script><xf:sendsubmission="s-get-time-data"></xf:send><!--<xxf:script>timeChart()</xxf:script>--></xf:action></xf:model>
</xhtml:head><body><divclass="id-app-scroller"><idc:partitiondata="instance('i-partition-results')"id="partitionChart"data-width="500"data-height="400"style="height:auto;max-width:500px;margin:auto;"/><!--<idc:time-chartdata="instance('i-time-results')"id="timeChart"data-width="500"data-height="400"style="height:auto;max-width:500px;margin:auto;"/>--><!--<fr:xforms-inspectorxmlns:fr="http://orbeon.org/oxf/xml/form-runner"/>--></div></body></html>
Partition(WorkInProgress).js
functionpartitionChart(){varvalues="["+String(document.getElementById('partitionChart≡partition-data-container').textContent).replace(//g,"").slice(0,-1)+"]";//console.log(values.slice(0,-46)+"]");values=JSON.parse(values.slice(0,-46)+"]");//console.log(values);makeCorrectFormat(values)
Appendices
79
}functionmakeCorrectFormat(results){console.log(results);for(vari=0;i<results.length;i++){for(varj=0;j<results.length;j++){if(results[i].parent_id==results[j].child_id){console.log("Parent:"+results[j].state+"Child:"+results[i].state);}}}}
functiondrawChart(gekregenArray){//vardata=$.ajax({type:"GET",url:"data",async:false}).responseJSON;
varradius=200/*Math.min(margin.top,margin.right,margin.bottom,margin.left)-10;*/varmargin={top:radius+10,right:radius+10,bottom:radius+10,left:radius+10}varhue=d3.scale.category10();
varluminance=d3.scale.sqrt().domain([0,1e6]).clamp(true).range([90,20]);varsvg=d3.select(".id-app-scroller").append("svg").attr("width",margin.left+margin.right).attr("height",margin.top+margin.bottom).append("g").attr("transform","translate("+margin.left+","+margin.top+")");
varpartition=d3.layout.partition().sort(function(a,b){returnd3.ascending(a.name,b.name);}).size([2*Math.PI,radius]);
vararc=d3.svg.arc().startAngle(function(d){returnd.x;}).endAngle(function(d){returnd.x+d.dx;}).padAngle(.01).padRadius(radius/3).innerRadius(function(d){returnradius/3*d.depth;}).outerRadius(function(d){returnradius/3*(d.depth+1)-1;});
vartooltip=d3.select("body").append("div").style("position","absolute").style("font","10pxsans-serif").style("z-index","10").style("visibility","hidden").style("background-color","white")
Appendices
80
.style("-webkit-border-radius","10px").style("border-radius","10px").style("padding","10px").style("opacity","0.9").style("box-shadow","4px4px10pxrbga(0,0,0,0.4)pointer-events:none");//d3.json("/data",function(error,root){root=gekregenArray;console.log(root);//Computetheinitiallayoutontheentiretreetosumsizes.//Alsocomputethefullnameandfillcolorforeachnode,//andstashthechildrensotheycanberestoredaswedescend.partition.value(function(d){returnd.size;}).nodes(root).forEach(function(d){d._children=d.children;d.sum=d.value;d.key=key(d);d.fill=fill(d);});
//Nowredefinethevaluefunctiontousethepreviously-computedsum.partition.children(function(d,depth){returndepth<2?d._children:null;}).value(function(d){returnd.sum;});
varcenter=svg.append("circle").attr("r",radius/3).on("click",zoomOut).style("fill","#FFFFFF")
center.append("title").text("zoomout");
varpath=svg.selectAll("path").data(partition.nodes(root).slice(1)).enter().append("path").attr("d",arc).style("fill",function(d,i){varcolorI=0;for(vari=0;i<kleurenArray.length;i++){if(kleurenArray[i].State.toString().replace(//g,"").toLowerCase()==d.name.toString().replace(//g,"").toLowerCase()){//console.log(d.name.toString().toLowerCase());returnlocalColorScale[kleurenArray[i].color];}}
Appendices
81
//returnd.fill;}).each(function(d){this._current=updateArc(d);}).on("click",zoomIn).on("mouseover",function(d){returntooltip.style("visibility","visible");}).on("mousemove",function(d,i){returntooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").text(d.name+":"+d.value);}).on("mouseout",function(d){returntooltip.style("visibility","hidden");});
functionzoomIn(p){if(p.depth>1)p=p.parent;if(!p.children)return;zoom(p,p);}
functionzoomOut(p){if(!p.parent)return;zoom(p.parent,p);}
//Zoomtothespecifiednewroot.functionzoom(root,p){if(document.documentElement.__transition__)return;
//Rescaleoutsideanglestomatchthenewlayout.varenterArc,exitArc,outsideAngle=d3.scale.linear().domain([0,2*Math.PI]);
functioninsideArc(d){returnp.key>d.key?{depth:d.depth-1,x:0,dx:0}:p.key<d.key?{depth:d.depth-1,x:2*Math.PI,dx:0}:{depth:0,x:0,dx:2*Math.PI};}
functionoutsideArc(d){return{depth:d.depth+1,x:outsideAngle(d.x),dx:outsideAngle(d.x+d.dx)-outsideAngle(d.x)};}
center.datum(root);
//Whenzoomingin,arcsenterfromtheoutsideandexittotheinside.//Enteringoutsidearcsstartfromtheoldlayout.if(root===p)enterArc=outsideArc,exitArc=insideArc,outsideAngle.range([p.x,p.x+p.dx]);path=path.data(partition.nodes(root).slice(1),function(d){returnd.key;});//Whenzoomingout,arcsenterfromtheinsideandexittotheoutside.//Exitingoutsidearcstransitiontothenewlayout.
Appendices
82
if(root!==p)enterArc=insideArc,exitArc=outsideArc,outsideAngle.range([p.x,p.x+p.dx]);
d3.transition().duration(d3.event.altKey?7500:750).each(function(){path.exit().transition().style("fill-opacity",function(d){returnd.depth===1+(root===p)?1:0;}).attrTween("d",function(d){returnarcTween.call(this,exitArc(d));}).remove();
path.enter().append("path").style("fill-opacity",function(d){returnd.depth===2-(root===p)?1:0;}).style("fill",function(d){varcolorI=0;for(vari=0;i<kleurenArray.length;i++){if(kleurenArray[i].State.toString().replace(//g,"").toLowerCase()==d.name.toString().replace(//g,"").toLowerCase()){
returnlocalColorScale[kleurenArray[i].color];}}}).on("click",zoomIn).each(function(d){this._current=enterArc(d);}).on("mouseover",function(d){returntooltip.style("visibility","visible");}).on("mousemove",function(d,i){returntooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").text(d.name+":"+d.value);}).on("mouseout",function(d){returntooltip.style("visibility","hidden");});
path.transition().style("fill-opacity",1).attrTween("d",function(d){returnarcTween.call(this,updateArc(d));});});};
functionkey(d){vark=[],p=d;while(p.depth)k.push(p.name),p=p.parent;returnk.reverse().join(".");}
functionfill(d){varp=d;while(p.depth>1)p=p.parent;varc=d3.lab(hue(p.name));c.l=luminance(d.sum);returnc;}
functionarcTween(b){
Appendices
83
vari=d3.interpolate(this._current,b);this._current=i(0);returnfunction(t){returnarc(i(t));};}
functionupdateArc(d){return{depth:d.depth,x:d.x,dx:d.dx};}
d3.select(self.frameElement).style("height",margin.top+margin.bottom+"px");};
partition(WorkInProgress).xbl
<xbl:xblxmlns:xhtml="http://www.w3.org/1999/xhtml"xmlns:xf="http://www.w3.org/2002/xforms"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:ev="http://www.w3.org/2001/xml-events"xmlns:xxf="http://orbeon.org/oxf/xml/xforms"xmlns:fr="http://orbeon.org/oxf/xml/form-runner"xmlns:xbl="http://www.w3.org/ns/xbl"xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"xmlns:sld="http://www.inventivedesigners.com/livedocs"xmlns:idc="http://www.inventivedesigners.com/xbl"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:oxf="http://www.orbeon.com/oxf/processors"xmlns:result="http://uris.inventivedesigners.com/scriptura/tracking/result">
<!--=================================================================================--><!--XBLfiletocreateachartwithd3library--><!--=================================================================================-->
<xbl:scriptsrc="/xbl/idc/js/d3/d3.min.js"/><xbl:scriptsrc="/xbl/idc/js/partition.js"/><xbl:scriptsrc="/xbl/idc/js/prepareJS.js"/>
<xbl:bindingelement="idc|partition"id="idc-partition"xxf:external-events="makeChart">
<xbl:resources><xbl:stylesrc="/xbl/idc/css/d3-custom.css"/></xbl:resources>
<!--==============================================--><!--handlers(create,update,...)-->
Appendices
84
<!--==============================================-->
<xbl:handlers><xbl:handlerevent="makeChart"phase="target"><xxf:script>partitionChart();</xxf:script></xbl:handler></xbl:handlers><xbl:implementation><xf:actionev:event="xforms-ready"><xf:dispatchname="makeChart"target="idc-partition"/></xf:action></xbl:implementation>
<!--==============================================--><!--thegraph--><!--==============================================-->
<xbl:templatexxbl:transform="oxf:xslt"><xsl:transformversion="2.0"><xsl:templatematch="/*"><xhtml:divstyle=""><xf:groupxxbl:scope="inner"><xhtml:divclass="data-width"><xf:outputref="{@data-width}"/></xhtml:div><xhtml:divclass="data-height"><xf:outputref="{@data-height}"/></xhtml:div><xxf:variablename="data"><xxf:sequenceselect="{@data}"xxbl:scope="outer"/></xxf:variable>
<xhtml:divid="partition-data-container"><xf:repeatref="$data/result:element">{"state":<xf:outputvalue="concat('"',./relation/@com,'"')"></xf:output>,"count":<xf:outputvalue="concat('"',.,'"')"></xf:output>,"parent_id":<xf:outputvalue="concat('"',./relation/@parent_id,'"')"></xf:output>,"child_id":<xf:outputvalue="concat('"',./relation/@child_id,'"')"></xf:output>},</xf:repeat></xhtml:div></xf:group></xhtml:div></xsl:template></xsl:transform>
Appendices
85
</xbl:template>
</xbl:binding></xbl:xbl>
Appendices
86
Glossary
XSL
XSLstaatvoorExtensibleStylesheetLanguage.DiteeneenformaattypewaarinjekanbeschrijvenhoeeenXMLdocumentgeformatteerdmoetenworden.
EigenlijkkanjezeggendatXSLdoetmeteenXMLbestaandwatCSSmeteenHTMLbestanddoet.HetgaatdestylingtoepassenomdeXMLtagseenbepaaldelooktegeven.
XPL
XPLstaatvoorXMLPipelineLanguage.DitiseigenlijkgewooneenXMLdocumentdatopdecorrectemaniergeschrevenis,zoalsbeschrevendoorW3C.Hierkanudezebeschrijvingbekijken.
Appendices
87