Programare web

Cum să creezi un chart doar cu PHP

În tutorialul anterior am discutat despre cum putem crea un chart dinamic utilizând ChartJS pentru a crea toată interfața pe un element canvas, PHP-ul fiind necesar doar pentru a prelua informațiile dintr-o bază de date și pentru a le parsa în format Json scriptului.Acum vom merge pe o altă abordare și vom utiliza doar PHP pentru crearea întregului chart.Pentru aceasta ne vom folosi de funcțiile image din PHP pentru a crea o imagine cu chart-ul nostru.

1.Primul lucru pe care îl facem este să creăm un vector asociativ care să conțină informațiile ce vor fi prezente pe cele două axe.Pe axa Ox vom scrie lunile anului, iar pe axa Oy valorile numerice ce corespund fiecăreia.
[cc lang=”php”]
110,
“Feb” => 130,
“Mar” => 215,
“Apr” => 81,
“May” => 310,
“Jun” => 110,
“Jul” => 190,
“Aug” => 175,
“Sep” => 390,
“Oct” => 286,
“Nov” => 150,
“Dec” => 196
);
[/cc]

2.Următorul pas este să setăm lungimea și lățimea viitorului chart, dar și marginile acestuia.
[cc lang=”php”]
$img_width=450;
$img_height=300;
$margins=20;
[/cc]

3.Acum vom calcula dimensiunea efectivă a chart-ului, scăzând din lungime și lățime lățimea marginilor.
[cc lang=”php”]
# —- Gasim marimea chartului scazand marimea marginilor
$graph_width=$img_width – $margins * 2;
$graph_height=$img_height – $margins * 2;
$img=imagecreate($img_width,$img_height);
[/cc]

4.Vom defini lățimea unei bare, iar apoi utilizând funcția count aflăm câte bare vom avea în chart.Ultimul lucru pe care trebuie să-l facem este să aflăm lățimea spațiului dintre bare – pe acesta îl calculăm scăzând din lățimea efectivă a chart-ului lățimea totală a barelor(acest calcul ne oferă lățimea totală a spațiilor libere) și împărțind la numărul de spații libere care veți vedea, dacă faceți un mic desen, că sunt egale cu numărul de bare + 1.
[cc lang=”php”]
$bar_width=20;
$total_bars=count($values);
$gap= ($graph_width- $total_bars * $bar_width ) / ($total_bars +1);
[/cc]

5.Folosind funcția imagecolorallocate atribuim imaginii noastre, $img, culorile necesare, în format RGB.
[cc lang=”php”]
# ——- Definim culorile —————-
$bar_color=imagecolorallocate($img,0,64,128);
$background_color=imagecolorallocate($img,240,240,255);
$border_color=imagecolorallocate($img,200,200,200);
$line_color=imagecolorallocate($img,220,220,220);
[/cc]

6.Funcția imagefilledrectangle crează un border în jurul chart-ului.Are nevoie de 6 parametrii:$img adică imaginea, x1, y1(coordonatele punctului 1), x2, y2(coordonatele punctului 2) și culoarea border-ului.
[cc lang=”php”]
# —— Cream marginile in jurul chartului ——
imagefilledrectangle($img,1,1,$img_width-2,$img_height-2,$border_color);
imagefilledrectangle($img,$margins,$margins,$img_width-1-$margins,$img_height-1-$margins,$background_color);
[/cc]

7.Pentru a ne defini scala trebuie să știm valoarea maximă pe care o va conține aceasta.Utilizând funcția max, aflăm acea valoare, iar apoi aflăm raportul care ne va da înălțimea unității, acesta egal cu înălțimea chart-ului pe valoarea maximă.
[cc lang=”php”]
# ——- Max value o vom folosi pentru a ne defini scala ——-
$max_value=max($values);
$ratio= $graph_height/$max_value;
[/cc]

8.Acum vom seta câte linii orizontale dorim, iar apoi vom calcula distanța dintre ele.După ce facem asta, vom desena, într-un loop cele 20 de linii cu funcția imageline.Dacă vă întrebați ce e cu variabila $y, aceasta o puteți considera un contor pentru poziția pe verticală a unei noi linii.Această valoare crește după cum observați datorită înmulțirii cu $i.Cât despre variabila $v aceasta arată valoarea numerică ce va apărea în dreptul fiecarei linii orizontale.Funcția imagestring se ocupă de inserarea acelor valori numerice.
[cc lang=”php”]
# ——– Cream scala si desenam linii orizontale ——–
$horizontal_lines=20;
$horizontal_gap=$graph_height/$horizontal_lines;

