Dynamiczne generowanie wykresów w PHP
Napisane: Grudzień 5th, 2009 | Kategoria: php | Tagi: google, php class, programowanie | 31 Comments »W poprzednim poście opisywałem jak łatwo jest tworzyć wykresy z Google Charts API. Tworzyć jest łatwo, jednak jeśli przyjdzie nam zrobić kilka wykresów to może to być kłopotliwe. Postanowiłem napisać małą bibliotekę PHP generującą wykresy. Biblioteka korzysta z opisanego wcześniej Google Charts API. Dzięki tej bibliotece można stworzyć wykres kołowy, słupkowy i liniowy podając tylko kolejne wartości. Biblioteka LabCharts wygeneruje odpowiednie wartości dla Google Charts API a ten wygeneruje obrazek. Dodatkowo można troche „upiększyć” wykres.
Wykres kołowy
- <?php
- include_once(‚./LabChartsPie.php’);
- $LabChartsPie = new LabChartsPie();
- $LabChartsPie->setData(array(100, 200, 200, 200, 430, 760, 54));
- echo ‚<img src=”‚.$LabChartsPie->getChart().‚” />’;
- ?>
Na początek trzeba wczytać klasę dla wykresu kołowego i utworzyć jej obiekt. Teraz najważniejsza metoda – setData(). Jest to metoda dla wszystkich typów wykresów. Definiuje ona wartości potrzebne do wygenerowania wykresu, a argumentem tej metody jest właśnie tablica wartości. Nie należy się przejmować tym, że Google Charts API przyjmuje wartości tylko z określonych zakresów. LabCharts skaluje te wartości aby zmieściły się w wyznaczonym zakresie. Nie ma limitu wartości, jednak trzeba się z tym liczyć, że przy większej ilości danych wykres może być nieczytelny. W kolejnej linijce znajduje się wywołanie wykresu tj. obrazka z odpowiednim adresem. Metoda getChart() zwraca adres obrazka wygenerowany na podstawie właściwości obiektu.
Jak widać niewiele potrzeba do wygenerowania wykresu. Wykres ten można trochę „upiększyć” za pomocą kilku metod:
- setType() – typ wykresu – dla wykresu kołowego może to być wartość „p” (2D) lub „p3” (3D)
- setTitle() – tytuł wykresu – będzie to napis widoczny na górze obrazka
- setSize() – wymiary obrazka w pixelach
- setColors() – kolor lub kilka kolorów oddzielonych znakiem „|”
- setLabels() – etykiety kolejnych wartości (w takiej samej kolejności jak podane w metodzie setData()
- <?php
- //$LabChartsPie->setType(‚p3′);
- $LabChartsPie->setTitle(‚Udziały w pewnej firmie’);
- $LabChartsPie->setSize(’400×200′);
- $LabChartsPie->setColors(‚D9351C’);
- $LabChartsPie->setLabels (‚Marek|Franek|Michał|Lech|Jarosław|Grzesiek|Tomek’);
- echo ‚<img src=”‚.$LabChartsPie->getChart().‚” />’;
- ?>
A tak będzie wyglądał wykres po modyfikacjach:
Wykres słupkowy
- <?php
- include_once(‚./LabChartsBar.php’);
- $LabChartsBar = new LabChartsBar();
- $LabChartsBar->setData(array(85.8,57.5, 16.7, 5, 1.7));
- echo ‚<img src=”‚.$LabChartsBar->getChart().‚” />’;
- ?>
Tak jak w przypadku wykresu kołowego najpierw trzeba wczytać klasę wykresu słupkowego i utworzyć obiekt. Metoda setData() działa dokładnie tak samo. Wystarczy po prostu wczytać kolejne wartości.
Dodatkowe metody do wykresu słupkowego:
- setSize()
- setTitle()
- setColors() – kolory w systemie szesnastkowym odpowiadające kolejnym słupkom. Najlepiej jak liczba kolorów jest równa liczbie danych.
- setLabels() – etykiety kolejnych słupków oddzielone znakiem „|”
- setBarStyles() – metoda definiująca style wykresu słupkowego. Pierwszy argument metody ustawia szerokość słupków, a drugi odległość słupków od siebie.
- setAxis() – Metoda ustawia skale na osi y oraz co ile wartości ma być wyświetlana np. jeśli mamy wartości z przedziału 0-300 można ustawić wartość 30 i na osi y będą zaznaczone wartości: 0, 30, 60 itd.
- setGrids() – Metoda definiująca położenie poziomych lini pomocniczych na wykresie. Argument $range mówi co ile jednostek ma być linia. Zwyke jest to ta sama wartość co w metodzie setAxis(), ale można też ustawić inną wartość.
- <?php
- $LabChartsBar->setSize(’400×200′);
- $LabChartsBar->setTitle(‚Przychody w poszczególnych miesiącach’);
- //$LabChartsBar->setColors(‚D9351C|FAAC02|79D81C|2A9DF0|02AA9D’);
- $LabChartsBar->setLabels(‚Styczen|Luty|Marzec|Kwiecien|Maj’);
- $LabChartsBar->setBarStyles(40);
- $LabChartsBar->setAxis(10);
- $LabChartsBar->setGrids(10);
- echo ‚<img src=”‚.$LabChartsBar->getChart().‚” />’;
- ?>
A wykres będzie wyglądał:
Wykres liniowy:
- <?php
- include_once(‚./LabChartsLine.php’);
- $LabChartsLine = new LabChartsLine();
- $LabChartsLine->setData(array(27,25,60,31,25,39,25, 31,26,28,8,28,27,31,27,29,26,35,70,25));
- echo ‚<img src=”‚.$LabChartsLine->getChart().‚” />’;
- ?>
Inicjalizacja wygląda tak samo jak w poprzednich wykresach. Wczytanie klasy LabChartsLine, utworzenie obiektu i wczytanie danych.
Metody dla wykresu liniowego:
- setSize()
- setTitle()
- setColors()
- setAxis() – metoda działa podobnie do tej z wykresu słupkowego z tą różnicą, że przyjmuje drugi argument – nazwy etykiet na osi x, których MUSI być tyle samo co wartości zadeklarowanych w metodzie setData() oddzielonych znakiem „|”.
- setGrids() – metoda definiująca położenie poziomych i pionowych linii pomocniczych na wykresie. Argument $range mówi co ile jednostek ma być linia pozioma. Zwykle jest to ta sama wartość co w metodzie setAxis(), ale można też ustawić inną wartość. Linie pionowe są generowane automatycznie do każdej wartości na wykresie.
- <?php
- $LabChartsLine->setColors(‚D9351C’);
- $LabChartsLine->setSize(’400×250′);
- $LabChartsLine->setTitle(‚Zyski w poszczególnych miesiącach’);
- $LabChartsLine->setAxis (10, ‚Sty||Mar||Maj||Lip||Wrz||Lis||Sty||Mar||Maj||Lip|’);
- $LabChartsLine->setGrids (10);
- echo ‚<img src=”‚.$LabChartsLine->getChart().‚” />’;
- ?>
Podsumowanie
Wiele jest serwisów, które prowadzą różnego rodzaju statystyki. Profesor od statystyki powiedział, że jeśli tylko da się coś zobrazować to należy to zrobić ;) Klasę LabCharts łatwo można zintegrować z istniejącą aplikacją. Kod źródłowy, przykłady oraz dokumentację można pobrać poniżej.
UPDATE 2010-01-30 13:40
Dodana została metoda setBackground($color) dla wszytskich typów wykresów, która zmienia tło np. $LabChartsLine->setBackground(’474747′);
UPDATE 2010-05-22 22:59
Zmieniona została klasa LabChartsLine – teraz możliwe jest pokazywanie na wykresie liczb ujemnych i dodatnich





