Как правильно написать динамический график на php. Работаем с диаграммами. Что такое связные диаграммы

Всякому web-программисту приходится работать с изображениями – чисто текстовых сайтов в интернете немного. Самый простой способ поместить на страницу картинку – сохранить ее в файле и поставить в HTML-файле соответствующий тэг. Один из недостатков этого способа очевиден: картинки, которые лежат в файле никак не меняются, чтобы пользователь увидел другое изображение, вебмастеру нужно открыть графический редактор, внести измения и сохранить их. В этой статье я расскажу о создании динамических изображений с помощью языка web-программирования PHP.

Для начала – несколько слов для тех, кто не знаком с PHP. Это – язык сценариев, выполняющихся на стороне сервера для создания динамических web-страниц. Программа на PHP, подобно тексту на JavaScript, VBScript или ASP, вставляется в HTML-файл или сохраняется в отдельном файле с соответствующим расширением. Начало и конец программы отмечаются специальными тэгами . Текст вне этих скобок PHP не интерпретирует, он передается web-браузеру «как есть». Синтаксис PHP довольно подробно описан в руководстве, которое входит в комплект поставки (его также можно взять на сайте http://www.php.net).
Принцип работы с изображениями такой: PHP-программа (а точнее PHP-интерпретатор, работающий на стороне сервера) создает картинку «на лету» и передает ее браузеру в нужном графическом формате.
Для того чтобы воспользоваться возможностями PHP по работе с изображениями, необходимо установить в системе библиотеку GD. Если вы работаете с Linux, то эта библиотека уже должна быть установлена. Если нет – ее можно найти по адресу http://www.boutell.com/gd. Если вы работаете с Windows, то лучше всего посетить http://php.weblogs.com/easywindows. Здесь можно скачать библиотеку php_gd, которая позволит вам насладиться всеми прелестями работы с графикой на PHP. Если вы планируете использовать в своих изображениях шрифты TrueType, вам понадобится библиотека FreeType (http://www.freetype.org).
Несколько слов о поддерживаемых библиотекой GD графических форматах. Версии старше 1.6 поддерживают форматы GIF и JPEG. Более новые версии позволяют работать с JPEG и PNG. Начиная с версии 1.6 формат GIF в GD не поддерживается. Это связанно с тем, что всеми правами на алгоритм LZW-компрессии, использующийся в этом формате, обладает компания Unisys.

Первые шаги

Итак, система настроена, все необходимые библиотеки установлены. Для начала создадим какое-нибудь простое изображение:

Сохраните текст в файле с расширением.php и просмотрите его с помощью браузера. Если вы все сделали правильно, то вы увидите то, что показано на рисунке 1.

рисунок 1

Рассмотрим код нашего скрипта более подробно. В первой строчке скрипт сообщает браузеру информацию о типе передаваемых данных с помощью HTTP-заголовка. В нашем примере используется предопределенный тип «image/gif», который означает, что далее последует изображение в формате GIF. Передавать браузеру соответствующий заголовок необходимо всегда. Для форматов JPEG и PNG первая строчка выглядела иначе:

Header(“Content-Type: image/jpeg”);
Header(“Content-Type: image/png”);

Обратите внимание, что заголовок “Content-Type” передается для каждой страницы только один раз, поэтому PHP-код для генерации изображения необходимо помещать в отдельный файл. Кстати, размещение динамической графики вместе с HTML-кодом возможно только при использовании механизма SSI (Server Side Includes), о чем мы поговорим чуть позже.
Создание графики в PHP состоит из четыре этапов:

    создание дескриптора изображения;

    регистрация используемых цветов;

    рисование с использованием предопределенных функций;

    и финальная стадия – создание изображения и передача его браузеру.

В нашем примере первый этап выглядит так:

$image = ImageCreate(500, 75);

Здесь функция ImageCreate() создает дескриптор изображения и присваивается его переменной $image. Функция вызывается с двумя параметрами – высотой и шириной изображения. По умолчанию изображение заливается черным цветом. Следующий этап – цвета:

Все используемые в изображении цвета необходимо регистрировать. Для этого используется функция ImageColorAllocate(); ее параметры – дескриптор изображения и RGB-кодировка цвета. Каждый цвет ставится в соответствие переменной, в дальнейшем эта переменная передается функциям рисования.
Вряд ли стоит перечислять все функции рисования. Скажу лишь, что их немало: вы можете «заливать» изображения цветом, рисовать различные фигуры, делать рисунок прозрачным и т.д. Рассмотрим некоторые из них на практике, а об остальных вы сможете узнать из документации.
В нашем первом примере мы «заливаем» изображение синим цветом с помощью функции

ImageFill:
ImageFill($image, 1, 1, $blue);

Второй и третий параметр – координаты начала заливки. Начало координат располагается в левом верхнем углу изображения. Таким образом, координаты (500, 75) определяют правый нижний угол изображения из первого примера.
Теперь следует передать готовый рисунок браузеру. Это делает функция ImageGIF(), ее единственный параметр – дескриптор изображения. Для форматов JPEG и PNG применяйте функции ImageJPEG() и ImagePNG() соответственно. Для освобождения памяти, выделенной под рисунок, в конце скрипта надо вызвать функцию ImageDestroy().

Использование текста в рисунках

Рассмотрим еще одну возможность: попробуем что-нибудь написать на рисунке. Я приведу небольшой пример, а потом поясню механизм работы с текстом:

Результат выполнения скрипта показан на рисунке 2.

рисунок 2

Собственно выводом текста занимается функция itrings(). Ее параметры – дескриптор изображения, номер шрифта, координаты точки вывода изображения, строка текста и цвет. Можно использовать один из пяти предопределенных шрифтов фиксированного размера. Они нумеруются от 1 (самый маленький) до 5 (самый большой).
В следующем примере начинается самое интересное: изображение создается динамически на основе вводимых пользователем данных. Создадим простой HTML-файл с формой (рисунок 3).

рисунок 3

Вот его код:




Введите Ваше имя:




А теперь создадим такой файл example3.php:

Изображение будет содержать введенный текст (рисунок 4).

рисунок 4

Скажу пару слов и о других функциях из библиотеки GD, предназначенных для работы с текстом. itringUp() выводит текст вертикально; ImageChar() и ImageCharUp() выводят один символ; ImageFontHeight() и ImageFontWidth() возвращают высоту и ширину шрифта. Последние две функции используются в следующем примере, в котором строка текста подчеркивается линией (функция ImageLine рисует линии по заданным координатам):

Результат работы скрипта показан на рисунке 5.

рисунок 5

Что еще можно рисовать?

Естественно, кроме линий с помощью GD можно рисовать и другие фигуры. В следующем примере мы воспользуемся функцией ImageFilledRectangle() для того, чтобы вывести в окне браузера французский флаг. Функция предназначена для рисования заполненных определенным цветом прямоугольников. Для начала «зальем» весь рисунок белым цветом, а затем нарисуем красный и синий прямоугольники:

На рисунке 6 можно видеть результат наших трудов.

рисунок 6

PHP позволяет рисовать и другие типы многоугольников. Для этого имеется функция ImagePolygon(). Следующий пример выводит на экран пятиугольник. В качестве параметров (кроме дескриптора изображения и цвета линии) этой функции передается следующая информация: количество вершин (в нашем случае – пять) и массив координат точек, являющихся вершинами. Результат работы скрипта представлен на рисунке 7.

рисунок 7

В этом же скрипте используется еще одна функция, не упоминавшаяся ранее – ImageFillToBorder(). Она используется для заливки области, ограниченной определенным цветом (в нашем случае это синяя линия многоугольника).
Функция ImageArc() умеет рисовать дуги и окружности. Приведу небольшой пример (см. рисунок 8):

рисунок 8

Меняя значения переменных $width и $height, можно рисовать овалы, а меняя углы – добиться отображения различного рода дуг.

Использование готовых изображений

Библиотека GD позволяет не только рисовать картинки, но и пользоваться уже готовыми. Рассмотрим вполне реальную ситуацию: штатный дизайнер вашей фирмы разработал внешний вид кнопок для некоторого сайта, а вам надо поместить на странице несколько одинаковых по дизайну кнопок и подписи к ним.
В состав библиотеки GD входят такие функции, как ImageCreateFromGIF(), ImageCreateFromJPEG() и ImageCreateFromPNG(). Они помогут в тех случаях, когда надо создать новое изображение на основе уже существующего. Пусть у нас имеется файл button.gif (рисунок 9), который содержит гениальный дизайн кнопки для сайта. Ниже приводится PHP-код, который делает готовые кнопки на основе этого файла. Обратите внимание на то, как размеры кнопки, шрифта, и строк текста используются для вычисления координат размещения заголовков. Здесь в качестве подписи к кнопке берется значение переменной $caption, которая передается в скрипт извне:

рисунок 9

Функции iX() и iY() возвращают, соответственно, ширину и высоту изображения. Также существует функция Getiize(), с помощью которой можно определить размеры и тип изображения.
Сам по себе приведенный выше скрипт большой практической ценности не имеет, но его можно использовать в любой HTML-странице посредством SSI или так, как описано в следующем коде:


После того как мы нарисовали средствами GD нашу картинку, ее необходимо вывести в браузер. Для этого в зависимости от формата рисунка необходимо вызвать одну из функций: imagepng(int im [, string filename]) или imagejpeg (int im [, string filename [, int quality]]), - передав ей в качестве параметра идентификатор картинки. Если кроме идентификатора области рисования указать имя файла, то изображение будет сохранено на диске под этим именем). После того как мы завершили работу с рисунком, необходимо освободить занимаемую им память. Для этого служит функция imagedestroy (int im). Рассмотрим работу с этими функциями на примере.

