Ik heb de volgende code om een staafdiagram te maken (eea zo goed mogelijk gedocumenteerd):
Een aantal voorbeelden:




Vraag: hoe kan ik ervoor zorgen dat alle plaatjes even breed zijn? Ik heb er al aan gedacht om de padding tussen de kolommen automatisch te maken ipv fixed (maar dan zit ik nog steeds met het afrond-probleem). De enige andere oplossing die ik zelf kon bedenken was om alle "verloren" pixels op te tellen en tussen de laatste kolom en de zwarte rechterkant van het kader, een marge / witruimte ter grootte van die pixels te stoppen. Heeft iemand nog een ander idee?
PHP:
Het probleem is als volgt: in regel 15 gebruik ik floor om de breedte van de kolommen te berekenen. Ik gebruik floor, omdat ik de breedte in hele pixels wil hebben. Als ik ceil gebruik, kan de totale breedte van de kolommen meer zijn dan de breedte van het plaatje zelf ($width = 530 in regel 2). Het grote nadeel van floor is, dat als er veel kolommen zijn, de waarde van $base telkens een halve pixel ofzo kleiner is dan de werkelijke (niet-gefloorde) breedte. Aan het einde van de rit mis ik dan 10 pixels ofzo. Met andere woorden: het plaatje wordt minder breed dan 530 pixels. Samengevat:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| function stats_bar($title, $data, $imagename) { $width = 530; $height = 200; $vmargin = 20; // top + bottom margin for x-labels $hmargin = 30; // left margin for y-labels $ngrid = 5; // number of grid lines $image = imagecreate($width, $height); $white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); $navy = imagecolorallocate($image, 0x00, 0x00, 0x80); $black = imagecolorallocate($image, 0x00, 0x00, 0x00); $gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0); $nval = sizeof($data); $base = floor(($width - $hmargin) / $nval); // distance between columns $ysize = $height - (2 * $vmargin); // y-size of plot $xsize = $nval * $base; // x-size of plot $txtsz = imagefontwidth(2) * strlen($title); // pixel-width of title $xpos = max(1, $hmargin); // force positive coordinates imagestring($image, 2, $xpos, 0, $title , $black); $dydat = max($data) / $ngrid; // data units between grid lines $dypix = $ysize / ($ngrid + 1); // pixels between grid lines $padding = 2; // 1/2 spacing between columns $yscale = $ysize / (($ngrid + 1) * $dydat); // pixels per data unit for ($i = 0; $i <= ($ngrid); $i++) { // $ngrid + 1 voor extra y-label $ydat = (int)($i * $dydat); $ypos = $vmargin + $ysize - (int)($i * $dypix); $txtsz = imagefontwidth(1) * strlen($ydat); // pixel-width of label $txtht = imagefontheight(1); // pixel-height of label $xpos = max(1, (int)(($hmargin - $txtsz) / 2)); imagestring($image, 1, $xpos, $ypos - (int)($txtht / 2), $ydat, $black); if (!($i == 0) && !($i > $ngrid)) { imagelinedotted($image, $hmargin, $ypos, $hmargin + $xsize, $ypos, 2, $gray); } } imagerectangle($image, $hmargin, $vmargin, $hmargin + $xsize, $vmargin + $ysize, $black); for ($i = 0; list($xval, $yval) = each($data); $i++) { $ymax = $vmargin + $ysize; $ymin = $ymax - (int)($yval * $yscale); $xmax = $hmargin + ($i + 1) * $base - $padding; $xmin = $hmargin + $i * $base + $padding; imagefilledrectangle($image, $xmin, $ymin, $xmax, $ymax, $navy); $txtsz = imagefontwidth(1) * strlen($xval); $xpos = $xmin + (int)(($base - $txtsz) / 2); $xpos = max($xmin, $xpos); $ypos = $ymax + 6; // distance of x-labels from x axis imagestring($image, 1, $xpos, $ypos, $xval, $black); } imagepng($image, IMG_PATH . $imagename . '.png'); imagedestroy($image); } // Voorbeeldcode om functie te gebruiken: for ($i = 1; $i < 8; $i++) { $dag[$i] = (3 * $i) + 5; } stats_bar("Verdeling over dagen van de week", $dag, 'dagelijks'); |
- floor zorgt bij veel kolommen voor grafieken smaller dan 530 px
- ceil zorgt bij veel kolommen voor grafieken breder dan 530 px
PHP:
7
| $base = round((($width - $hmargin) / $nval), 1); // width of columns |
Een aantal voorbeelden:




Vraag: hoe kan ik ervoor zorgen dat alle plaatjes even breed zijn? Ik heb er al aan gedacht om de padding tussen de kolommen automatisch te maken ipv fixed (maar dan zit ik nog steeds met het afrond-probleem). De enige andere oplossing die ik zelf kon bedenken was om alle "verloren" pixels op te tellen en tussen de laatste kolom en de zwarte rechterkant van het kader, een marge / witruimte ter grootte van die pixels te stoppen. Heeft iemand nog een ander idee?
[ Voor 6% gewijzigd door Reveller op 05-05-2006 16:41 ]
"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."