4min

De omlijsting tekenen

Naast de witte achtergrond moet er ook een omlijsting worden gemaakt. De omlijsting is afhankelijk van hoe groot de rand moet zijn. Die is in het script van de vorige pagina viermaal ingesteld; voor elke kant van het figuur is een waarde op gegeven. Een manier om de omlijsting te tekenen is door vier opgevulde rechthoeken te tekenen op het figuur met diverse afmetingen en posities. In dit geval ga ik gebruiken maken van imagefilledpolygon.

Een polygon (polygoon) is een figuur waar bij je de vorm kan opgeven met behulp van een array. Hoeveel hoeken deze polygoon heeft mag je helemaal zelf bepalen. Met ‘imagefilledpolygon’ wordt tevens ook de polygoon opgevuld. Door de omlijsting te definiëren als een polygoon kan in één stap de omlijsting worden getekend. Het is dan nodig om alle ‘hoeken’ te tekenen van de vorm. PHP vult dan alle ruimte op die binnen deze vorm valt.

Om het duidelijker te maken hoe de omlijsting dan gedefinieerd is heb ik het volgende figuur getekend:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
// Teken de omlijsting
$punten =  array(
	0,0, // 1
	0,$hoogte, // 2
	$breedte, $hoogte, // 3
	$breedte, 0, // 4
	$rand_links,0, // 5
	$rand_links, $rand_boven, // 6
	$breedte-$rand_rechts, $rand_boven, // 7
	$breedte-$rand_rechts, $hoogte-$rand_onder, // 8
	$rand_links, $hoogte-$rand_onder, // 9
	$rand_links, 0 // 10
);
imagefilledpolygon($graph, $punten, count($punten)/2, $gray);
 
$grafiek_breedte = $breedte-$rand_links-$rand_rechts;
$grafiek_hoogte = $hoogte-$rand_onder-$rand_boven; 
 

De polygoon begint in de linkerbovenhoek op 0,0. Vervolgens wordt de hoek linksonder gedefinieerd. Dat is 0 naar rechts, maar met de hoogte van de grafiek naar beneden enzovoorts. De nummering van de hoeken in het figuur geeft de volgorde aan die in de php-code wordt gebruikt.

Bij imagefilledpolygon wordt de volgende functiedefinitie gehanteerd:
Code
1
bool imagefilledpolygon(resource $image, array $polygon, int $hoeken, resource $kleur);

  • resource $image
    Het figuur waar op getekend moet worden, in dit geval de grafiek;
  • array $polygon
    De array met de coördinaten van alle hoeken;
  • int $hoeken
    Het aantal hoeken dat in de polygoon gedefinieerd is. Omdat een coördinaat (is een hoek) altijd twee waardes nodig heeft (X en Y waarde) is het dus het aantal punten in de polygon array en die gedeeld door twee. Merk ook op dat een oneven aantal waarden in de polygon array niet kan, dan is er een coördinaat dat niet compleet is;
  • int $kleur
    De kleur waar mee de polygoon opgevuld mee moet worden. Deze is afkomstig van imagecolorallocate.

Raster & schaalverdeling


Een grafiek heeft vaak een raster nodig. Zonder raster is het lastig om in te schatten waar de tussenliggende waardes liggen. Een raster is ook de basis voor de verdeling van alle waarden. Zo is de schaling van de y as afhankelijk van de ingevoerde waarden. Het is dan ook van belang om te bepalen hoeveel labels er moeten worden weergegeven. In dit geval heb ik gekozen voor tien labels. Dat wilt zeggen dat er tien nummers in de kantlijn komen te staan.

Om het verschil tussen elk nummer uit te rekenen (dus hoeveel er per nummer bij komt) kun je de maximale waarde van de grafiek pakken en die delen door tien (het aantal nummers). Dat zal in principe prima werken. Het is echter vervelend als een grafiek enkel punten heeft boven de 900, met zeer kleine veranderingen (maximaal twintig bijvoorbeeld). De grafiek wordt dan uit zijn verband getrokken.
Om dat op te lossen maak ik gebruik van het verschil tussen de minimum-waarde en maximumwaarde. Het kan dus gebeuren dat de nullijn niet altijd getekend wordt. Bovendien is het ook netjes om geen komma’s in de kantlijn te gebruiken. Hele getallen werken veel gemakkelijker bij het schatten van tussenliggende waardes. Het gebied dat moet worden weergegeven moet dus wat opgerekt worden. In dit geval heb ik gekozen om het maximum altijd te vergroten indien blijkt dat er kommagetallen nodig zijn. De code voor de schaalverdeling is:

PHP Code
1
2
3
4
5
// Schaalverdeling berekeningen.
$y_max = max($gegevens);
$y_min = min($gegevens);
$y_stap = ceil( ($y_max - $y_min)/10);
$y_max = $y_min + 10 * $y_stap;

Als eerst wordt er een analyse op de gegevens uitgevoerd; wat is de minimale en maximale waarde van de gegevens? Vervolgens is het nodig om de maximale waarde te vergroten. Door de stapgrootte uit te rekenen en die altijd naar boven af te ronden (met behulp van ceil), wordt er dus altijd een nette stap bepaald. Vervolgens moet de maximumwaarde worden herberekend, die is namelijk vergroot (omdat de stap vergroot is).

In tegenstelling tot de y-as zorgt de x-as voor veel minder rekenwerk. De x-as-verdeling is afhankelijk van het aantal ingevoerde waardes. Meer waardes betekent dat de punten dichter op elkaar moet worden getekend. Dat is een kwestie van de grafiekbreedte delen door het aantal punten.