Для начала создадим шаблоны заголовка и "подвала" HTML-документа, которые будем использовать для того, чтобы не засорять PHP-код конструкциями HTML:





Работа с графикой в php


Допустим, мы хотим создать графический счетчик посещений и у нас есть файл-заготовка, в который нужно "дописать" количества посещений. Он может выглядеть так.

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

Скрипт для отображения счетчика может быть таким:

Что мы изменили?
  • Теперь поскольку у нас в наличии имеется несколько видов диаграмм, через $_GET нам будет передаваться тип диаграммы. То же самое и с $Month и $Hour и $Year;
  • Далее мы создаём массив $MonthNames, который будет содержать названия месяцев. Поскольку массив начинается с нуля, то первый элемент равен null;
  • Теперь в зависимости от типа переменные $Query, $ResultArray, $ChartHeading и $XAsixName присваиваются в switch. Если $Type не установлен, то по умолчанию будут отображаться месяца;
  • Далее мы подключаемся к базе, выполняем запрос, копим результат в массив и генерируем первую часть xml файла;
  • Далее генерируем тело XML файла. Поскольку тело зависит от типа диаграммы, мы снова используем switch;
  • Месяца: всё то же самое за исключением ссылки. Теперь она будет такой: newchart-xmlurl-get-data.php; newchart - говорит о том, что мы создаём новую диаграмму, xmlurl - по какому адресу искать данные. Всё что идёт далее является частью URL. Вот полная ссылка к месяцу Январь: newchart-xmlurl-get-data.php?type=hourly&Year=2010&Month=1
  • Дни: всё тоже самое и в случае с месяцем, только вот URL теперь содержит информацию, касающуюся дней;
  • Часы: если мы не хотим, чтобы после этой диаграммы следовали другие, просто не установим ей URL;
  • В самом конце закрываем XML;

