-
Notifications
You must be signed in to change notification settings - Fork 0
UpdatePattern
Om een de d3 visualisatie interactief te maken is het nodig om een update pattern toe te voegen. Het update pattern van d3 zorgt ervoor dat je data, zonder het herladen van de pagina, kan manipuleren. En zo dus verschillende inzichten kan krijgen in de data.
Voor mijn concept heb ik een filter toegevoegd, die bepaalde garages wel en niet laat zien op basis van een aantal eisen waar aan de garage moet voldoen. Hiervoor heb ik allereerst een filter gemaakt die bestaat uit een aantal radiobuttons:
//reserve div for the input form
const form = d3.select('form')
.selectAll('div')
.data(idInput)
.enter()
.append('div')
.attr('class', 'radio')
// inside the div make a label with the text of the year array
form.append('label')
.attr('for', (d, i) => (d))
.text((d, i) => {
const beperkt = "Beperkte parkeerplaatsen"
const valide = "Invaliden parkeerplaatsen"
const Alles = "Alle parkeerplaatsen"
if (d == "disabled") {
return d = beperkt
} else if (d == "charging") {
return d = valide
} else if (d == 'both') {
return d = Alles
}
})
.style('background-color', (d, i) => color(d))
Bij de volgende code wordt de input aan de form toegevoegd, ook wordt hierin een onchange event toegevoegd. Dit zorgt ervoor dat de data kan worden geupdate wanneer er een verandering in het formulier plaats vindt. Aan het einde van wordt de functie update aangeroepen, die functie gaat er voor zorgen dat de nieuwe data wordt gefilterd.
// Make radiobuttons inside the input form
form.append('input')
.attr('type', 'radio')
.attr('name', 'radio')
.on('change', (d, i) => {
if (i === 'disabled') {
i = ['disabled', 'both']
} else if (i === 'charging') {
i = ['charging', 'both']
} else if (i === 'both') {
i = ['charging', 'both', 'none', 'disabled']
} else if (i === 'none') {
i = ['none']
}
update(i); // Call function to reassing dots
})
In update functie wordt nu een array meegegeven met de id's die moeten worden gerenderd. Vervolgens gaat de filter functie over de data heen die kijkt in welke van de datapunten de meegegeven id's zitten. Deze worden opgeslagen in een variable, en deze variable wordt meegegeven aan de updateDots functie, die vervolgens de nieuwe punten inlaad.
function update(i) {
const checkedBoxes = data.filter((row) => i.includes(row.id))
updateDots(checkedBoxes);
}
Hieronder is deze updateDots functie weergegeven. Aan het einde van het neerzetten van de nieuwe punten wordt de .exit().remove functie gebruikt. Deze zoekt de cirkels op die zijn geplot die op dat moment geen data meer hebben, al deze cirkels worden door de remove() functie verwijderd van de visualisatie. Hierdoor zijn deze punten zowel uit de data als uit het scherm. It's as easy as that :)
function updateDots(data) {
const dots = g.selectAll('circle')
.data(data)
dots
.attr('cx', (d) => projection([d.accessPointLocation[0].longitude, d.accessPointLocation[0].latitude])[0])
.attr('cy', (d) => projection([d.accessPointLocation[0].longitude, d.accessPointLocation[0].latitude])[1])
dots.enter()
.append('circle')
.attr('r', radius)
.attr('class', d => d.id)
.attr('fill', (d) => color(d.id))
.attr('stroke', (d) => color(d.id))
.attr('fill-opacity', 0.3)
.attr('r', radius)
.attr('cx', (d) => projection([d.accessPointLocation[0].longitude, d.accessPointLocation[0].latitude])[0])
.attr('cy', (d) => projection([d.accessPointLocation[0].longitude, d.accessPointLocation[0].latitude])[1])
dots.exit()
.remove()
}