Kolomdiagrammen met animatie
In het item Staafdiagrammen wordt getoond hoe je met betrekkelijk eenvoudige middelen een staaf- of kolomdiagram op kunt zetten. Daar zit ook een applicatie bij om zo'n diagram te genereren.
Op deze pagina wordt code gepresenteerd die hetzelfde doet voor een kolomdiagram, maar met een animatie die wordt getriggerd door aanwijzen met de muis of door aanraken.
Als je de code van zo'n diagram bekijkt blijkt er vaak helemaal geen ingewikkelde grafische representatie te zijn, alleen maar wat kleine .GIF-bestandjes. Elk van die bestandjes bevat een plaatje van één of hooguit een paar pixels; elk plaatje bevat één kleur.
De hier besproken code kun je downloaden voor eigen gebruik, inclusief de plaatjes.
- Er worden twee items besproken:
- Een voorbeeld van een Kolomdiagram met animatie.
- De HTML en het JavaScript die hiervoor nodig is.
- Inspiratie voor dit item is ontstaan door de benchmarks op tweakers.net.
Daar worden staafdiagrammen gebruikt. Voor deze site heb ik iets nagebouwd wat er op lijkt, maar dan als kolomdiagram.
De code bestaat uit HTML en JavaScript. Gebruik van CSS is minimaal.
- Een Kolomdiagram bevat staande balken, waarvan de lengte staat voor een getal. Het is moeilijk om een legenda direct bij
de kolommen te zetten. In dit verhaal is het achterwege gelaten.
- De opzet van een Kolomdiagram is als volgt:
- De hele figuur bestaat uit een tabel met twee rijen, elk met één cel.
- De bovenste rij/cel bevat de titel.
- De onderste rij/cel dient om wat witruimte te maken. Hier kan eventueel een ondertitel in worden gezet.
- De onderste rij/cel bevat zelf weer een tabel. In de bovenste rij/cel van deze tabel staat de titel van het kolomdiagram (aantal "votes").
- De tweede rij bevat de percentages. Voor elke kolom is er een cel.
- De derde rij bevat de kolommen met daaronder de waarden die de kolommen voorstellen. Ook hier is er voor elke kolom/waarde een cel<./li>
- Om de kleuren van de balken te veranderen moet je de .GIF-bestanden veranderen. Hiertoe moet je het kleuren-palet van
de achtergrond aanpassen. De plaatjes zelf bevatten slechts één bit per pixel. Dit is voor de goede functie
overigens niet nodig. Elk .GIF-plaatje is bruikbaar. Voor het beste resultaat zijn ze wel zo klein mogelijk en bevatten ze
dus één kleur.
Het voorbeeld op deze pagina is geschikt voor statische diagrammen, d.w.z. met inhoud die niet steeds verandert.
- Bij dynamische diagrammen is de werkwijze anders.
Eerst worden de vereiste gegevens uit een database gehaald. Vervolgens wordt de HTML op de server door een speciaal programma in elkaar gezet en naar de browser gestuurd. Ook de plaatjes worden door dat programma gemaakt en naar de browser gestuurd. Dat kan overigens ook met CSS worden geregeld.
Op deze manier kun je de veranderingen in de database bijhouden en kun je dus steeds een recente grafiek laten zien. Dit valt buiten het bestek van deze pagina.
- De werking van het script
-
HTML - De HTML van het voorbeeld bestaat uit twee geneste tabellen, die gecentreerd in het document zijn geplaatst.
- De eerste tabel beslaat 90% van de breedte van het document en bevat twee rijen. De eerste rij bevat de titel. De tweede rij bevat de tweede tabel met het kolomdiagram.
- De tweede tabel beslaat de volledige breedte van de eerste tabel en heeft evenveel kolommen als er in het diagram zijn. In het voorbeeld zijn dat er zes.
- De eerste rij beslaat volledige breedte van de zes kolommen van de tabel en bevat de ondertitel. De tweede rij is leeg.
- De derde rij bevat de percentages één getal per tabelcel.
- De vierde rij bevat de kolommen met daaronder het aantal dat de kolom voorstelt, één kolom per tabelcel.
- Helemaal onderaan, buiten de tabellen, staan de beschrijvende tekst en de link om het venster te sluiten.
- JavaScript
- Het JavaScript staat helemaal in de <head>-sectie van het document. Het bestuurt het gedrag van het kolomdiagram
via de events click (bij aanraakschermen) en mouseover / mouseout (bij gewone beeldschermen en een muis).
De event-handlers worden ingesteld met addEventListener().
- Het script begint met de declaratie van de constante waarden. Dit is een array waarin de getalswaarden worden gezet. Een bijbehorende beschrijving is met deze code niet mogelijk. Het aantal elementen wordt in de constante aantalWaarden bewaard.
- De constante waarden het enige dat moet worden aangepast in het JavaScript om een kolomdiagram te maken.
- Met de constanten kolomBreedte en maxLengte kan het uiterlijk van de kolommen worden veranderd.
- In de variabele totaalWaarden wordt het totaal van de getallen in waarden opgeslagen. Het totaal wordt bepaald door de function somWaarden(), die voor elk getal in waarden wordt aangeroepen waarbij totaalWaarden wordt bijgewerkt via een side-effect. Het berekende totaal wordt in het document geplaatst via de id totalen.
- Het percentage van elke kolom ten opzichte van het totaal wordt boven elke kolom gezet door de function toonPercentage().
- De staven worden getekend door de HTML. De tekst onder elke kolom wordt uit de data in waarden genomen en door
de function toonWaarde() in het document gezet.
- Er wordt onderscheid gemaakt tussen aanraakschermen en "gewone" beeldschermen.
º Als er met een aanraakscherm op een kolom wordt getikt, wordt het percentage van die kolom ingesteld op 100% en wordt bij de andere kolommen het percentage t.o.v. de aangetikte kolom getoond door de function percentage100().
º Als er met een gewoon scherm met de muis over een kolom wordt bewogen, wordt het percentage van die kolom ingesteld op 100% en wordt bij de andere kolommen het percentage t.o.v. de aangewezen kolom getoond door de function percentage100(). Als de muis de kolom verlaat worden de oorspronkelijke percentages terug gezet door de function resetPercentages().
N.B.: Computers met een aanraakscherm én een muis gedragen zich alsof een muis niet aanwezig is. - De koppeling van percentage100() verloopt via een anonieme function. Het hoe-en-waarom hiervan wordt besproken
in het item Functions met parameters gebruiken in addEventListener.
- De function somWaarden(item) telt de waarde item op bij totaalWaarden. De aanpak met een aparte function is nodig om de methode ForEach te kunnen gebruiken, waarin het niet niet mogelijk is om parameters te gebruiken in een function-aanroep.
- De function toonWaarde(n) zet element n van de array waarden in de id's wrden.
- De function toonKolom(n) berekent de lengte van de kolom (in px) en stelt die in, samen met de breedte van de kolom.
- De function toonPercentage(n) berekent voor waarden[n] het percentage van totaalAantal en zet dat in de id percn, afgerond op 1 decimaal. De afronding gebeurt met toFixed(1). Dit is een methode van het object number. Dit werkt alleen voor "echte" getallen, niet als het getal een string is.
- De function percentage100(n) berekent een percentage van een kolom ten opzichte van een kolom die op 100% is gezet door er met de muis boven te hangen of door aantikken. Ook hier wordt toFix(1) gebruikt om de getallen met 1 decimaal te laten zien.
- De function resetPercentages() zet de door percentage100(n) aangebrachte wijzingingen in het kolomdiagram
terug naar de beginsituatie.
- Inbouwen in je eigen site
- Download de zip-file en pak hem uit. Hernoem eventueel de file html830a.htm naar index.html. Je hebt nu een werkend voorbeeld.
- Zet een lijst van getallen in de constante waarden.
- Als er minder dan zes waarden zijn moet je de betreffende tabelcellen, in twee tabelregels, in de HTML verwijderen. Pas daarbij ook het attribuut colspan aan (op twee plaatsen).
- Als er meer dan zes waarden zijn moet je de betreffende tabelcellen, in twee tabelregels, HTML toevoegen. Pas daarbij ook het attribuut colspan aan (op twee plaatsen).
- De nummering van de diverse id's moet bij nul beginnen en mag geen gaten bevatten.
- Verander eventueel de breedte kolomBreedte van de kolommen (staat nu op 30px).
- Verander eventueel de maximale lengte maxLengte van de kolommen (staat nu op 150px). Deze waarde wordt toegekend aan de hoogste waarde in waarden. De lengtes van de andere kolommen worden berekend ten opzichte van MaxLengte.
- Pas de kleuren aan naar je eigen smaak.
Gebruik:
- De code staat gedeeltelijk in de <HEAD> en gedeeltelijk in de <BODY>.
De code van het voorbeeld ziet er als volgt uit:
(Zet dit in de <HEAD>).
<style>
.perc { text-align:center; }
.kolom {
vertical-align:bottom;
text-align:center;
width:60px;
}
</style>
<script>
const waarden = [3,2,2,4,1,7], kolomBreedte = 30, maxLengte = 150;
/* ==== Hieronder niet meer wijzigen ==== */
const aantalWaarden = waarden.length;
let totaalWaarden = 0, maxWaarde = 0;
window.addEventListener('load', function() {
// Bepaal de som en de hoogste van waarden[]
waarden.forEach(somWaarden);
for (let i=0; i<aantalWaarden; i++) { // Toon de percentages na de balk
toonWaarde(i);
toonKolom(i);
toonPercentage(i);
}
document.getElementById('totalen').innerHTML =
'<b>' + totaalWaarden + '</b>';
if ("ontouchstart" in document.documentElement) { // Aanraakscherm?
for (let i=0; i<aantalWaarden; i++)
document.getElementById('kolom'+i).addEventListener('click',
function() {percentage100(i)});
} else {
for (let i=0; i<aantalWaarden; i++) {
document.getElementById('kolom'+i).addEventListener('mouseover',
function() {percentage100(i)});
document.getElementById('kolom'+i).addEventListener('mouseout',
resetPercentages);
}
}
}); // event Load
function somWaarden(item) {
totaalWaarden += item;
if (item > maxWaarde) maxWaarde = item;
} // somWaarden
function toonWaarde(n) {
document.getElementById('wrde'+n).innerHTML = waarden[n];
} //toonWaarde
function toonKolom(n) {
document.getElementById('stl'+n).style.width = kolomBreedte + "px";
document.getElementById('stl'+n).style.height =
waarden[n] / maxWaarde * maxLengte + "px";
} //toonKolom
function toonPercentage(n) {
let helper = waarden[n] / totaalWaarden * 100;
document.getElementById('perc'+n).innerHTML =
helper.toFixed(1) + "%";
} // toonPercentage
function percentage100(n) {
let helper = 0.;
for (let i=0; i<aantalWaarden; i++) {
if (i == n || waarden[i] == waarden[n]) {
helper = 100;
document.getElementById('perc'+i).innerHTML =
helper.toFixed(1) + "%";
} else {
helper = (waarden[i] - waarden[n]) / waarden[n] * 100;
if (helper < 0) document.getElementById('perc'+i).innerHTML =
helper.toFixed(1) + "%";
else document.getElementById('perc'+i).innerHTML =
"+" + helper.toFixed(1) + "%";
}
}
} // percentage100
function resetPercentages() {
for (let i=0; i<aantalWaarden; i++) toonPercentage(i);
} // resetPercentages
</script>
(Zet dit in de <BODY> op de plaats waar het diagram moet verschijnen)
<div align="center">
<table border="1" cellspacing="1" cellpadding="2" bgcolor="#ddeeff"
width="90%">
<tr>
<td style="background-color:#5588cc; text-align:center; color:#fff">Geef uw mening!</td>
</tr><tr>
<td align="center">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
<tr>
<td colspan="6" align="center"><b>Wat vindt u van deze site?
[totaal <span id="totalen">??</span> stemmen]</b></td>
</tr><tr>
<td colspan="6"> <!-- Lege regel --></td>
</tr><tr>
<td class="perc" id="perc0">??</td>
.
Herhalen voor alle kolommen
.
<td class="perc" id="perc5">??</td>
</tr><tr>
<td class="kolom" id="kolom0"><img src="pixel-1.gif" id="stl0"><br><span id="wrde0">??</span></td>
.
Herhalen voor alle kolommen
.
<td class="kolom" id="kolom5"><img src="pixel-6.gif" id="stl5"><br><span id="wrde5">??</span></td>
</tr></table>
</tr></table><br>
Voorbeeld van een Kolomdiagram.</div>
Downloaden:
Druk op de knop:
File: voorb830.zip, 2562 bytes.
Opmerking:
Een versie voor staafdiagrammen is te vinden het item Staafdiagrammen met animatie.