Сохраните данный файл как get-data.php; Теперь откройте браузер и проверьте работу скрипта. Например: http://localhost/fcdemo/get-data.php?year=2010

Вы должны увидеть что-то вроде этого:

Тестируйте

Теперь мы полностью закончили работу над диаграммами. Для того, что проверить работу зайдите по адресу http://localhost/fcdemo/demo.html

Если вы всё правильно сделали, то на странице увидите Column3D диаграмму. Если вы кликните по одному из столбцов, то откроется новая диаграмма. И так далее…

Вывод

Если вы внимательно изучили данный урок, то уже скорее всего имеете общее представление о связных диаграммах на PHP/MySQL. Точно такие же диаграммы могут быть сделаны для следующей статистики:

  • Количество продаж за период времени;
  • Сколько раз ваш сайт переставал работать;
  • Количество посетителей отдельной страницы;

Структура диаграммы будет одна и та же для любой темы. Используйте какой-то параметр для выборки инфы из базы, затем превратите ответ в XML и всё, диаграмма готова!

Для большего вдохновения можете посетить вот эту демо страницу. Спасибо за внимание!

Построение графиков на PHP возможно двумя способами. Можно нарисовать самостоятельно или использовать какую-нибудь библиотеку. Я предлагаю научиться создавать графики самим. Во-первых, потому что хорошие библиотеки являются платными. Во-вторых, используя любую библиотеку, вы ограничены её функционалом. Лучше рисовать графики самостоятельно.

