Enter, update en exit - RoyCsuka/frontend-data GitHub Wiki
Enter
In mijn code creëer ik svg cirkels en text elementen in app.js met D3. Dit doe ik met .enter() en daarna .append(). Als eerst maak je de cirkels aan die er nog niet zijn door algemene variabele aan te maken zoals hieronder: note: svg bestaat wel de HTML als element en hierin worden dan met svg cirkels aangemaakt en text. De svg elementen krijgen ook nog data mee die op het element zitten.
let circles = select('svg').selectAll('circle').data([data][0])
let text = select('svg').selectAll('text').data([data][0])
Mijn enter
Hieronder het begin van mijn enter.
circles
.enter()
.append('circle')
Dit is de enter die allemaal 'circle' elementen aanmaakt. Door voor de enter 'circles' aan te roepen (de variabele die ik aan het begin heb aangemaakt).
Daarna zet ik attributen op mijn svg element zoals hier onder te zien is:
note: De derde regel roep ik een functie aan die ervoor zorgt dat elke cirkel op basis van de data die die binnen krijgt een minimale en een maximale waarde van de array aan roept en daarna een range neer zet van het aantal pixel deze maximaal mag worden. code daarvan ziet er zo uit:
const scale = d3.scaleLinear().domain([ min, max ]).range([ 15, 90 ]);
.attr('cx', d => projection([d.contLong, d.contLat])[0])
.attr('cy', d => projection([d.contLong, d.contLat])[1])
.attr('r', function(d) { return scale(d.amountOfCountryItems) })
.attr('opacity', 0.8)
Ik geef een x & y positie mee met de eerste twee regels. Deze posities zijn gebaseerd op mijn data. Daarna geef ik aan hoe groot elke cirkel moet worden en maak ik mijn cirkels 80% zichtbaar. Als je bijvoorbeeld naar de eerste regel kijkt zie je .attr staan en hiermee geef je aan dat je een attribute wilt zetten op een element. Vervolgens geef je aan wat voor soort attribute er toegevoegd moet worden en ik geef hier de 'cx' aan en dat gaat over de horizontale positie van de cirkel. Daarna geef ik aan dat die moet loopen door de data zodat ie dit voor elk element doet met: d => d
('d' staat voor 'data') Het enige verschil is hier dat "projection" erbij staat en dat is om het te kunnen plotten op een kaart van D3.
Een overzichtelijke loop is de code hieronder te zien op de vijfde regel.
Hierna doe ik hetzelfde voor de text elementen die hieronder te zien is:
text
.enter()
.append('text')
.attr('x', d => projection([d.contLong, d.contLat])[0])
.attr('y', d => projection([d.contLong, d.contLat])[1])
.text(d => d.amountOfCountryItems)
Update
Met update geef je alleen maar aan wat je gaat wijzigen als de data opnieuw binnenkomt. De waardes hiervan gaan dus bijvoorbeeld alleen over de attributen (positie, grootte bijv.) van elk element.
Mijn update
Door alle attribute waardes die je wilt veranderen voor de enter te zetten en te definiëren update je je waardes zoals hieronder stap voor stap te zien is.
Cirkels
Hieronder geef ik voordat de enter wordt uitgevoerd de attributen nogmaals aan zodat deze waardes aangepast worden. Voor mijn cirkels doe ik het volgende:
circles
.attr('cx', d => projection([d.contLong, d.contLat])[0])
.attr('cy', d => projection([d.contLong, d.contLat])[1])
.attr('r', function(d) { return scale(d.amountOfCountryItems) })
Hierboven geef ik een nieuwe x & y positie voor op de kaart mee en een nieuwe grootte van de cirkel.
Tekst
Voor de tekst waardes doe ik het volgende:
text
.attr('x', d => projection([d.contLong, d.contLat])[0])
.attr('y', d => projection([d.contLong, d.contLat])[1])
.text(d => d.amountOfCountryItems)
Hierboven geef ik een nieuwe x & y positie voor op de kaart mee en een nieuw cijfer.
Exit
Door .exit().remove() op een geselecteerd svg element op het einde van je D3 functie neer te zetten verwijder je de items die niet meegenomen zijn in de update. Alles wat je dit niet aangeeft in je update blijft staan.
Mijn exit
Hieronder is te zien dat ik op het laatste de circles en text weer selecteer en daar twee dingen op uitvoer: .exit() en .remove()
circles
.exit()
.remove()
text
.exit()
.remove()