Создание линейного графика на PHP с библиотекой GD2

Это часть статьи, посвященной работе с графологической библиотекой PHP, а именно с GD2.
Статья довольно распространенная и пространная. Я взял из не только кусок посвященный построению линейного графика.
Как есть скрипт у меня не заработал. В итоге я внес в тело скрипта переменные с цветами и поднял второй for в функции draw_grid на уровень первого.

Таким образом далее будет пример простого php-скрипта который генерирует линейные графики по заданным координатам.
И пример графика, который он генерирует.

<?php
header("Content-type: image/png");
function draw_axises($im_width,$im_heignt)
{
	global $im, $black, $l_grey, $x0, $y0, $maxX, $maxY;
	$x0=25.0; //начало оси координат по X
	$y0=20.0; //начало оси координат по Y
	$maxX=$im_width-$x0;  //максимальное значение оси координат по X в пикселах
	$maxY=$im_heignt-$y0; //максимальное значение оси координат по Y в пикселах
	imageline($im, $x0, $maxY, $maxX, $maxY, $black); //рисуем ось X
	imageline($im, $x0, $y0, $x0, $maxY, $black);     //рисуем ось Y
 
	//рисуем стрелку на оси X
	$xArrow[0]=$maxX-6; $xArrow[1]=$maxY-2;
	$xArrow[2]=$maxX; $xArrow[3]=$maxY;
	$xArrow[4]=$maxX-6; $xArrow[5]=$maxY+2;
	imagefilledpolygon($im, $xArrow, 3, $black);
	//рисуем стрелку на оси Y
	$yArrow[0]=$x0-2; $yArrow[1]=$y0+6;
	$yArrow[2]=$x0; $yArrow[3]=$y0;
	$yArrow[4]=$x0+2; $yArrow[5]=$y0+6;
	imagefilledpolygon($im, $yArrow, 3, $black);
}
function draw_grid($xStep,$yStep,$xCoef,$yCoef)
{
	global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY;
	$xSteps=($maxX-$x0)/$xStep-1; //определяем количество шагов по оси X
	$ySteps=($maxY-$y0)/$yStep-1; //определяем количество шагов по оси Y
 
	for($i=1;$i<$xSteps+1;$i++)   //выводим сетку по оси X
		{
		imageline($im, $x0+$xStep*$i, $y0, $x0+$xStep*$i, $maxY-1, $l_grey);
		//при необходимости выводим значения линий сетки по оси X
		ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i*$xCoef, $black);
 
		}
	for($i=1;$i<$ySteps+1;$i++)
		{
		imageline($im, $x0+1, $maxY-$yStep*$i, $maxX, $maxY-$yStep*$i, $l_grey);
		//при необходимости выводим значения линий сетки по оси Y
		ImageString($im, 1, 0, ($maxY-$yStep*$i)-3, $i*$yCoef, $black);
		} 
}
function draw_data($data_x,$data_y,$points_count,$color)
{
	global $im,$x0,$y0,$maxY,$scaleX,$scaleY;
	for($i=1;$i<$points_count;$i++)
		{
		//рисуем линейный график по точкам из массивов данных
		imageline($im, $x0+$data_x[$i-1]*$scaleX, $maxY-$data_y[$i-1]*$scaleY, $x0+$data_x[$i]*$scaleX, $maxY-$data_y[$i]*$scaleY, $color);
		}
}
	//создаем рисунок шириной 500 и высотой 400 пикселов
	$im = @ImageCreate(500, 400);
	$white = ImageColorAllocate ($im, 255, 255, 255);
	$black = ImageColorAllocate ($im, 0, 0, 0);
	$red = ImageColorAllocate ($im, 255, 0, 0);
	$green = ImageColorAllocate ($im, 0, 255, 0);
	$blue = ImageColorAllocate ($im, 0, 0, 255);
	$yellow = ImageColorAllocate ($im, 255, 255, 0);
	$magenta = ImageColorAllocate ($im, 255, 0, 255);
	$cyan = ImageColorAllocate ($im, 0, 255, 255);
	$l_grey = ImageColorAllocate ($im, 200, 200, 200);
 
	draw_axises(500,400); //рисуем оси координат
	//задаем массивы данных графиков
	$x1[0]=1; $y1[0]=1;
	$x1[1]=2; $y1[1]=4;
	$x1[2]=3; $y1[2]=8;
	$x1[3]=4; $y1[3]=16;
	$x2[0]=1.5; $y2[0]=2;
	$x2[1]=2.5; $y2[1]=3;
	$x2[2]=3.5; $y2[2]=9;
	$x2[3]=4.5; $y2[3]=17;
 
	//объединяем данные из массивов данных для вычисления масштаба
	$x=array_merge($x1,$x2);
	$y=array_merge($y1,$y2);
	//получаем максимальные значения элементов для каждого массива
	$maxXVal=max($x);
	$maxYVal=max($y);
	//вычисляем масштаб преобразования данных в координаты рабочей области
	$scaleX=($maxX-$x0)/$maxXVal;
	$scaleY=($maxY-$y0)/$maxYVal;
	//задаем шаг для координатной сетки в пикселах
	$xStep=30;
	$yStep=30;
	//рисуем координатную сетку
	draw_grid($xStep,$yStep, round($xStep/$scaleX,1), round($yStep/$scaleY,1), true);
	draw_data($x1,$y1,20,$green); //рисуем первый график
	draw_data($x2,$y2,20,$blue); //рисуем второй график
	ImagePNG($im); //выводим рисунок
	imagedestroy($im); //освобождаем занимаемую рисунком память
?>