Для начала рассмотрим самый простой вариант. Есть массив, содержащий количество пользователей, которые зарегистрировались на сайте за 5 дней.

$mas = array(2, 7, 20, 9, 14);

Выведем этот массив на страницу в виде графика. Сначала нарисуем оси координат.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

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

3 - создаём изображение

7, 8 - оси x и y

9-13 - засечки на оси x

14-18 - цифры на оси x

19, 20 - засечки на оси y

21, 22 - цифры на оси y

Рисунок должен выглядеть так:

Чтобы нарисовать линию на графике, нужно найти на нём точки, по которым линия будет строиться. На практике можно сразу находить точку и рисовать по ней линию. Но чтобы пример был более понятным, мы разделим задачу на две части. Сначала найдём все точки, потом нарисуем по ним график. Для этого создадим двухмерный массив, в котором будут координаты x и y каждой точки. Для поиска координат нам нужна точка отсчёта. Это та точка, в которой пересекаются оси координат. В нашем рисунке она имеет координаты x: 50, y: 250 пикселей. Для определения положения каждой точки нужно использовать масштаб графика. В примере мы задали масштаб сами. По оси x для каждого дня создано 100 пикселей. Первый день находится на расстоянии 100 пикселей от начала отсчёта, второй на расстоянии 200 пикселей и так далее. Значит координата x для первого дня равна 50 + 100 = 150. Для второго 50 + 200 = 250.

По оси y для каждых 10 пользователей выделено 100 пикселей. Значит для одного пользователя - 10 пикселей. Нужно учитывать, что у изображения ось y направлена вниз, значит нужно не прибавлять значение к точке отсчёта, а вычитать. В первый день на сайте зарегистрировались 2 посетителя. Координата для этого значения равна 250 - (2 * 10) = 230. Для второго дня 250 - (7 * 10) = 180. Таким образом, массив с координатами точек получается такой:

График выглядит так:

Мы рассмотрели самый простой вариант построения графика. Я заранее знал количество дней и максимальное число пользователей. Поэтому я сам выбрал масштаб графика. Но обычно эти данные могут быть разными и масштаб нужно расчитывать. И сам график выглядит немного иначе. Нам привычно, что оси координат начинаются с нуля. Но для удобства отображения это правило иногда не соблюдается. Ось x начинается не с 0, а с 1, чтобы не слева от линии не было пустого пространства. А ось y показывается так, чтобы на график поместились все значения. Например, если минимальное значение - 60, а максимальное - 70, то ось y содержит именно такой диапазон. Рассмотрим создание такого графика.

В примере ось x имеет длину 570 пикселей. Её нужно разделить на одинаковые сегменты для каждого дня. Ось x начинаться не с 0, а с 1. Поэтому сегмента между 0 и 1 не будет и количество сегментов становится на 1 меньше. Если дней 5, то получится 4 сегмента. Формула расчёта длины сегмента такая:

длина = длина оси / (число дней - 1)

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

570 - 50 это длина оси x . Она зависит от размеров изображения.

Ось y делаем такой, чтобы поместились все значения. Нужно получить минимальное и максимальное значения. Они должны занять всю высоту графика. Зная диапазон, мы сможем рассчитать, сколько пикселей должно соответствовать одному пользователю на графике.

диапазон = максимальное - минимальное

длина = длина оси / диапазон

Полученное число также нужно округлить.