for($i=1;$i<=$horizontal_lines;$i++){ $y=$img_height - $margins - $horizontal_gap * $i ; imageline($img,$margins,$y,$img_width-$margins,$y,$line_color); $v=intval($horizontal_gap * $i /$ratio); imagestring($img,0,5,$y-5,$v,$bar_color); } [/cc] 9.Acest pas este și cel mai important.El se ocupă cu crearea barelor din chart.În primul rând va trebui să separăm informațiile din vectorul asociativ $values, cu care ne-am lovit la pasul 1, în două variabile, $key și $value.$key sunt de fapt lunile ce vor apărea pe axa Ox a chart-ului, iar $value este după cum deja intuiți valoarea corespunzătoare fiecărei luni. Următorul pas constă în aflarea coordonatelor fiecărei bare.Țineți minte că punctul (0,0) se află în colțul stânga sus.Folosim de două ori funcția imagestring, odată pentru inserarea liniilor și odată pentru colorarea barelor, iar la final folosim funcția imagefilledrectangle pentru a crea bordurile acestora.

În final, după finalizarea loop-ului salvăm imaginea $img ca test.png și vedem ce am obșinut.
[cc lang=”php”]
# ———– Desenam barele din chart ——
for($i=0;$i<$total_bars; $i++){ # ------ Extragem cheia si value din vectorul asociativ list($key,$value)=each($values); $x1= $margins + $gap + $i * ($gap+$bar_width) ; $x2= $x1 + $bar_width; $y1=$margins + $graph_height - intval($value * $ratio) ; $y2=$img_height-$margins; imagestring($img,0,$x1+3,$y1-10,$value,$bar_color); imagestring($img,0,$x1+3,$img_height-15,$key,$bar_color); imagefilledrectangle($img,$x1,$y1,$x2,$y2,$bar_color); } imagepng($img, 'test.png'); ?>
[/cc]

Rezultatul final(țin să menționez că am schimbat lungimea și lățimea pentru a vedea mai bine ce obțineți):
Chart dinamic creat doar cu PHP

Iar acum codul complet:
[cc lang=”php”]
110,
“Feb” => 130,
“Mar” => 215,
“Apr” => 81,
“May” => 310,
“Jun” => 110,
“Jul” => 190,
“Aug” => 175,
“Sep” => 390,
“Oct” => 286,
“Nov” => 150,
“Dec” => 196
);

$img_width=450;
$img_height=300;
$margins=20;

$graph_width=$img_width – $margins * 2;
$graph_height=$img_height – $margins * 2;
$img=imagecreate($img_width,$img_height);
$bar_width=20;
$total_bars=count($values);
$gap= ($graph_width- $total_bars * $bar_width ) / ($total_bars +1);

$bar_color=imagecolorallocate($img,0,64,128);
$background_color=imagecolorallocate($img,240,240,255);
$border_color=imagecolorallocate($img,200,200,200);
$line_color=imagecolorallocate($img,220,220,220);

imagefilledrectangle($img,1,1,$img_width-2,$img_height-2,$border_color);
imagefilledrectangle($img,$margins,$margins,$img_width-1-$margins,$img_height-1-$margins,$background_color);

$max_value=max($values);
$ratio= $graph_height/$max_value;

$horizontal_lines=20;
$horizontal_gap=$graph_height/$horizontal_lines;

for($i=1;$i<=$horizontal_lines;$i++){ $y=$img_height - $margins - $horizontal_gap * $i ; imageline($img,$margins,$y,$img_width-$margins,$y,$line_color); $v=intval($horizontal_gap * $i /$ratio); imagestring($img,0,5,$y-5,$v,$bar_color); } for($i=0;$i< $total_bars; $i++){ # ------ Extract key and value pair from the current pointer position list($key,$value)=each($values); $x1= $margins + $gap + $i * ($gap+$bar_width) ; $x2= $x1 + $bar_width; $y1=$margins + $graph_height - intval($value * $ratio) ; $y2=$img_height-$margins; imagestring($img,0,$x1+3,$y1-10,$value,$bar_color); imagestring($img,0,$x1+3,$img_height-15,$key,$bar_color); imagefilledrectangle($img,$x1,$y1,$x2,$y2,$bar_color); } imagepng($img, 'test.png'); ?>
[/cc]

2 Comments

  1. Salutare, am incercat scriptul “Cum să creezi un chart doar cu PHP”.
    Dar nu imi afiseaza nimic. Am gresit undeva? Am copiat intocmai scriptul tau.
    Crezi ca exista vreo varianta ca acest script sa-l folosesc cu o tabela din mysql?

    • Salut Florin. Scriptul funcționează corespunzător, dar trebuie să ții cont de următorul aspect: am folosit funcțiile image din PHP, iar asta înseamnă că rezultatul final este o imagine. Vezi folderul în care există fila PHP și caută imaginea generată test.png. Poti să îl folosești foarte ușor cu MySQL, trebuie doar să returnezi rezultatele într-un format corespunzător ca array.

Write A Comment