code-laboratory.com jest blogiem poświęconym w całości programowaniu oraz technologiom internetowym. Znajdziesz tutaj kod, gotowy do wykorzystania w twoich projektach.

Dynamiczne generowanie wykresów w PHP

Napisane: Grudzień 5th, 2009 | Kategoria: php | Tagi: , , | 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
  1. <?php
  2. include_once(‚./LabChartsPie.php’);
  3. $LabChartsPie = new LabChartsPie();
  4. $LabChartsPie->setData(array(100, 200, 200, 200, 430, 760, 54));
  5. echo ‚<img src=”‚.$LabChartsPie->getChart().‚” />’;
  6. ?>

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()
  1. <?php
  2. //$LabChartsPie->setType(‚p3′);
  3. $LabChartsPie->setTitle(‚Udziały w pewnej firmie’);
  4. $LabChartsPie->setSize(’400×200′);
  5. $LabChartsPie->setColors(‚D9351C’);
  6. $LabChartsPie->setLabels (‚Marek|Franek|Michał|Lech|Jarosław|Grzesiek|Tomek’);
  7. echo ‚<img src=”‚.$LabChartsPie->getChart().‚” />’;
  8. ?>

A tak będzie wyglądał wykres po modyfikacjach:

Wykres słupkowy
  1. <?php
  2. include_once(‚./LabChartsBar.php’);
  3. $LabChartsBar = new LabChartsBar();
  4. $LabChartsBar->setData(array(85.8,57.5, 16.7, 5, 1.7));
  5. echo ‚<img src=”‚.$LabChartsBar->getChart().‚” />’;
  6. ?>

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ść.
  1. <?php
  2. $LabChartsBar->setSize(’400×200′);
  3. $LabChartsBar->setTitle(‚Przychody w poszczególnych miesiącach’);
  4. //$LabChartsBar->setColors(‚D9351C|FAAC02|79D81C|2A9DF0|02AA9D’);
  5. $LabChartsBar->setLabels(‚Styczen|Luty|Marzec|Kwiecien|Maj’);
  6. $LabChartsBar->setBarStyles(40);
  7. $LabChartsBar->setAxis(10);
  8. $LabChartsBar->setGrids(10);
  9. echo ‚<img src=”‚.$LabChartsBar->getChart().‚” />’;
  10. ?>

A wykres będzie wyglądał:

Wykres liniowy:
  1. <?php
  2. include_once(‚./LabChartsLine.php’);
  3. $LabChartsLine = new LabChartsLine();
  4. $LabChartsLine->setData(array(27,25,60,31,25,39,25, 31,26,28,8,28,27,31,27,29,26,35,70,25));
  5. echo ‚<img src=”‚.$LabChartsLine->getChart().‚” />’;
  6. ?>

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.
  1. <?php
  2. $LabChartsLine->setColors(‚D9351C’);
  3. $LabChartsLine->setSize(’400×250′);
  4. $LabChartsLine->setTitle(‚Zyski w poszczególnych miesiącach’);
  5. $LabChartsLine->setAxis (10, ‚Sty||Mar||Maj||Lip||Wrz||Lis||Sty||Mar||Maj||Lip|’);
  6. $LabChartsLine->setGrids (10);
  7. echo ‚<img src=”‚.$LabChartsLine->getChart().‚” />’;
  8. ?>

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