a mozna zmienic kolor tla w tych wykresach???
jak mozna zmienic kolor tla dla tych wykresow
metoda setBackround() została dodana – dzięki za info ;)
Super ! Wielkie dzieki ! Nie moglem sobie poradzic z tym samemu….
Dobra robota !
Witam, w jaki sposób możliwe jest skorzystanie zarówno z ujemnych jak i dodatnich wartości dla wykresu liniowego?
@Q
Zrobiłem już tymczasową wersję obsługującą ujemne wartości – na weekendzie poprawie wygląd kodu i uaktualnię
metoda setBackround() została dodana – dzięki za info ;)
Dziękuję :)
Zauważyłem jeszcze, że w przypadku gdy wszystkie wartości będą miały te same wartości to pojawi się błąd a powinna wyświetlić się pozioma linia.
Jeszcze jeden błąd. Tym razem błędnie wyświetlane są wartości na osi Y. Ma to miejsce, gdy każda liczba ma taką samą wartość całkowitą , np. 15.00 , 15.05, 15.30 , 15.00. Gdy następną dodamy wartość 16 to wszystko wyświetli się poprawnie.
Wyskakuje mi ten error gdy proboje wygenerowac wyskes, analogiczny wyskakuje podczas proby generowania kazdego wykresu. Jakies pomysly jak to rozwiazac??
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‚}’ in /var/www/sites/yoyo.pl/t/e/test230/LabCharts/LabChartsPie.php on line 17
@Northwood
z całą pewnością chodzi o to, że kod napisany jest w php5, a Twój serwer obsługuje tylko php4. Żeby to działało jeszcze pod php4 trzebabedzie to przepisać ale lepiej będzie zmienić wersje php na nowszą
Witam.
A gdybym chciał nanieść dwa wykresy liniowe na jeden obraz, i obie linie w różnych kolorach, jak zmodyfikować kod?
Np „zyski w poszczególnych miesiącach” jako wykres liniowy dla dwóch pracowników.
Pozdrawiam i czekam na pomoc.
Witam,
Mam problem ponieważ chcę stworzyć wykres słupkowy za pomocą Twojego skryptu, ale gdy korzystam z setGrids i setAxis wyskakuje komunikat o błędzie: „Warning: Wrong parameter count for max() in /home/fantazja/domains/fantazjada.pl/public_html/rejestracja/admin/charts/LabChartsBar.php on line 39″ i w linii 56. Nie mogę też ustawić większej wysokości wykresu niż 300, ponieważ inaczej wykres się nie wyświetla.
Pozdrawiam, Osa
@Osa prawdopodobnie chodzi o to że metoda setData powinna być najpierw wywołana z tablicą wartości. Jak coś to podaj kawałek kodu.
Co do wielkości to tak jak pisałem w poprzednim wpisie wymiary obrazka nie mogą przekraczać 300 tys pixeli łącznie
Mam pytanie czy jest możliwe zapisanie tego obrazka na serwer za pomocą php?
@Ciekawy – pewnie.. można skorzystać z funkcji imagecreatefrompng, w argumencie przekazać url i później zapisać przez imagepng ;)
Skopiowałem kod z wykresu Pie. I o dziwo w wykresie Pie nie wyświetla mi opisów, tylko sam wykres ! W słupkowym wszystko działa jak należy. Dziwne bo przekazywane wartości w zapytaniu są poprawne. Nie bardzo wiem gdzie może być problem. Jakieś sugestie ?
What an awesome way to explain this-now I know eveyrnthig!
Your answer shows real itnellgience.
jest błąd jeśli wszystkie wartości są takie same to skrypt się wywala z powodu braku pamięci ;)
Witam, na jakiej licencji udostępniasz powyższą klasę? Można z niej korzystać komercyjnie?
@Barcelona – jeżeli tylko uważasz że klasy są przydatne – korzystaj ;) Dual licensed under the MIT and GPL licenses.
super! dziękuję!
Q napisał(a) 16:29, Czerwiec 7th, 2010:
Dziękuję :)
Zauważyłem jeszcze, że w przypadku gdy wszystkie wartości będą miały te same wartości to pojawi się błąd a powinna wyświetlić się pozioma linia.
Witam Admina, niestety ten problem nadal wystepuje, np robie roczne statystyki dla roku, w ktorym jeszcze zakupow nie bylo to wyskakuje blad, zamiast jednej poziomej linii
bardzo fajnie, szkoda, że po wywołaniu kodu:
$LabChartsLine->setData(array($tablica));
skrypt nie działa
@p wydaje mi się, że jeśli już masz $tablica typu tablicowego nie musisz pisać Array();
Od razu: $LabChartsLine->setData($tablica);
Witam.
A gdybym chciał nanieść dwa wykresy liniowe na jeden obraz, i obie linie w różnych kolorach, jak zmodyfikować kod?
Np „zyski w poszczególnych miesiącach” jako wykres liniowy dla dwóch pracowników.
Pozdrawiam i czekam na pomoc.
Mam pytanie czy jest możliwość napisania skryptu który zapiszę na serwerze wykres jako np. wykres.jpg ?
@Z
W tej chwili nie jest to możliwe. Wydaje mi się, że musiałbyś dziedziczyć po klasie i dodać metodę, która odpowiednio sterowałaby parametrami przekazanymi jako źródło obrazka. Zobacz w dokumentacji Google Charts.
@Paweł
Jak wyżej napisałem w komentarzu – można skorzystać z funkcji imagecreatefrompng, w argumencie przekazać url i później zapisać przez imagepng
Wyłapałem jeden dość interesujący błąd – ilość kolumn deklarowanych w setAxis deklaruje również co ile będą wyświetlane wartości na osi y.
Np. ustawiam sobie 11 kolumn, czyli wartości będę mieć 0,11,22,33,44… ;)
Co trzeba zmienić w kodzie w „wykresie liniowym” aby było możliwość pobrania danych z bazy sql. I te dane pokazało w formie wykresu.
Pozdrawiam