Table of Contents - Elektronica-ICTbeta.eaict.ap.be/wp-content/uploads/2016/06/KennyEmbrech...PHP...

Preview:

Citation preview

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('{','&quot;','state','&quot;',':','&quot;',./result/channels/@com,'&quot;,','&quot;','count','&quot;',':','&quot;',.,'&quot;,','&quot;','chan','&quot;',':','&quot;',./result/channels/@chan,'&quot;},')"></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('&quot;',./result/channels/@com,'&quot;')"></xf:output>,"count":<xf:outputvalue="concat('&quot;',.,'&quot;')"></xf:output>,"chan":<xf:outputvalue="concat('&quot;',./result/channels/@chan,'&quot;')"></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('&quot;',@com,'&quot;')"></xf:output>,"date":<xf:outputvalue="concat('&quot;',../date,'&quot;')"></xf:output>,"count":<xf:outputvalue="concat('&quot;',.,'&quot;')"></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('{','&quot;','state','&quot;',':','&quot;',./result/channels/@com,'&quot;,','&quot;','count','&quot;',':','&quot;',.,'&quot;,','&quot;','chan','&quot;',':','&quot;',./result/channels/@chan,'&quot;},')"></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('&quot;',./result/channels/@com,'&quot;')"></xf:output>,"count":<xf:outputvalue="concat('&quot;',.,'&quot;')"></xf:output>,"chan":<xf:outputvalue="concat('&quot;',./result/channels/@chan,'&quot;')"></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('&quot;',@com,'&quot;')"></xf:output>,"date":<xf:outputvalue="concat('&quot;',../date,'&quot;')"></xf:output>,"count":<xf:outputvalue="concat('&quot;',.,'&quot;')"></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('&quot;',./relation/@com,'&quot;')"></xf:output>,"count":<xf:outputvalue="concat('&quot;',.,'&quot;')"></xf:output>,"parent_id":<xf:outputvalue="concat('&quot;',./relation/@parent_id,'&quot;')"></xf:output>,"child_id":<xf:outputvalue="concat('&quot;',./relation/@child_id,'&quot;')"></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

Recommended