Кстати в качестве координат констант можно подать рандомные значения:

	$x1=Array(); 
	$y1=Array(); 
	$x2=Array(); 
	$y1=Array(); 
 
	for ($i=0;$i<20;$i++) 
        {
        $x1[]=rand(0,20);
        $x2[]=rand(0,20)/2;
        $y1[]=rand(0,20);
        $y2[]=rand(0,20)/2;
	}

Тогда на графиках будут «графики» похожие на некоторые дефолтные заставки WinXP.
Пример линейного (2D) графика на PHP с рандомными значениями, описанного в статье:
Линейный (2D) график на PHP

Комментариев: 18

  • 16.11.2010 Artem:

    Спасибо скрипт полезный, но у меня выводится только надпись изображение. в чем может быть дело?

  • 02.12.2010 Максим:

    Пишет, что undefined offset в 50 строчке.

    • 02.12.2010 Кирилл:

      Привет Максим, скопипастил код исходника (без вставки рандомных значений, который под ним) в файлик, запустил — график появился. Вы точно ничего не меняли?

  • 02.12.2010 Максим:

    Скопипастил ещё раз.

    Пишет

    Notice: Undefined offset: 4 in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\chart2.php on line 50

    И так по различным значениям, всё в строчке 50.

    После этого идут каракули, скорее всего — это и есть график, только не в удобочитаемом виде.

    У меня такая же была ситуация, когда черед графиком, который рисует pChart выводились значения из проги.

    А что с моей просьбой насчёт трёхосного, поможешь?

  • 07.03.2011 Павел:

    Интересный вариант.

    Только мне не удалось вывести график, показывающий точные значения...

    Получается так чисто приблизительная оценочная динамика.

    С ходу не разобрался как начать выводить график по оси X начиная с нулевой отметки. При этом значения по оси Y слегка увеличены, подозреваю что на величину $y0=20.0

    • 07.03.2011 Кирилл:

      Насколько я помню точных значений нет из-за коэффициентов $scaleX и $scaleY, про начать с нуля по оси X не совсем понял.

  • 07.03.2011 Павел:

    меняем строки примерно так:

    (конец документа)

    draw_axises(500,400); //рисуем оси координат //задаем массивы данных графиков $x1[0]=1; $y1[0]=1.6; $x1[1]=2; $y1[1]=1.7; $x1[2]=3; $y1[2]=1.96; $x1[3]=4; $y1[3]=1.8; $x2[0]=1; $y2[0]=2.9; $x2[1]=2; $y2[1]=3.1; $x2[2]=3; $y2[2]=2.98; $x2[3]=4; $y2[3]=3.16; //объединяем данные из массивов данных для вычисления масштаба $x=array_merge($x1,$x2); $y=array_merge($y1,$y2); //получаем максимальные значения элементов для каждого массива $maxXVal=max($x); $maxYVal=max($y); //вычисляем масштаб преобразования данных в координаты рабочей области $scaleX=($maxX-$x0)/$maxXVal; $scaleY=($maxY-$y0)/$maxYVal; //задаем шаг для координатной сетки в пикселах $xStep=30; $yStep=30; //рисуем координатную сетку draw_grid($xStep,$yStep, round($xStep/$scaleX,1), round($yStep/$scaleY,1), true); draw_data($x1,$y1,4,$green); //рисуем первый график draw_data($x2,$y2,4,$blue); //рисуем второй график ImagePNG($im); //выводим рисунок imagedestroy($im); //освобождаем занимаемую рисунком память

    т.е. всего 4 значения, но почему они начинаются не с самого начала?

    • 07.03.2011 Кирилл:

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

  • 13.05.2011 Владимир:

    Пожалуйста, подскажите как сделать так чтоб график начинал рисоваться, к примеру, из точки — $x1[0]=1; $y1[0]=1; — тоесть линия начиналась не с Y=0, X=0, а из первой заданной точки.

    • 13.05.2011 Кирилл:

      Насколько я помню, сейчас так и происходит:

      //задаем массивы данных графиков $x1[0]=1; $y1[0]=1;

  • 13.05.2011 Владимир:

    вот мой результат: График

    вот значение переменных:

    $x1[0]=12; $y1[0]=85;

    $x1[1]=11; $y1[1]=75;

    $x1[2]=10; $y1[2]=80;

    $x1[3]=9; $y1[3]=70;

    $x1[4]=8; $y1[4]=65;

    $x1[5]=7; $y1[5]=60;

    $x1[6]=6; $y1[6]=50;

    $x1[7]=5; $y1[7]=60;

    $x1[8]=4; $y1[8]=50;

    $x1[9]=3; $y1[9]=40;

    $x1[10]=2; $y1[10]=45;

    $x1[11]=1; $y1[11]=35;

  • 13.05.2011 Владимир:

    Хаа... Я разгадал от чего зависит, будет ли график начинаться от нуля по (Х,У) или от первой его точки.

    Если в массивах $x1[ ],$у1[ ] этого скрипта меньше 20 значений то по любому появляется линия от (Х=0,У=0) до первой точки координат.

    Если Вам нужно поставить всего три точки и они должны начинаться где-то посередине графика то нужно внести в массивы $x1[ ],$у1[ ] еще как минимум по 17 значений, которые можно установить такие же как Ваше третье значение (все 17 значений будут в одном пикселе).

    За это, я заслужил ссылку на Студию веб дизайна.

    • 13.05.2011 Кирилл:

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

  • 21.06.2012 Роман:

    Огромное спасибо за столь подробный, а главное рабочий пример! Желаю вам и в дальнейшем успешно решать все задачи с легкостью. Очень благодарен за помощь!

  • 13.08.2012 Регина:

    Подскажите, пожалуйста, а как сделать чтобы сама ось начиналась не с 0 а , к примеру с 40


Добавление комментария:

 css.php