Onego czasu próbowałem znaleźć coś co ułatwiłoby mi rysowanie prostych wykresów w PHP’ie inaczej niż z palca w GD. Kumpel polecił mi JPGraph .
JPGraph to świetna sprawa, do generowania statystyk jak chociażby na mojej stronie, ale biblioteka potrafi dużo więcej…
Załóżmy, że ze stronki zbieramy do bazy takie rzeczy jak: datę, adres IP, ilość połączeń z tego adresu. Prosta tabela (przykład w Postgre SQL’u):
CREATE TABLE wizyty
(
pid serial NOT NULL,
"data" date NOT NULL DEFAULT ('now'::text)::date,
odslony integer NOT NULL DEFAULT 1,
CONSTRAINT visits_pkey PRIMARY KEY (id)
);
Dane z takiej tabeli można łatwo wyciągnąć jednym select’em:
SELECT date_part('day', "data") AS x, sum(odslony) AS y
FROM wizyty
WHERE date > ('today'::date - '30 days'::interval)
GROUP BY "data"
ORDER BY "data"
LIMIT 30
Powyższe zapytanie wyciągnie nam z kolumny z datą tylko dzień miesiąca, który posłuży za etykietę (oś X) oraz sumę odsłon z danego dnia (oś Y), posortowane według daty i tylko z ostatnich 30 dni.
W zależności od sposobu dostępu i pobierania wyników, trzeba je ładnie zapisać w dwóch tablicach. Ja to robię w prostej pętli:
foreach ($query->result() as $row) {
$x[] = $row->x;
$y[] = $row->y;
}
Mając dane została zabawa z ustawieniem oczekiwanych opcji wykresu:
/* bez tego ani rusz */
include_once 'jpgraph/jpgraph.php';
include_once 'jpgraph/jpgraph_bar.php';
/* szerokość */
$width = 400;
/* wysokość */
$height = 300;
$graph = new Graph($width, $height);
/* oś X tekst, oś Y wartości całkowite */
$graph->SetScale("textint");
/* kolorowa ramka */
$graph->SetFrame(true, '#222222');
$graph->SetMarginColor('#222222');
/* tytuł wykresu, trochę konfiguracji fontów i kolorów */
$graph->title->Set('Sumaryczna liczba odsłon');
$graph->title->SetFont(FF_VERDANA,FS_BOLD,10);
$graph->title->SetColor('#999999');
/* podobnież jak powyżej dla osi X */
$graph->xaxis->SetFont(FF_VERDANA,FS_NORMAL,8);
$graph->xaxis->SetColor('#999999');
$graph->yaxis->SetFont(FF_VERDANA,FS_NORMAL,8);
$graph->yaxis->SetColor('#999999');
/* dodatkowe ozdobniki ;) */
$graph->yscale->ticks->SupressZeroLabel(false);
$graph->yscale->ticks->SetColor('#999999');
$graph->xaxis->SetTickLabels($x);
/* genrujemy właściwy wykres, w tym przypadku słupkowy */
$bplot = new BarPlot($y);
$bplot->SetWidth(0.6);
$bplot->SetFillColor('#D01A71@0.25');
$bplot->SetColor('gray');
/* dodajemy wykres do obiektu $graph (który to może pomieścić
i wyświetlić wiele wykresów, co z resztą pokazane jest poniżej) */
$graph->Add($bplot);
/* teraz wykres liniowy */
$lplot = new LinePlot($y);
/* z wypełnieniem pod wykresem */
$lplot->SetFillColor('skyblue@0.5');
$lplot->SetColor('navy@0.7');
$lplot->SetBarCenter();
/* typ znacznika na łącznikach pomiędzy kolejnymi słupkami */
$lplot->mark->SetType(MARK_SQUARE);
$lplot->mark->SetColor('blue@0.5');
$lplot->mark->SetFillColor('lightblue');
$lplot->mark->SetSize(6);
/* wrzucamy kolejny wykres do obrazu */
$graph->Add($lplot);
/* a teraz magia... */
$graph->Stroke();
Co to robi… Ano dokładnie taki wykres jak ten poniżej:

Co prawda ten wykres nie odpowiada w 100% podanemu źródłu. To statystyka z mojej strony, która niebieską linią zaznacza volumen pobranych danych - przykład jest nieco uproszczony.
Na pierwszy rzut oka powyższy skrypt wydaje się dość długi i jest tam dużo nie do końca jasnych opcji, ale najfajniejsze jest to, że tak na prawdę nie trzeba się tego uczyć. Biblioteka domyślnie dostarczana jest z masą przykładów. Wystarczy wybrać wykres podobny do tego, który sami chcemy zrobić - skopiować większość kodu. Znaleźć inne wykresy, których cechy chcemy powielić i po kilku próbach skleimy takiego Frankenstein’a jakiego świat nie widział wcześniej ;-D
Mój wykres akurat ma trochę zmieniony kolor tła ramki i fonty, tak aby lepiej wkomponował się w moją stronę - reszta bazuje na dwóch przykładach z dokumentacji. Na zrobienie pierwszego wykresu z wykorzystaniem JPGraph potrzebowałem ok. godziny. Teraz wystarcza mi 10 minut 😃
](https://gagor.pro/generic-cover.webp)