Onze eerste stap is het maken van een overzichtsgrafiek. We willen een lijst van alle boeken, met daarnaast het aantal personages en bladzijden per boek. We starten bij de lijst van huidige boeken. Om erachter te komen hoe groot onze dataset is, kunnen we de functie length gebruiken. Door deze achter mijnData te plaatsen (de variabele waar al onze data in zit). Aangezien we alle boeken hebben opgevraagd, is de lengte van de data ook meteen het totale aantal boeken. Om dit te testen kunnen we een text neerzetten met als inhoud mijnData.length.
We zien dat deze 10 aangeeft. In totaal zijn er dus op dit moment 10 boeken. Voor elke van die 10 boeken willen we de titel weten. Van onze vorige lessen herinneren we dat we hiervoor een loop kunnen gebruiken. Deze loop bestaat uit :
- start: 0 (bij het eerste boek)
- stap: 1 ( boek per keer)
- stop: mijnData.length (het totaal aantal boeken, onafhankelijk of we precies weten hoeveel)
de loop wordt dan:
for(var i=0; i<mijnData.length; i++){ ... }
Deze loop gaat alle boeken langs. Elke keer we een volgend boek oproepen, willen daar de titel van laten zien. Als we even terugkijken naar de data die we hebben opgehaald, zien we dat daar structuur en hiërarchie in zit. Elk boek bevat een url, name,… enzovoort. Door een punt te zetten achter mijnData kan je in de hierarchie zakken. Wil ik bv. enkel de URL van een boek inladen, kan dat door mijnData.url. Als we dit toepassen werkt dit niet ! Dit komt omdat er in mijnData niet 1 , maar 10 boeken zitten. Alhoewel we pas volgend blok dieper op arrays ingaan, krijg je hier de basics alvast mee. We moeten niet alleen aangeven dat we de url willen, maar ook van WELK boek. mijnData[0] geeft bijvoorbeeld alle data van het eerste boek. mijnData[1] van het tweede, enzovoort…
Als we dan terug naar onze loop kijken, zien we daar iets bijzonders: de letter i. i staat namelijk voor het punt waarop we in de loop zitten. i wordt 0,1,2,3,4,5,6,7,8 en 9. Als we dus van elk boek de titel willen zullen we niet mijnData[0], mijnData[1],… moeten doen (alhoewel dit kan, maar veel nodeloos werk is). We kunnen mijnData[i] opvragen !.
de loop wordt dan:
for(var i=0; i<mijnData.length; i++){ text(mijnData[i].name, 10, height/2); }
Als we de loop op deze manier uitvoeren, komen alle namen over elkaar heen te staan. Dit lossen we op door i ook voor de y-positie te gebruiken. Als we telkens ix20 doen, krijgen we 20,40,60,80,… We passen de loop nogmaals aan:
for(var i=0; i<mijnData.length; i++){ text(mijnData[i].name, 10, i*20); }
tijd om te testen:
We zijn er in geslaag om in een loop de titel op te halen voor elk boek en deze te laten zien op het scherm. Volgende stap is het aantal personages en het aantal bladzijden opvragen. We gaan weer terug naar onze structuur van het JSON object kijken en zien dat de aantal bladzijden zijn ondergebracht in numberOfPages en al de personages in characters. numberOfPages is gewoon 1 cijfer, characters bevat een lijst met alle personages uit dat boek.
Vooraleer we proberen iets met de data te tekenen, gaan we ze eerst achter de titels van de boeken laten zien. Om het aantal bladzijden op te vragen kunnen we
mijnData[i].numberofPages
aanroepen.
Om het aantal personages te weten zullen we ze moeten tellen. Dat kunnen we op dezelfde manier als waarop we het aantal boeken hebben geteld. Door de lengte van de data in characters op te vragen:
mijnData[i].characters.length
Wanneer we beiden in de loop plaatsen en hun waarden achter de titel van het boek voegen krijgen we:
for(var i=0; i < mijnData.length; i++){ text(mijnData[i].name + " " + mijnData[i].numberOfPages + " " + mijnData[i].characters.length, 10, 20 + i*20); }
Merk op dat we
+ " " +
gebruiken om spaties aan te brengen. Dit komt omdat de text() functie alles omzet naar een String. Een string is een reeks woorden. Woorden kan je niet optellen, dus we gebruiken + om ze samen te voegen. Doen we dat echter zonder spatie, dan hangt alles aan elkaar. Door lege Strings toe te voegen, maken we spaties aan.
Nu is het tijd om deze getallen om te zetten naar een grafische representatie. We gaan punten plaatsen relatief aan het aantal personages en bladzijden. Omdat onze sketch maar 400 pixels breed is, zullen we de getallen moeten verkleinen. We doen dit door beiden door 5 te delen. We plaatsen dus een witte en een groene ellipse, op een x-afstand die overeenkomt met het aantal personages en het aantal karakters, een y-afstand die we overnemen van de y-coordinaat van de titel van het boek en we maken de ellipse 10 pixels breed en hoog.
Dat resulteert in :
ellipse(mijnData[i].characters.length/5, i*20, 10, 10); ellipse(mijnData[i].numberOfPages/5, i*20, 10,10);
We zien echter dat als we dit in onze code integreren dat sommige punten door de tekst heen lopen. Dit lossen we op door een vast getal 140 bij de x-coordinaat bij te tellen.
ellipse(140 + mijnData[i].characters.length/5, i*20, 10, 10); ellipse(140 + mijnData[i].numberOfPages/5, i*20, 10,10);
Tijd om onze code te testen. We zetten nu ook de canvasbreedte en hoogte op 400, anders is er niet genoeg plaats.
Als laatste actie voor ons overzicht gaan we een lijn trekken tussen de zwarte punten en een lijn tussen de groene punten. Om dit te doen moeten we in de loop telkens een punt met het volgende verbinden. Het huidige punt vragen we op met:
mijnData[i].characters.length/5 en mijnData[i].numberOfPages/5
Als we het daaropvolgende punt telkens willen weten, doen we dat door :
mijnData[i+1].characters.length/5 en mijnData[i+1].numberOfPages/5
merk op dat i, i+1 is geworden. Hierdoor vragen we telkens het punt op dat volgt op het huidige punt. Wanneer je dit in je code invoegt zal het werken, maar je krijgt een foutmelding. We maken namelijk een fout. Het laatste punt heeft helemaal geen volgende meer! Dat lossen we op door een conditie te gebruiken. We vragen alleen een volgend punt op, als er nog een volgend is. Dat wil zeggen:
zo lang i kleiner is dan 1 minder dan de lengte van mijnData of if(i < mijnData.length-1)
Het hele stukje code voor de lijnen komt er dan zo uit te zien:
if (i < mijnData.length - 1) { line(140 + mijnData[i].characters.length / 5, 20 + i * 20, 140 + mijnData[i + 1].characters.length / 5, 20 + (i + 1) * 20); stroke(0, 255, 0); line(140 + mijnData[i].numberOfPages / 5, 20 + i * 20, 140 + mijnData[i + 1].numberOfPages / 5, 20 + (i + 1) * 20); }
Nu hebben we onze complete code voor een mooi overzicht: