Kolacove grafy v PHP lahko a rychlo

16.12.2004 19:48 | blackhole

V tomto clanku si ukazeme ako v PHP generovat dynamicke kolacove grafy. Je to velmi jednoduchy priklad, ako pouzivat graficku kniznicu GD. Na konci clanku budu odkazy na stiahnutie. Odporucam najprv si pozriet ukazku , aby ste hned vedeli ci citat dalej.

Ja osobne rozsahliejsie veci kvoli jednoduchosti a prehladnosti pisem ako triedy a ukladam ich do samostatneho suboru. Pre mierne pokrocileho uzivatela by nemal byt problem prepisat si tento skript pre svoje uceli. Ak by ste vsak mali s timto problemi tak napiste do komentarov a ja vam pomozem. Takze zacneme:

class Graf
{
...
Zadeklarovanie triedy by malo byt kazdemu jasne. Teraz si zadefinujeme premenne ktore budeme potrebovat. Pri kazdom obrazku by sme mali poznat sirku a vysku. Dalej budeme potrebovat identifikator obrazku. Dalsia premenna bude pole, ktorebued obsahovat indexi farieb ktore ziskame pri alokacii. Dalej tam budu premenne pre pocet vrstieva farebny rozdiel v oblasti svetla a tiena. Potom samotni program bude potrebovat 4 pomocne premenne, ktore budu uchovavat ohol predchadzajuceho vyseku a uhol aktualneho vyseku, cestu k obrazku pri ulozeni a posledna bude urcovat, ci uz bol obrazok odoslani do prehliadaca aby sa zamedzilo duplicitnemu odoslaniu.

...
var $image; //identifikator obrazku
var $sirka; //celkova sirka ...

var $vyska; //... a vyska obrazku
var $farby = Array(); /* farby, asociativne pole,
obsahuje index v palete vrateny funkciou ImageCollorAllocate */
var $vrstvy; //pocet vrstiev
var $old; //posledny uhol, koniec predchadzajuceho vyseku
var $uhol; //uhol tohto vyseku
var $send; //urcuje, ci uz bol obr. poslany
var $rozdiel = 17; //urcuje farebny rozdiel
var $path; //cesta k obr.
...
Tak, premenne by boli, teraz je na rade konstruktor a metody:

...
function Graf ($sirka, $vyska, $pozadie, $vrstvy = 10, $rozdiel = 17){
$this->rozdiel = $rozdiel;
$this->send = 0;
$this->sirka = $sirka;
$this->vyska = $vyska;
$this->vrstvy = $vrstvy;
$this->image = imagecreate($sirka, $vyska);
$this->Alokuj ($bg, $pozadie[0], $pozadie[1], $pozadie[2]);
}
...
Prva cast konstruktoru len zadefinuje premenne a ta druha len alokuje farbu pozadia. Nasleduje metoda Alokuj, ktora sluzi na alokaciu farieb. Alokuje farbu a ulozi jej index do asociativneho pola pod jej menom (zadane ako prvy parameter) a vytvori tmavsiu farbu, ktora sa pouzije na tienovane okraje:

...
function Alokuj ($farba, $r, $g, $b) {
$this->farby[$farba] = imagecolorallocate($this->image, $r, $g, $b);
$darkr = $r > ($this->rozdiel - 1) ? $r - $this->rozdiel : 0;
$darkg = $g > ($this->rozdiel - 1) ? $g - $this->rozdiel : 0;
$darkb = $b > ($this->rozdiel - 1) ? $b - $this->rozdiel : 0;
$this->farby[\"dark\"
.$farba] = imagecolorallocate($this->image,$darkr,$darkg,$darkb);
}
...
Tak, a teraz najdolezitejsia funkcia ktora vykresli graf:

...
function Pridaj ($data) {
foreach($data as $kolko) {
$celkovo += $kolko;
}
$x = 60 - $this->vrstvy;
for ($i = 60; $i > $x; $i--) {
foreach ($data as $farba=>$kolko) {
if ($i != ($x + 1)) {
$farba = \"dark\" . $farba;
}
$this->uhol = $kolko / $celkovo * 100 * 3.6;
imagefilledarc($this->image, 50, $i, 100, 50, $this->old,
($this->old + $this->uhol), $this->farby[$farba], IMG_ARC_PIE);
$this->old += $this->uhol;
} // foreach - koniec
} // for - koniec
} // pridaj () - koniec
...
Toto je uz tazsia cast programu. Najprv cyklus foreach spocita celkovu hodnotu. Potom dalsi cyklus prejde vsetky hodnoty, vykresli ich spravnou farbou a pod spravnim uhlom. Pripadne otazky piste do komentarov. Nasleduju 3 funkcie na ulozenie, odoslanie na vystup a vygenerovanie HTML kodu. Tieto funkcie su velmi jednoduche a preto ich nebudem popisovat:

// ulozi obr.
function Save ($path) {
$this->path = $path;
ImagePNG ($this->image, $path);
}

// odosle obr. na vystup
function Send () {
if ($this->send) return; // ak uz bol poslany obr. skoncime
Header(\"Content-type: image/png\");
ImagePNG ($this->image);
$this->send = 1;
}

//vygeneruje HTML kod pre vlozenie obr.
function HTMLCode () {
$code = \"path.\"\"width=\"\".$this->sirka.\"\"height=&q uot;\".$this->vyska.\"\">\";
return $code;
}

} // class graf - koniec
?>
A teraz si ukazeme ako tuto triedu pouzivat. Vsetko by malo byt jasne z komentarov v skripte:

require (\"3Dkolacgraf.class.php\"); //nacitanie triedy
$x[] = 255; //zlozka cervenej vo farbe pozadia (0 - 255)
$x[] = 255; //zlozka zelenej
$x[] = 255; //zlozka modrej
$tr = new Graf(100, 100, $x, 10, 17 * 5); /* vytvorenie grafu
parametre => graf(SIRKA, VYSKA, pozadie, pocet vrstiev,
farebny rozdiel medzi svetlom a tienom) */
$tr->Alokuj(\"modra\", 0, 0, 255); /* vytvorenie farby -
patrametre => Alokuj(meno farby, cervena, zelena, modra) */
$tr->Alokuj(\"zelena\", 0, 255, 0);
$tr->Alokuj(\"cervena\", 255, 0, 0);
$tr->Alokuj(\"zlta\", 0, 255, 255);
$data[\"zelena\"] = 30; // zadanie hodnot pre zelenu farbu
$data[\"modra\"] = 20;
$data[\"zlta\"] = 10;
$data[\"cervena\"] = 40;
$tr->Pridaj($data); //vykreslenie
$tr->Save(\"obr.png\"); //ulozenie
$tr->Send(); //zobrazenie grafu
imagedestroy($tr->image); //zrusenie obrazku - uvolnenie pamete
?>

Dufam ze sa vam clanok pacil, uz sa tesim na vase komentare :)). Subory najdete na tejto adrese.lacop