PHP

Графический вывод статистики

Задача ставится так - выводим данные о посещениях и просмотрах в виде диаграммы, для сравнения - еще и вчерашние данные, заодно сравниваем сегодняшние показатели со вчерашними. Вот то, что видит посетитель на странице (если мы ему это, конечно, покажем):

А вот что можем увидеть мы. Можно обновить эту страницу, посмотреть, как меняются показания счетчика на странице и статистика на диаграмме. Перейдем к самому скрипту. Вот он целиком:

И, как обычно подробно обо всем. В начале - блок функций. Первая функция получает вчерашнюю дату - это нужно, чтобы была возможность вывести на диаграмму число просмотров и посетителей вчера.

function yesterday(){
$ct=mktime(0,0,0,date('m'),date('d')-1,date("Y"));
$y=date('d-m',$ct);
return $y;}

Следующая функция читает содержимое файла статистики и возвращает это содержимое в виде массива:

function get_count($fn){
$dtf=@file_get_contents($fn);
$dtr=explode("|",$dtf);
return $dtr;}

Функция get_date() возвращает текущую дату в формате число-месяц-год, причем месяц - по-русски. То же самое можно сделать и установкой местной (российской) локали, но эта установка немного отличается в различных версиях PHP. Функцией - проще:

И, наконец, самая главная и самая громоздкая функция скрипта, та, которая строит график. Функции передается массив сегодняшних данных $dat, вчерашних $daty и переменная режима $si - она нужна для формирования комментариев. Функция рисует график и сохраняет его в виде файла, поэтому при обращении к функции первым делом изничтожаем предыдущую картинку, если такая существует:

function picture($dat,$daty,$si){
if(file_exists(date('d-m').".jpg")){unlink(date('d-m').".jpg");}

Определяем идентификатор рисунка(в скобках - его размеры) и вспомогательную переменную $linelen для вывода координатной сетки:

$img = imageCreate(600, 480);
$linelen=2;

Определяем те цвета, которые будем использовать и заполняем поле рисунка белым цветом (последняя строка этого фрагмента):

$gray = imageColorAllocate($img, 220, 220, 220);
$black = imageColorAllocate($img, 0, 0, 0);
$white = imageColorAllocate($img, 255, 255, 255);
$green = imageColorAllocate($img, 100, 255, 100);
$red = imageColorAllocate($img, 255, 0, 0);
$pink = imageColorAllocate($img, 240, 200, 240);
imageFill($img, 1, 1, $white);

Получаем значение текущего часа и число посетителей или просмотров с начала суток и по настоящее время. Число посетителей или просмотров за вчерашний день обнуляем:

$h=intval(date('H'));
$tt=array_sum($dat);
$ty=0;

Теперь предстоит просуммировать число посетителей или просмотров за прошлые сутки от начала суток до текущего часа (первая строка, процесс организован в цикл), вычислить разность между сегодняшними и вчерашними показателями и определить цвет, которым эта разность будет выводиться, рассортировать массивы вчерашней и сегодняшней статистики по возрастанию и найти в каждом массиве наибольшее значение:

for($i=0;$i<=$h;$i++){$ty=$ty+$daty[$i];}
$dif=$tt-$ty;
if($dif>=0){$col=$green;$sign="+";}else{$col=$red;$sign="";}
$dats=$dat;
sort($dats);
$datsy=$daty;
sort($datsy);
$ymax0= array_pop($dats);
$ymax1= array_pop($datsy);

Выбираем из двух максимальных значений наибольшее - оно потребуется для определения вертикального масштаба графика:

if($ymax0>$ymax1){$ymax=$ymax0;}else{$ymax=$ymax1;}

Задаем координаты углов графика:

$xtl=30;
$xbr=560;
$ybr=380;
$ytl=30;

И два массива масштабов: первый - полное число по вертикали, второй - на единицу масштаба:

$tlm=array(0,10,20,40,100,200,400,1000,2000,5000,10000,20000);
$tlk=array(1,2,4,5,10,20,50,100,200,500,1000,4000);

Определяем масштаб, который будем использовать:

for($i=0;$i<count($tlm);$i++){
if($ymax>$tlm[$i]&$ymax<=$tlm[$i+1]){$km=$i;break;}
}

и шрифт:

$mf = imageloadfont ('fontc.phpfont');

Теперь от единиц переходим к пикселям:

$mx=($xbr-$xtl)/24;
$my=(($ybr-$ytl)/$tlm[$km+1]);

Определяем текущий час и строим координатную сетку:

$h=intval(date('H'));

for($i=0;$i*$mx<$xbr-$mx;$i++){

рисуя деления горизонтальной оси черным цветом, а вспомогательную сетку (пока только вертикальную) - серым:

imageline($img,$xtl+$i*$mx,$ytl,$xtl+$i*$mx,$ybr,$gray);
imageline($img,$xtl+$i*$mx,$ybr,$xtl+$i*$mx,$ybr+$linelen,$black);

Подписываем значения делений оси Х, используя шрифт arial (он легко масштабируется до нужного размера):

imagefttext ($img, 8,0, $ytl+$i*$mx-5,$ybr+12,$black, "arial.ttf",$i);

Строим диаграмму в виде закрашенных прямоугольников, над каждым - пишем числовое значение:

if($i<=$h){imagefilledrectangle($img,$xtl+$i*$mx,$ybr-$daty[$i]*$my,$xtl+$i*$mx-10,$ybr,$pink);
imagefilledrectangle($img,$xtl+$i*$mx,$ybr-$dat[$i]*$my,$xtl+$i*$mx+10,$ybr,$green);
imagefttext ($img, 5,0, $xtl+$i*$mx-7,$ybr-$daty[$i]*$my-5,$red, "arial.ttf",$daty[$i]);
imagefttext ($img, 5,0, $xtl+$i*$mx+1,$ybr-$dat[$i]*$my-5,$black, "arial.ttf",$dat[$i]);}
}

Рисуем горизонтальную вспомогательную сетку, используя полученное раньше значение масштаба, и расставляем деления:

$n=$tlk[$km+1];
$z=$tlm[$km+1]/$n;
$ind=0;
for($i=$ybr;$i>=$ytl;$i=$i-$my*$n){
imageline($img,$xtl,$i,$xbr,$i,$gray);
imageline($img,$xtl,$i,$xtl-$linelen,$i,$black);
imagefttext ($img, 8,0, $xtl-strlen($ind*$n)*3-15, $i+3,$black, "arial.ttf",$ind*$n);
$ind=$ind+1;
}

Проводим линии координат черным цветом и рисуем два маленких вспомогательных квадрата - заготовки к подписи графика:

imageline($img,$xtl,$ytl,$xtl,$ybr,$black);
imageline($img,$xtl,$ybr,$xbr,$ybr,$black);
imagefilledrectangle($img,180,$ybr+28,190,$ybr+38,$green);
imagefilledrectangle($img,280,$ybr+28,290,$ybr+38,$pink);

Подготавливаем текст подписей с учетом режима (посетители или просмотры):

Выводим текстовые переменные, сохраняем рисунок и заканчиваем функцию:

Уф! Наконец мы у ворот Мадрида! - так, кажется у классиков... Осталось самая малость. Основной блок: получаем переменную $mode, которая определит, что будем рассматривать - посетителей или просмотры, и, если, просмотры - то считываем из файлов статистики данные за сегодняшний и вчерашний день:

$mode=$_GET['mode'];
if(!$mode)$mode=hit;

if($mode=="hit"){
$dt=get_count("stat/hit/".date('d-m').".hit");
$dty=get_count("stat/hit/".yesterday().".hit");
}

а если посетителей - то делаем то же самое, только читаем другие файлы:

if($mode=="host"){
$dt=get_count("stat/hst/".date('d-m').".hst");
$dty=get_count("stat/hst/".yesterday().".hst");
}

и передаем функции построения графика все необходимые значения:

$pic=picture($dt,$dty,$h);

Формируем меню режима вывода, переменную вывода нарисованной картинки и завершаем скрипт:

Важный момент: в меню ссылки на сам файл скрипта, его название в этом примере stat.php. Название может быть любым, расширение - только таким. Если меняем название файла, то меряем и адреса ссылок в меню. Дальше HTML-блок с вкраплениями PHP-кода:

<HTML>
<head>
</head>
<body>
<?echo $mnu."<BR><BR>".$out?>
</body>
</HTML>

Вот и все. Для просмотра статистики в некоторых обозревателях необходимо обновить страницу после выбора соответствующего пункта меню. Шрифты для работы скрипта (скачиваем) - fontc и arial. Теперь - о зашите от автоматических регистраций и спама.

1
Рейтинг@Mail.ru