31 komentarze na “Dynamiczne generowanie wykresów w PHP”

  1. 1 nikt napisał(a) 16:52, Styczeń 29th, 2010:

    a mozna zmienic kolor tla w tych wykresach???

  2. 2 fragentek napisał(a) 17:54, Styczeń 29th, 2010:

    jak mozna zmienic kolor tla dla tych wykresow

  3. 3 admin napisał(a) 13:13, Styczeń 30th, 2010:

    metoda setBackround() została dodana – dzięki za info ;)

  4. 4 fragentek napisał(a) 14:07, Styczeń 30th, 2010:

    Super ! Wielkie dzieki ! Nie moglem sobie poradzic z tym samemu….
    Dobra robota !

  5. 5 Q napisał(a) 8:23, Maj 21st, 2010:

    Witam, w jaki sposób możliwe jest skorzystanie zarówno z ujemnych jak i dodatnich wartości dla wykresu liniowego?

  6. 6 admin napisał(a) 23:57, Maj 21st, 2010:

    @Q
    Zrobiłem już tymczasową wersję obsługującą ujemne wartości – na weekendzie poprawie wygląd kodu i uaktualnię

  7. 7 Steve napisał(a) 19:51, Maj 28th, 2010:

    metoda setBackround() została dodana – dzięki za info ;)

  8. 8 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.

  9. 9 Q napisał(a) 16:40, Czerwiec 7th, 2010:

    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.

  10. 10 Northwood napisał(a) 22:59, Czerwiec 13th, 2010:

    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

  11. 11 admin napisał(a) 19:22, Czerwiec 14th, 2010:

    @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ą

  12. 12 miccom napisał(a) 12:47, Lipiec 26th, 2010:

    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.

  13. 13 Osa napisał(a) 19:17, Czerwiec 1st, 2011:

    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

  14. 14 admin napisał(a) 22:46, Czerwiec 1st, 2011:

    @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

  15. 15 Ciekawy napisał(a) 11:31, Październik 25th, 2011:

    Mam pytanie czy jest możliwe zapisanie tego obrazka na serwer za pomocą php?

  16. 16 admin napisał(a) 19:27, Październik 26th, 2011:

    @Ciekawy – pewnie.. można skorzystać z funkcji imagecreatefrompng, w argumencie przekazać url i później zapisać przez imagepng ;)

  17. 17 Adamski napisał(a) 21:10, Listopad 18th, 2011:

    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 ?

  18. 18 Rocky napisał(a) 18:22, Grudzień 22nd, 2011:

    What an awesome way to explain this-now I know eveyrnthig!

  19. 19 Audel napisał(a) 4:57, Grudzień 24th, 2011:

    Your answer shows real itnellgience.

  20. 20 matiszon napisał(a) 22:01, Marzec 13th, 2012:

    jest błąd jeśli wszystkie wartości są takie same to skrypt się wywala z powodu braku pamięci ;)

  21. 21 Barcelona napisał(a) 14:51, Kwiecień 13th, 2012:

    Witam, na jakiej licencji udostępniasz powyższą klasę? Można z niej korzystać komercyjnie?

  22. 22 admin napisał(a) 22:45, Kwiecień 16th, 2012:

    @Barcelona – jeżeli tylko uważasz że klasy są przydatne – korzystaj ;) Dual licensed under the MIT and GPL licenses.

  23. 23 amon napisał(a) 22:49, Czerwiec 19th, 2012:

    super! dziękuję!

  24. 24 lukaszw napisał(a) 11:46, Lipiec 3rd, 2012:

    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

  25. 25 p napisał(a) 13:39, Lipiec 12th, 2012:

    bardzo fajnie, szkoda, że po wywołaniu kodu:

    $LabChartsLine->setData(array($tablica));

    skrypt nie działa

  26. 26 dekiel napisał(a) 22:34, Lipiec 18th, 2012:

    @p wydaje mi się, że jeśli już masz $tablica typu tablicowego nie musisz pisać Array();
    Od razu: $LabChartsLine->setData($tablica);

  27. 27 Z napisał(a) 12:36, Lipiec 25th, 2012:

    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.

  28. 28 Paweł napisał(a) 13:06, Sierpień 9th, 2012:

    Mam pytanie czy jest możliwość napisania skryptu który zapiszę na serwerze wykres jako np. wykres.jpg ?

  29. 29 admin napisał(a) 21:43, Sierpień 9th, 2012:

    @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

  30. 30 Z napisał(a) 9:08, Sierpień 21st, 2012:

    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… ;)

  31. 31 Spaidergall napisał(a) 0:32, Październik 15th, 2012:

    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

Zostaw komentarz

  • Anti-Spam Quiz: