16 Май 2008

Круговая диаграма на PHP с использованием GD

posted in PHP |

Часто данные приходится отображать в наглядном для пользователя виде, а именно с помощью диаграм. Одним из видов диаграм является круговая, где за каждый элемент отвечает свой сектор.
Напишем функцию, которая стоит такую диаграму используя библиотеку GD для PHP. В качестве входных параметров ассоциативный массив $ar ($ar[‘имя’]=данные;) и $title для заголовка диаграмы.

Сначала создадим саму функцию в piegraph.php:

<?

function GraphPie($ar,$title) {
// размеры диаграмы
$diagramWidth=600;
$diagramHeight=370;
$legendOffset=50;

// отсортируем по убыванию, сохраняя ключи
arsort($ar);

// наш скрипт будет объединять в один сектор все элементы, которые по отдельности не превыщают 1%
// Суммируем (можете использовать также функцию array_sum() )
$sum=0;
foreach ($ar as $name => $val) {
    $sum+=$val;
}

//узнаем сколько меньше 1%
$sumless1=0; // и их сумму
$countless1=$countgreater1=0; 
foreach ($ar as $name => $val) {
    if ($val/$sum<0.01)
     { $sumless1+=$val;
       $countless1++;
       }
       else $countgreater1++;
}

 // создаем ихображение
$image = imageCreate($diagramWidth, $diagramHeight);

// цвета для фона и текста
$colorBackgr = imageColorAllocate($image, 220,220,220);
$colorText = imageColorAllocate($image, 0, 0, 0);
// цвета для наших секторов
$colors&#91;0&#93; = imagecolorallocate($image, 255, 0, 0);
$colors&#91;1&#93; = imagecolorallocate($image, 0, 151, 0);
$colors&#91;2&#93; = imagecolorallocate($image, 0, 0, 255);
$colors&#91;3&#93; = imagecolorallocate($image, 255, 255, 0);
$colors&#91;4&#93; = imagecolorallocate($image, 0, 255, 255);
$colors&#91;5&#93; = imagecolorallocate($image, 204, 0, 206);
$colors&#91;6&#93; = imagecolorallocate($image, 155, 105, 27);
$colors&#91;7&#93; = imagecolorallocate($image, 134,188,134);
$colors&#91;8&#93; = imagecolorallocate($image, 255,189,62);
$colors&#91;9&#93; = imagecolorallocate($image, 168,168,255);
$colors&#91;10&#93; = imagecolorallocate($image, 219,255,111);
$colors&#91;11&#93; = imagecolorallocate($image, 255,201,200);
$colors&#91;12&#93; = imagecolorallocate($image, 0,169,168);
$colors&#91;13&#93; = imagecolorallocate($image, 248,255,213);
$colors&#91;14&#93; = imagecolorallocate($image, 255,106,105);
$colors&#91;15&#93; = imagecolorallocate($image, 133,133,133);
$colors&#91;16&#93; = imagecolorallocate($image, 194,255,255);
$colors&#91;17&#93; = imagecolorallocate($image, 90,9,255);
$colors&#91;18&#93; = imagecolorallocate($image, 109,255,110);
$colors&#91;19&#93; = imagecolorallocate($image, 255,133,22);

// заполняем изображение цветом фона
imageFilledRectangle($image, 0, 0, $diagramWidth - 1, $diagramHeight - 1, $colorBackgr);

// начальный угол для сектора
$startAngle=0;
$perc=360/$sum; // соотвествие градусов 1 проценту
$i=0; // для вывода порядка элемента в легенде и выбора цвета
foreach ($ar as $name => $val) {
// если текущий элемент больше 1%
  if ($val/$sum<0.01) // выходим из цикла
	break;

// конечный угол сектора
  $endAngle=$startAngle+$val*$perc;
// сколько % у нашего элемента
  $percents=round(100*($val/$sum),2);
  // цветной квадратик в легенде
  imagefilledrectangle($image,285,$legendOffset+$i*15-9,295,$legendOffset+$i*15,$colors&#91;$i&#93;);
  // текст легенды
  imagettftext ($image, 10, 0, 300, $legendOffset+$i*15, $colorText, "arialcyr.ttf", ($i+1).". ".$name." (".$percents." %)");
  // сектор
  imagefilledarc($image, $diagramWidth/2-150, $diagramHeight/2, 200, 200, $startAngle, $endAngle, $colors&#91;$i++&#93;, IMG_ARC_PIE);
  // следующий сектор в качестве начального угла будет использовать конечный угол текущего
  $startAngle=$endAngle;
}

// если есть элементы менее 1%
if ($countless1) {
  $endAngle=360;
  $percents=round(100*($sumless1/$sum),2);
  // цветной квадратик в легенде
  imagefilledrectangle($image,285,$legendOffset+$i*15-9,295,$legendOffset+$i*15,$colors&#91;$i&#93;);
  // текст в легенде
  imagettftext ($image, 10, 0, 300, $legendOffset+$i*15, $colorText, "arialcyr.ttf", ($i+1).". "."Other"." (".$percents." %)");
  // сектор "Other"
  imagefilledarc($image, $diagramWidth/2-150, $diagramHeight/2, 200, 200, $startAngle, $endAngle, $colors&#91;$i++&#93;, IMG_ARC_PIE);
}


  // Заголовок диаграмы
 imagettftext ($image, 14, 0, 10, 20, $colorText, "arialcyr.ttf", $title);
  // некая копирайт информация
 imagettftext ($image, 10, 0, 10, $diagramHeight-10, $colorText, "arialcyr.ttf", "www.aurorascorpio.com");

// выводим картинку
header("Content-type:  image/png");
imagepng($image);
imageInterlace($image, 1);
imageColorTransparent($image, $colorBackgr);

return;
}
?>

Теперь протестируем скрипт. Создадим diagrampietest.php с данными о использовании веб-браузеров:

<?
include("piegraph.php"); // скрипт с функцией GraphPie
// наш массив данных
$gr_val=array("Firefox"=>80,"Opera"=>50,"IE"=>150);
$gr_val["Netscape"]=2;
$gr_val["Konqueror"]=1;
$gr_val["Mozilla"]=3;
$gr_val["Safari"]=20;
// постоение диаграмы
GraphPie($gr_val,"Browsers");
?>

Вы увидите следующую диаграму:

Browsers - Pie Diagram

Демо

У нас 5 комментариев на запись “Круговая диаграма на PHP с использованием GD”

Почему бы Вам не высказать своем мнение! Позвольте нам узнать, что Вы думаете...

  1. 1 On 05.02.2009, yAnTar said:

    Сьогодні треба було в проекті генерувати кругові діаграми, згадав, що ти писав скрипт, взяв його.
    Є тільки одна недоробка — пов’язана з округленням в PHP — буває так, що сума всіх процентів не дорівнює 100%.
    Я поправив так, щоб завжди була 100 (процент останнього елемента дорівнює різниці 100 і сумі попередніх). Поставив замість

    $percents = round(100 * ($val / $sum), 2);

    такий кусок
    $percents = (count($ar) == ++$j) ? (100 — $temp_sum) : (round(100 * ($val / $sum), 2));
    $temp_sum += $percents;
    і перед циклом
    $j = $temp_sum = 0;

  2. 2 On 05.02.2009, yAnTar said:

    І ще, забув написати, добре якщо би можна було скачати файл piegraph.php, а то потрібно код копіювати через буфер, а він копіюється з номерами рядків(їх треба вилучати через рег.вирази у PHP-редакторі).

  3. 3 On 05.02.2009, scorpio said:

    Кликаешь на «Plain Text» и не надо номера строк удалять 😉

    Рад, что тебе пригодился скрипт 🙂

  4. 4 On 29.06.2009, gosha said:

    А не проще ли использовать jgraph? один раз прикрутить и строй какие хочешь графики и диаграммы 🙂

  5. 5 On 29.06.2009, scorpio said:

    ну да, проще. и проще нанять прогера, чем самому че-нить писать 🙂

Оставить комментарий