Создание круговой диаграммы средствами библиотеки GD на PHP


Содержание

Создание круговой диаграммы средствами библиотеки GD на PHP

Nickolay.info. PHP. Скрипт построения круговой диаграммы на PHP

Скрипт рисует круговую диаграмму с подписями для секторов по данным, переданным через строку параметров URL (методом GET) и выводит относительные величины полученных секторов в процентах. Сектора, которые должны занимать менее 2% площади круга, не рисуются. Если раскомментарить строку, помеченную в листинге, такие сектора будут присоединяться к следующему сектору.

Скрипт реагирует на следующие параметры URL:

  • h=число — ширина генерируемого рисунка в пикселах, от 100 до 1000 включительно, по умолчанию 300;
  • w=число — высота генерируемого рисунка в пикселах, от 100 до 1000 включительно, по умолчанию 300;
  • f=число — размер шрифта (пункты), в котором выводятся подписи, от 8 до 72 включительно, по умолчанию 13;
  • d=число1,подпись1;. ;числоN,подписьN — относительные значения категорий диаграммы и подписи к категориям, записи разделены символом ;, внутри одной записи число отделяется от строки подписи символом запятой

Скрипт написан очень быстро и в процессе совсем другой работы, поэтому его код неоптимален и возможны, например, такие ширина и высота рисунка, при которых надписи расположатся на секторах «некрасиво», при значениях по умолчанию и не слишком длинных подписях всё должно выглядеть нормально.

Наличие расширения GD (библиотеки GDLib для динамической работы с изображениями) проверяется в самом начале:

Затем скрипт пытается поставить российскую локаль, перебирая распространённые варианты написания — увы, стандарта здесь нет и всё зависит от операционки сервера:

Второе «увы» — встроенные в PHP шрифты не имеют региональной части символов (в нашем случае — кириллицы), и даже при использовании стандартного метода imagettftext из библиотеки GDLib плюс кириллического шрифта, вместо русского текста всё равно выводятся кракозябры. Скрипт пытается решить эту проблему с помощью собственной функции str_rus :

У меня работает и на локалхосте под Windows, и на сервере под FreeBSD.

С другой стороны, чтобы не мучиться с setlocale или number_format (на разных хостах и в разных ОС могут быть разные локали для отображения вещественных чисел, например, целая часть числа может отделяться от дробной как точкой, так и запятой), все числа из данных предполагаются целыми.

Пример вызова скрипта:

— при условии, что index.php назначено как имя документа по умолчанию, иначе

Вот что выдаст такой вызов:

Некоторые браузеры, например Google Chrome, при таком вызове всё равно покажут кракозябры, потому что по стандартам в URL допускаются только символы с кодами 33-127, а к кириллице надо применять двухбайтовое URL-кодирование в UTF-8 (метод urlencode в PHP) и наш запрос должен выглядеть так:

Просто русифицированные Internet Explorer, Opera и Firefox закодируют URL автоматически.

Графики и диаграммы средствами PHP+GD

Часто перед web-разработчиком стоит задача генерирования графиков и диаграмм на основе некоторых данных. Если диаграммы еще можно построить средствами HTML + CSS, то графики так вывести уже не удастся. Более предпочтительный вариант – генерирование рисунков с помощью PHP + GD. Но и этот вариант достаточно трудоемок.

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

Моим требований полностью соответствовал лишь ASE ChartDirector, но, к сожалению, этот продукт распространяется на платных условиях, поэтому сферы его применения весьма ограничены ;)

Но буквально пару дней назад я нашел достойную бесплатную альтернативу продукту от компании ASE. Имя ей – JpGraph. Библиотека полностью объектно-ориентированная, содержит в себе 101 класс и 948 методов, которые позволяют создавать практически любые диаграммы и графики. Вместе с библиотекой поставляется подробнейший мануал, описание всех классов и методов, а также пара сотен примеров.

Для примера я попытался создать простую диаграмму и по возможности придать ей как можно более приятный глазу вид.

Ниже преведен код, который генерирует эту прелесть :]

Построение графиков на PHP с использованием JpGraph и библиотеки GD

Возникла необходимость построения графика на сайте, чтобы значения подтягивались из базы данных MySql.

Пока хочу все смоделировать на Денвере, прочитал что вроде необходимая для работы JpGraph библиотека gd предустановлена на Денвер, вставляю код из примера:

Пишет ошибку: Warning: include(pChart/pData.class) [function.include]: failed to open stream: No such file or directory in Z:\home\candbnews\www\index.php on line 151 и далее в подобном стиле. Я понимаю что этого файла pChart/pData.class у меня нет в корневике, и нужно прописать путь куда то в самом денвере, и тут не могу разобраться,

Подскажите пожалуйста кто сталкивался с такой проблемой.

Дополнительные возможности JpGraph

JpGraph ( http://www.aditus.nu/jpgraph/ ) — объектно-ориентированная PHP-библиотека, позволяющая достаточно просто создавать графику профессионального качества, используя минимум кода. Данная статья представляет собой учебный пример, иллюстрирующий некоторые дополнительные возможности библиотеки JpGraph, а именно:

* общая методика разработки скриптов с использованием JpGraph;
* последовательный процесс разработки графиков (в отличие от простой демонстрации конечного результата);
* использование механизмов кэширования JpGraph для увеличения производительности;
* использование карт-изображений на стороне клиента (далее — CSIM, т.е Client Side Image Map. Прим. перев.) для реализации быстрой навигации.

Инсталляция и необходимое программное окружение

Для начала работы с JpGraph необходимо скачать исходный код, доступный по адресу: http://www.aditus.nu/jpgraph/jpdownload.php.

Далее распакуйте содержимое архива в одну из директорий, перечисленных в конфигурационной опции PHP include_path. Теперь вы можете изменить пути к директориям установленных в вашей системе шрифтов, а также директории кэша изображений. Эти настройки находятся в файле jpgraph.php.

Для проверки правильности инсталляции просмотрите страницу /Examples/testsuit.php. Эта страница генерирует более 200 демонстрационных графиков, используя библиотеку JpGraph, и позволяет просмотреть исходный код, использованный для построения каждого из них.

Если вы только изучаете JpGraph и исследуете его возможности, вам потребуется справочное руководство. Оно доступно по адресу http://www.aditus.nu/jpgraph/jpdownload.php и содержит как последовательное описание, так и превосходный справочник по классам. Вы также можете посетить форум поддержки JpGraph — http://jpgraph.fan-atics.com.

Все скрипты в этой статье были разработаны и протестированы на PHP 4.3.0 (с включенной поддержкой библиотеки GD2), установленном как модуль к Apache 1.3.27 под управлением операционной системы RedHat Linux 7.2. Скрипты используют СУБД MySQL ( http://www.mysql.com ) и ADOdb ( http://php.weblogs.com/adodb ) как абстрактный уровень доступа к базе данных. По этой причине все скрипты включают в себя файл phpa_db.inc.php, показанный в листинге 1.

Примечание переводчика: в английском варианте статьи нет информации об используемой версии библиотеки JpGraph. Здесь и далее информация о путях, конфигурационных опциях, URI приведена для версии 1.14, имеющейся в распоряжении переводчика. Код примеров сохранен оригинальный. Примеры тестировались на Windows 2000 Server SP4/Apache 1.3.27/PHP 4.3.3 (уст. как модуль к Apache)/JpGraph 1.14/MySQL 4.1-alpha.

Листинг 1: phpa_db.inc.php

Данный включаемый файл создает объект-соединение ADOdb — $conn, который используется для доступа к БД в остальных скриптах. Вам необходимо изменить параметры вызова метода Connect() в соответствии с вашими установками, в том числе и имя тестовой базы данных.

Примечание переводчика: Пример, более понятный для русскоязычного читателя:

ADOdb должна быть установлена в одну из директорий, перечисленных в конфигурационной опции PHP include_path. Для читателей, не знакомых с ADOdb, я дам очень краткий обзор некоторых базовых возможностей. В ADOdb вы можете получить результат выполнения SQL-запроса используя следующий вызов:

Если запрос был выполнен удачно, метод вернет объект — набор записей ADOdb, в противном случае метод вернет FALSE. Затем используются два метода этого объекта: GetArray() и GetAssoc(). Метод GetArray() возвращает вектор записей, где каждая запись представлена ассоциативным массивом вида ‘COLUMN’ => ‘VALUE’. Метод GetAssoc() вместо вектора возвращает ассоциативный массив, индексы которого являются значениями первого столбца для каждой записи.

Приведенные ниже примеры предполагают, что у вас в системе установлен TrueType шрифт Arial, в противном случае JpGraph будет выдавать ошибку. Самый простой способ обойти эту проблему — заменить все ссылки на константу FF_ARIAL на FF_FONT1. FF_FONT1 — встроенный системный шрифт, он выглядит не так приятно как FF_ARIAL, но позволит вам просмотреть приведенные примеры. Этого должно быть достаточно, чтобы приступить к примерам. Теперь рассмотрим учебную задачу.

Учебная задача


В нашем учебном примере мы рассмотрим данные о продажах компании ABC, вымышленного производителя украшений. ABC производит широкий спектр украшений от дешевого B за $12.99 до украшений E класса «ультра-делюкс» за $1,499.50. В данном примере мы сосредоточимся на продажах в континентальных Соединенных Штатах, где компания разделена на четыре подразделения по регионам. Компания продает товар распространителям по трем каналам: Интернет, телефонный центр, и различные розничные точки.

Вас попросили сделать графики, отображающие данные о продажах в долларах и натуральных показателях. Вам необходимо также разбить графики по позициям каталога для каждого региона и выполнить сравнение со спрогнозированными данными. Компания ABC также требует, чтобы вы сделали график, показывающий данные о продажах за год по каналам для каждого региона. Им также необходима быстрая навигация между двумя графиками.
Разработка базы данных

Модель данных компании ABC составляют шесть таблиц. Центральная таблица — abc_sales. Таблица содержит информацию о продажах, включая время, канал, штат, позицию каталога, количество проданных изделий и доход от сделки.

Другие таблицы, составляющие модель данных — abc_catalog, abc_channel, abc_forecast, abc_region и abc_state_region. Таблица abc_catalog содержит суррогатный ключ для позиций каталога, которые клиент может приобрести, описания позиций и цену за единицу. Таблица abc_channel содержит суррогатный ключ, наименование и описание канала продажи (web, телефон, розничная точка), через который может быть куплен товар из каталога. Таблица abc_forecast хранит информацию о спрогнозированных планах продаж по позициям каталога, каналам продаж и месяцам. Таблица содержит информацию об ожидаемых объемах продаж и доходах по каждому «срезу» данных. Таблица abc_region содержит суррогатный ключ и описание для каждого региона продаж компании. Таблица abc_state_region ставит в соответствие аббревиатуру штата конкретному региону продаж.

SQL-запросы, используемые для создания таблиц, а также заполнения небольших таблиц, находятся в файле mysql_ddl.sql в директории с исходным кодом данной статьи. Что касается других, то таблицы продаж и прогнозов продаж могут быть заполнены с использованием скриптов abc_gen_sales.php и abc_fcst_ins.php соответственно. Скрипт abc_gen_sales.php должен запускаться первым, так как работа abc_fcst_ins.php зависит от данных, которые создает первый скрипт.

Примечание переводчика: Для создания учебной БД потребуются еще и данные о переписи населения в США за 2000 год. Эта информация (в виде ASCII-файла) доступна по адресу http://www.census.gov/geo/www/gazetteer/tiger/tms/gazetteer/ustracts2k.zip.

Поэтапно процесс создания и заполнения учебной БД выглядит так:

1. Скачать файл с данными переписи, распаковать и разместить его в директории с учебными примерами.
2. jvn_parse_census.php (соединение с БД — см. комментарии в скрипте) — парсит файл ustracts2k.txt (данные переписи в формате ASCII), создает и заполняет таблицу census_data, необходимую для работы скрипта abc_gen_sales.php.
3. mysql_ddl.sql.
4. abc_gen_sales.php.
5. abc_fcst_ins.php.

Примечание: Оригиналы данных скриптов были написаны в декабре 2002 года, данные подобраны из расчета, что текущей датой является 15 декабря 2002 года, чтобы графики выводились практически за полный год. Так как сейчас 2003 год, скрипты были модифицированы таким образом, чтобы запрашивать и выводить данные за предыдущий год.

Примечание переводчика: статья переводилась на русский язык в феврале 2004 года, и в скрипты были внесены необходимые изменения.
Сравнение данных о продажах со спрогнозированными показателями по регионам

Нашей первой задачей будет создание графика, сравнивающего объем продаж и доход с прогнозом для каждого региона. Предполагается, что эта информация является собственностью компании и не предназначена для публичного распространения.

При разработке PHP-скриптов, создающих графики с использованием JpGraph, я предпочитаю использовать следующий 4-х шаговый процесс:

1. Получение и обработка данных для построения графика.
2. Создание объекта Graph и задание его основных свойств (таких как цвет и координатные оси графиков).
3. Создание объектов Plot, для размещения на объекте Graph.
4. Завершение объекта Graph и его вывод графика.

Согласно вышеописанному процессу вы, в первую очередь, должны получить данные о продажах и прогнозные данные. Чтобы посмотреть, как используется ADOdb для получения данных этого графика, посмотрите строки 26-122 скрипта abc_reg_sales_graph.php. Цель этой статьи — построение графиков, поэтому вопросы извлечения данных из базы и конструирования графиков детально не рассматриваются. Поскольку графики строятся по регионам, ваш скрипт должен иметь соответствующий параметр и проверять его корректность. Если параметр корректен, его значение присваивается переменной $region_id, в противном случае генерируется ошибка. Здесь имеет место небольшая проблема. Так как данные, выводимые скриптом — графический объект, страницы сайта должны ссылаться на него используя HTML-тэг , т.е так:

Если скрипт выведет текстовое сообщение (например, сообщение об ошибке PHP), это будет понято как некорректное изображение, и все, что увидит пользователь — символ отсутствующего изображения на том месте, где должен быть ваш график. Код, показанный в листинге 2, проверяет переданный параметр «регион» и формирует сообщение об ошибке в графическом виде. Данный код предполагает, что вы уже выбрали из базы данных список регионов продаж и сохранили результат запроса в глобальной переменной-массиве $regions. Также предполагается, что в скрипт включены библиотечные файлы jpgraph.php и jpgraph_canvas.php.

Листинг 2: Создание сообщения об ошибки в графическом виде (abc_reg_sales_graph.php)

После извлечения из БД данных в виде набора записей часто необходимо преобразовать их в формат, более подходящий для построения графика. Это означает создание нескольких массивов с индексами, начинающимися с нуля для каждого числового ряда.

Вместо того, чтобы создавать несколько глобальных массивов для каждого ряда, я предпочитаю иметь единый ассоциативный массив с именем $graphData, содержащий массивы для каждого ряда и имеющий индексы, совпадающие с именами этих рядов. Код в листинге 3 собирает эти массивы в единый массив $graphData, который будет использоваться в дальнейшем для построения графиков.

Листинг 3: Формирование единого массива $graphData (abc_reg_sales_graph.php)

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

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

Этот код иллюстрирует сущность JpGraph API. Улучшение внешнего вида ваших графиков приведет к увеличению объема исходного кода, но код, приведенный в данном примере, является минимальным.

Эти несколько строк кода реализуют 4-х шаговый процесс, описанный выше. На шаге 2 Вы создаете и конфигурируете объект Graph. На шаге 3 создаются объекты BarPlot и LinePlot. Вы завершаете процесс на шаге 4, размещая графики на объекте-изображении и вызывая метод Graph::Stroke() для вывода графического объекта. Вызов метода Graph::Stroke() предписывает JpGraph напрямую вернуть браузеру изображение. Результат показан на рис. 1.

Рисунок 1. Ваш первый график

Листинг 4: Ваш первый график

Непрерывность линии графика (спрогнозированных продаж — прим.перев.) на самом деле не соответствует действительности, так как данные в реальности не изменяются плавно от месяца к месяцу (прогнозные данные привязаны к месяцам). Данные прогноза будут лучше представлены «ступенчатой» линией графика.

Давайте внесем эти изменения и, заодно, покажем данные о доходах вместо данных об объемах продаж. Вы можете сделать это, изменив два графика так, как показано в листинге 5. Результат показан на рисунке 2.

Листинг 5: Графики для создания изображения, показанного на рис. 2

Рисунок 2. Использование «ступенчатой» линии графика.

Для представления объемов продаж и доходов на одном графике вам необходимо воспользоваться возможностью JpGraph создавать на графике вторую ось ординат.

На следующем шаге мы совместим в одном изображении график объемов продаж и график доходов. Здесь есть два принципиальных момента. Во-первых, взглянув на две диаграммы, вы можете увидеть, что графики продаж и доходов представлены в разных масштабах. Во-вторых, было бы неплохо, если бы изображение выводилось таким образом, чтобы линия графика выходила за границу диаграммы, соответствующей декабрю месяцу. В идеале вам нужна сгруппированная столбцовая диаграмма. Однако, JpGraph не позволяет группировать графики, построенные в разных масштабах. Чтобы добиться этого, мы пойдем на небольшой обман.

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

Для форматирования меток на второй оси ординат вы можете создать функцию обратного вызова.

Листинг 6: Создание графика, состоящего из нулей (abc_reg_sales_graph.php)

JpGraph будет вызывать эту функцию для каждой метки, наносимой на координатную ось, и будет использовать значение, возвращенное функцией вместо номера строки. Это позволит нам выводить числа в формате денежных сумм. Код показан в листинге 7.

Листинг 7: Функция обратного вызова для форматирования меток (format_callback.php)

Для построения графика (см. рис. 3) измените ваш код, включив в него код из листинга 8.

Листинг 8: Код для построения графика на рис. 3

Рис. 3. Сгруппированная столбцовая диаграмма, построенная в разных масштабах.

На данный момент вы имеете график достаточно представительного вида, но к нему можно еще добавить некоторую полезную информацию. Пользователи хотели бы видеть вклад, вносимый каждым товаром в объемы продаж и соответствующий доход. Это может быть достигнуто созданием «слоеной» столбцовой диаграммы, добавленной к каждой сгруппированной столбцовой диаграмме, как показано в листинге 9. Результат показан на рис. 4.

Листинг 9: Код для создания «слоеной» столбцовой диаграммы, показанной на рис. 4 (abc_reg_sales_graph.php)

Рис. 4. Использование «слоеной» столбцовой диаграммы.

Мы почти у цели. Необходимо лишь немного отформатировать область, в которой отрисовываются графики, надписи возле координатных осей, а также название региона, для которого строится график. Кроме того, мы должны убедиться в том, что график используется только для внутренних целей фирмы. Один из способов указать на то, что объект является частной собственностью — добавить фоновое изображение. В данном случае, мы используем строку «ABC Co. Proprietary» («Собственность компании ABC» — Прим. перев.), написанную по диагонали и многократно повторенную.

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


Это избавит вас от усилий по редактированию изображения во внешнем графическом редакторе. Посмотрите файл img/abc-background.png в директории с исходными кодами данной статьи в качестве примера того, как может выглядеть фоновый рисунок. Вы можете использовать этот рисунок в качестве фонового изображения, используя код из листинга 10.

Примечание: Библиотека GD2, встроенная в PHP 4.3.0, конфликтует с методом Graph::AdjBackgroundImage(). Если вы используете эту версию PHP, вам придется отказаться от использования этого метода и обрабатывать изображение в графическом редакторе.

Листинг 10: Код для использования и настройки фонового изображения (abc_reg_sales_graph.php)

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

Листинг 11: Код для завершения построения графика на рис. 5 (abc_reg_sales_graph.php)

Рис. 5. Законченный вид графика

Из соображений повышения производительности вы решили реализовать механизм кэширования изображений JpGraph для этого графика. Механизм кэширования основан на сохранении копии изображения как файла на сервере. Если копия, сохраненная к кэше, еще действительна, JpGraph вернет ее в ответ на запрос клиента вместо того, чтобы генерировать изображение «на лету». Заметьте, что вы должны иметь на сервере соответствующую привилегию для записи в директорию кэша. При создании экземпляра класса Graph вам необходимо передать конструктору, кроме ширины и высоты изображения, также имя файла кэшируемого изображения и таймаут в минутах (время, в течение которого действительно изображение, сохраненное в кэше) и, наконец, параметр, сообщающий JpGraph о том, что изображение все равно нужно выводить. Это значит, что вы будете продолжать использовать ссылку на PHP-скрипт как значение атрибута src тэга img. Код, необходимый для реализации механизма кэширования, приведен в листинге 12.

Листинг 12: Код, реализующий кэширование изображения. (abc_reg_sales_graph.php)

Теперь, если в течение 24 часов будет запрошен тот же график для того же региона, клиенту будет возвращена версия изображения, находящаяся в кэше, и выполнение скрипта прервется после строки ‘new Graph()’.

Илон Маск рекомендует:  Что такое код dup

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

Сравнение объемов продаж через разные каналы по регионам

Второй график, который вас попросили сделать, показывает объемы продаж для каждого региона по каналам. Кроме того, нужно обеспечить простой способ навигации между первым и вторым графиками. Этот тип отчета предполагает просмотр информации о долях, поэтому наиболее эффективной будет круговая диаграмма. Просмотрите, пожалуйста, еще раз строки 22-82 файла abc_map_graph.php в директории с исходными кодами этой статьи, чтобы понять, как выполняются запросы к БД и формирование массивов для последующего построения графиков. В листинге 13 приведен код, необходимый для создания графика, показанного на рис. 6.

Листинг 13: Код для создания круговой диаграммы на рис. 6

Рис. 6. Простая круговая диаграмма

Вы можете использовать фоновое изображение так, как это показано на примере первого графика, а также разместить дополнительную информацию на вашем графике. Разместим на графике карту США, разделенную по регионам продаж компании ABC. Если вы используете эту карту как фоновое изображение для графика, вы можете расположить круговые диаграммы на фоне соответствующего региона. Посмотрите файл img/abc-regions.png как пример использования фонового изображения в этом графике.

Для использования этого примера вам необходимо добавить несколько строк в цикл формирования массива $graphData, чтобы сделать возможным динамическое расположение круговых диаграмм для каждого региона:

Теперь взгляните на код листинга 14, создающий график, изображенный на рис. 7.

Листинг 14: Код для создания графика на рис. 7 (abc_map_graph.php)

Рис. 7. Использование фонового изображения для показа регионов

В заключение заказчик хочет иметь возможность быстрой навигации между имеющимися круговыми диаграммами и соответствующими графиками продаж, построенными ранее. Вы можете реализовать эту возможность, используя карты-изображения на стороне клиента (Client Side Image Maps — CSIM — Прим. перев.). CSIM — HTML-технология, позволяющая определять области на изображении и связывать их с гиперссылками. Для реализации CSIM в этом графике вы должны определить гиперссылки и альтернативный текст для изображений (подсказки для пользователя). Для начала мы определим константу, используемую в большинстве ссылок:

Теперь в массиве $graphData нужно определить ссылки и альтернативный текст для изображений:

Так как в дополнение к двоичным данным необходимо выводить HTML (CSIM), мы не можем вернуть данные клиенту уже привычным нам способом. CSIM и изображение тесно зависят друг от друга. Чтобы сделать это, нам необходимо прибегнуть к кэшированию изображения. Это позволит нам вывести карту-изображение вместе с тэгом img и воспользоваться кэшированным изображением. Вместо того, чтобы воспользоваться механизмом кэширования JpGraph, описанным выше, мы применим другую технику и сохраним изображение в директории, из которой клиент сможет запросить его напрямую. Для этого надо создать директорию с именем ‘img’ в той же директории, где находится скрипт. Вы также должны иметь на сервере права на запись в эту директорию. При создании графика обрабатываем его так же, как если бы мы возвращали клиенту двоичный поток — изображение. В цикле формирования круговых диаграмм добавляем информацию о ссылках и альтернативном тексте (см. листинг 14 — Прим. перев.):

Далее выводим график, используя код из листинга 15.

Листинг 15: Код для формирования CSIM (abc_map_graph.php)

Данный код указывает JpGraph вывести изображение в файл img/abc_channel_graph.png. Далее помещаем в переменную $imgMap сгенерированную карту-изображение. Тэг img определен таким образом, что позволяет использовать сгенерированную карту-изображение.

Ключевые понятия

В данном учебном примере были рассмотрены следующие ключевые понятия, касающиеся построения графиков средствами JpGraph:

* использование в JpGraph линейных графиков, столбцовых и круговых диаграмм;
* использование «слоеных» и сгруппированных столбцовых диаграмм;
* использование второй оси ординат с другим масштабом;
* использование функции обратного вызова для форматирования меток на осях координат;
* генерация сообщений об ошибках в графическом виде;
* создание «водяных знаков» с использованием фоновых изображений;
* использование механизмов кэширования изображений JpGraph для увеличения производительности, а также облегчения использования CSIM;
* использование фонового изображения как части информационного контента диаграммы (расположение круговой диаграммы на фоне карты регионов продаж);
* использование карт-изображений на стороне клиента для быстрой навигации между графиками

Заключение

JpGraph предоставляет простое API, позволяющее быстро создавать профессиональную графику. Соединение возможностей JpGraph и средств PHP для доступа к БД дает вам в руки мощный инструмент для создания динамических графиков в web’е. В данной статье представлены некоторые из дополнительных возможностей JpGraph такие как: кэширование, фоновые изображения и карты-изображения на стороне клиента. Надеюсь, вы достаточно хорошо познакомились с данной технологией и сможете свободно использовать PHP и JpGraph в своих будущих data mining проектах.

Создание графики на PHP

Для того чтобы определить области применения средств создания графики в сценариях для веб, рассмотрим приведенный ниже ряд возможных вариантов использования графики:

  • На HTML-страницу могут быть внедрены статические изображения, созданные самостоятельно или заимствованные где-либо.
  • Могут быть использованы формируемые программным путем изображения (HTML + CSS).
  • Можно использовать библиотеку gd, чтобы заранее создавать статические графические изображения для всех возможных ситуации, возникающих в ходе выполнения сценария, сохранять их в файлах и отображать по условию.

Вариант внедрения графики с использованием статических изображений мы рассматривать не будем ввиду его простоты, поэтому сначала рассмотрим простой вариант (графика HTML + CSS), а затем рассмотрим использование библиотеки gd в PHP.

Графика HTML + CSS

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

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

Библиотека gd

Графические средства, описанные в предыдущем разделе, практически исчерпывают возможности стандартного кода HTML (правда стоит отметить, что мы не рассмотрели достаточно мощное средство создания графики HTML5 Canvas). Теперь перейдем к описанию методов создания действительно произвольной графики с использованием библиотеки gd.

Общее описание библиотеки gd

Вообще говоря, комплект инструментальных средств gd представляет собой библиотеку кода на языке C, предназначенную для создания изображений и манипулирования ими. Эта библиотека была первоначально разработана и предоставлена во всеобщее пользование талантливыми и великодушными сотрудниками компании Boutell.com.

Библиотека gd сама по себе не является графической программой или программой рисования, а также не представляет собой автономное приложение или графический интерфейс пользователя. Вместо этого библиотека gd предоставляет функции, которые могут быть вызваны на выполнение в любой программе для осуществления требуемых манипуляций с изображениями. Это означает, что с библиотекой gd можно связать любую программу на языке C, в которой необходимо использовать код данной библиотеки. Именно такую задачу решили разработчики системы PHP.

В действительности для этой цели был написан набор интерфейсных функций, который позволяет легко вызывать процедуры gd из сценария на языке PHP. Но в самой библиотеке gd нет какого-либо кода, относящегося только к PHP, и разработаны интерфейсы, позволяющие обращаться к этой библиотеке из нескольких других языков программирования и вариантов программной среды, включая Perl, Pascal, Haskell и REXX.


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

Форматы изображений

Библиотека gd в принципе позволяет импортировать и экспортировать изображения с использованием широкой разновидности форматов. Наиболее популярными форматами изображений являются GIF, JPEG и PNG, хотя в основном в рассматриваемых примерах применяется последний из этих форматов.

Форматы GIF и PNG предназначены для описания сетки из цветных элементов, соответствующих пикселям, с учетом некоторых дополнений. Первое дополнение состоит в том, что ячейки могут содержать действительные номера цветов или индексы в таблице с номерами цветов. (Первый вариант позволяет создавать более выразительные изображения, поскольку дает возможность предусматривать любое количество различных цветов, а последний вариант способствует созданию более компактных изображений.)

Второе дополнение заключается в следующем. Безусловно, концептуальное представление форматов GIF и PNG является довольно простым, но на практике чтение, запись и передача изображений в этих форматах всегда осуществляется в сжатой форме. Сжатие необходимо, поскольку для хранения данных, представленных в виде сетки ячеек, требуется большой объем памяти. Простое изображение, состоящее из 500×400 пикселей, включает 200 000 пикселей, причем если для задания каждого пикселя требуются три байта, то объем необходимой памяти уже превышает половину мегабайта.

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

Установка библиотеки

Откровенно говоря, задача инсталляции библиотеки gd и обеспечения ее успешной работы в сочетании с системой PHP является довольно сложной. Это обусловлено не какими-либо недостатками программного обеспечения PHP или gd, а полностью определяется проблемами настройки конфигурации; в частности, необходимо разобраться в том, где должны находиться и фактически находятся библиотеки gd, а также проследить за тем, чтобы этапы компиляции и связывания всех исполняемых файлов были выполнены должным образом. Поэтому наилучшей из всех возможных является такая ситуация, когда пользователь обнаруживает, что библиотека gd уже установлена, а в системе PHP уже разрешена поддержка gd (либо благодаря любезности компании, предоставляющей веб-хостинг, либо в связи с тем, что эта библиотека включена в состав инсталлированной системы PHP).

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

После вывода этой страницы на экран достаточно выполнить поиск текстовой строки «gd» в окне браузера. В результате должен быть обнаружен подраздел с описанием того, в какой степени в используемой инсталляции PHP разрешена поддержка библиотеки gd. Если вы намереваетесь лишь подготавливать изображения некоторых типов (например, в формате PNG), а результаты выполнения функции phpinfo() говорят о том, что поддержка изображения этого типа разрешена, то можете сразу же приступать к работе. А если данные о версии gd включают слово «bundled», то применяется библиотека gd, которая входит в комплект поставки PHP.

Если же попытка найти упоминание о библиотеке gd оканчивается неудачей, а инсталляцией PHP занимаетесь вы сами, то можете выполнить инсталляцию и настройку конфигурации библиотеки gd. (С другой стороны, если инсталляцией PHP занимается компания, предоставляющая вам услуги хостинга, то вам остается лишь попросить, чтобы эта компания обеспечила поддержку библиотеки gd, или прибегнуть к услугам другой компании веб-хостинга.)

Использование библиотеки gd, входящий в комплект поставки PHP, позволяет избавиться от многих затруднений, связанных с инсталляцией gd, но не от всех. Дело в том, что применение самой версии, входящей в комплект поставки, позволяет получить библиотеку gd, но не обязательно все библиотеки, необходимые для работы gd. Библиотека gd сама зависит от нескольких других библиотек: libpng (служит для манипулирования изображениями PNG), zlib (используется при сжатии) и jpeg-6b или более поздней версии (предназначена для манипулирования изображениями JPEG, если в этом есть необходимость). Указанные библиотеки уже присутствуют во многих инсталляциях Linux, и в таком случае может оказаться достаточным включить в состав параметров требуемый параметр with (такой как —with-zlib), не указывая инсталляционный каталог. Если настройку конфигурации PHP выполняете вы сами, то достаточно добавить параметр —with-gd, чтобы обеспечить включение в исполняемый файл версии gd, входящей в комплект поставки. А если вы хотите указать на другую версию, то воспользуйтесь вместо этого параметром —with-gd=path.

Если вы обнаружите отсутствие одной или нескольких необходимых библиотек, это будет означать, что эти библиотеки придется сформировать отдельно. Для ознакомления с информацией о том, где найти текущие версии, можно начать с изучения документации, находящейся по адресу www.libgd.org.

Основные принципы работы с библиотекой gd

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

Изображение, обрабатываемое с помощью инструментария gd, характеризуется информацией о ширине, высоте и цвете всех пикселей, количество которых равно произведению ширины на высоту. Обычно программа начинает свое взаимодействие с библиотекой gd, либо создавая новое пустое изображение (на котором будет осуществляться черчение и рисование), либо импортируя изображение из файла. На следующих этапах обычно выполняются такие действия: во-первых, распределение цветов в изображении, во-вторых, черчение и рисование или манипулирование изображением с помощью каких-то других операций, в-третьих, преобразование изображения в общепринятый формат (например, PNG или JPEG) и передача его по месту назначения.

Представление цветов

Для представления цветов в изображениях gd применяются два способа: представление на основе палитры, которое ограничивается 256 цветами, и представление с реалистичными цветами, позволяющее задавать произвольное количество различных номеров цветов RBG. В версии gd 1.x единственная возможность состояла в использовании цветов на основе палитры, а в библиотеке gd 2.x и в версии этой библиотеки, входящей в комплект поставки PHP, поддерживается возможность создавать и изображения на основе палитры, и изображения в реалистичных цветах. Необходимо учитывать, что каждое конкретное изображение gd должно быть либо основанном на палитре, либо иметь реалистичные цвета (RGB); это означает, что возможность ввести реалистичные цвета в изображения на основе палитры отсутствует.

Чтобы получить исходное пустое изображение на основе палитры, необходимо вызвать функцию ImageCreate(), а дня получения изображения в реалистичных цветах используется функция ImageCreateTrueColor().

Изображения на основе палитры

Цвета задаются в формате «красный-зеленый-синий» (Red-Green-Blue — RGB), с помощью трех чисел от 0 до 255. Например, цвет, заданный числами (255, 0, 0) является ярко-красным, цвет (0, 255, 0) — зеленый, цвет (0, 0, 255) — синий, цвет (0, 0, 0) — черный, цвет (255, 255, 255) — белый и цвет (127, 127, 127) — серый. Создавая все новые и новые цвета, можно выбирать значения трех цветовых компонентов произвольно.

Любое рисование на изображении должно осуществляться с помощью какого-то конкретного цвета, а цвета должны быть распределены в изображении еще до их использования. Кроме того, первый цвет, распределенный в изображении, автоматически становится цветом фона. Итак, ни в коем случае нельзя считать, что можно обойтись без задания цветов, и обычно операция распределения цветов становится первой операцией после создания нового пустого изображения.

Цвета в изображениях, основанных на палитре, создаются с помощью функции imagecolorallocate(), которая принимает в качестве параметров изображение (созданное ранее) и три целых числа, задающих долю красного, зеленого и синего цветов. Возвращаемым значением является целое число, которое задает индекс нового цвета во внутренней палитре изображения. Это возвращаемое значение необходимо присвоить переменной, поскольку указанное значение индекса необходимо для выполнения всех будущих операций с помощью данного цвета.

Изображения на основе палитры могут иметь максимальное количество цветов, равное 256. (Читателя может интересовать или не интересовать, на чем фактически основаны такие изображения, но каждый пиксель в изображении на основе палитры в действительности представляет собой единственный байт, который хранит индекс одного элемента в палитре из 256 цветов.)

Обратите внимание на то, что индекс, возвращаемый при распределении одного из цветов в некотором изображении, имеет смысл только для этого изображения. Например, если в сценарии PHP переменной $black присваивается цвет, распределенный в одном изображении, то нет смысла использовать эту переменную в качестве входных данных о цвете для команды рисования, вызываемой для обработки другого изображения.

Изображения с реалистичными цветами

В библиотеке gd 2.0 и в более поздних версиях предусмотрена также возможность создавать изображения, не основанные на палитре, в которых каждый пиксель хранит произвольный номер цвета RGB. В этом так называемом формате с реалистичными цветами количество возможных цветов чрезвычайно велико. Указанная возможность не только беспредельно расширяет рамки художественного самовыражения, но и позволяет достоверно воспроизводить изображения PNG и JPEG с реалистичными цветами, загруженные в память с помощью инструментария gd.

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

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

Прозрачность

В версиях gd 2.x поддерживается понятие прозрачности. Для этого используется альфа-канал (задаваемый дополнительно к значениям красного, зеленого и синего цветов), который указывает, насколько прозрачным является данный цвет. Это позволяет, например, накладывать одну форму на другую таким образом, чтобы первая форма оставалась частично видна, а не перекрывалась полностью второй.

В языке PHP многие функции для работы с изображениями имеют аналог, содержащий в имени слово «alpha», которое указывает, что в этих функциях цвет представлен четырьмя значениями (R,G,B,A). Например, функция imageColorAllocate() принимает три параметра, а при вызове функции ImageColorAllocateAlpha() необходимо задать четвертый параметр со значением от 0 до 127. Значение, равное нулю, указывает, что цвет полностью непрозрачен, а значение 127 говорит о том, что цвет полностью прозрачен.

Координаты и команды рисования

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

Начало координат в данной системе, соответствующее координатам (0, 0), находится в верхнем левом углу изображения. Положительным направлением для значений X является направление слева направо, а для значений Y — сверху вниз. (В системах координат компьютерной графики такое местонахождение начала координат встречается часто, но те, кто изучал аналитическую геометрию, по-видимому, привыкли к тому, что начало координат находится в левом нижнем углу диаграммы.)

Количество команд рисования очень велико. Эти команды включают, но не ограничиваются командами черчения отрезков линии, прямоугольников и дуг, а также командами задания значений конкретных пикселей. Но следует учитывать, что конечным результатом всех этих команд рисования и черчения становится задание значений пикселей. После выполнения команд, изменяющих значения пикселей, в памяти не остается каких-либо следов (кроме самих изменившихся значений), поэтому отсутствует способ, позволяющий отменять действие команд рисования и черчения или раздельно представлять результаты различных команд.

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

Преобразование форматов

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

Освобождение ресурсов

После того как результат преобразования законченного изображения gd передан пользователю, можно считать, что работа с внутренней версией закончена. Это означает, что данная версия должна быть уничтожена. Правильный способ выполнения подобной операции состоит в вызове функции imagedestroy() с указанием изображения в качестве параметра.

Функции библиотеки gd

Мы не собираемся отдельно перечислять и описывать в данной статье все функции, предусмотренные в интерфейсе gd интерпретатора PHP. Для ознакомления с этой информацией рекомендуем воспользоваться разделом «Обработка и генерация изображений» руководства php.net. Большинство из функции gd относятся к одной из категорий, приведенных в таблице ниже. Обратите внимание на то, что в именах функций, перечисленных в этой таблице, для удобства чтения первая буква каждого слова представлена в верхнем регистре, но это условие в примерах кода не всегда соблюдается, поскольку имена функций PHP не чувствительны к регистру:

Илон Маск рекомендует:  StringReplace - Функция Delphi

Классификация функций gd


Тип Пример Примечание
Функции создания изображения ImageCreate(), ImageCreateTruecolor(), ImageCreateFromGd(), ImageCreateFromJpeg() Возвращают новое изображение gd. Функция ImageCreate() принимает в качестве параметров значения ширины и высоты изображения, а параметрами других функций являются путь к файлу, URL или строка, содержащая ранее созданное изображение, которое должно быть загружено и преобразовано в формат gd
Функции, выполняющие операции распределения цветов ImageColorAllocate(), ImageColorAllocateAlpha(), ImageColorDeallocate() Функция ImageColorAllocate() принимает в качестве параметров дескриптор изображения и требуемые значения красного, зеленого и синего цветов, после чего возвращает номер цвета, предназначенный в дальнейшем для использования в операциях рисования и черчения. Функция ImageColorAllocateAlpha принимает дополнительный параметр—коэффициент прозрачности (0-127)
Функции, выполняющие операции согласования цветов ImageColorClosest(), ImageColorClosestAlpha(), ImageColorExact(), ImageColorExactAlpha() Возвращают индекс согласующегося цвета в изображении с палитрой. Функции, содержащие в своем имени слово «Closest», возвращают наиболее точно согласующийся цвет (точность согласования измеряется как расстояние между точками в пространстве значений RGB); функции с обозначением «Exact» возвращают номер цвета, только если он идентичен искомому, в противном случае возвращают значение -1, функции с именем «Alpha» оперируют цветами, для определения которых применяются четыре значения (с прозрачными цветами)
Функции вычерчивания линий ImageLine(), ImageDashedLine(), ImageRectangle(), ImagePolygon(), ImageEllipse(), ImageArc() Применяются для вычерчивания отрезков прямых или кривых указанной формы. Обычно первым параметром каждой из этих функций является изображение, последним параметром — цвет, промежуточными параметрами — координаты X и Y
Функции установки пера для вычерчивания линий ImageSetStyle(), ImageSetThickness() Изменяют параметры настройки, которые влияют на характеристики линий, создаваемых последующими командами вычерчивания линий (некоторые из этих функций применимы только в версии gd 2.0.1 или более поздних версиях)
Функции рисования и заливки ImageFilledRectangle(), ImageFilledEllipse(), ImageFilledPolygon(), ImageFilledArc(), ImageFill() Как правило, аналогичны соответствующим функциям вычерчивания линий, но предусматривают не только вычерчивание контуров областей, а заполнение создаваемых областей цветом. Специальная функция ImageFill() выполняет операцию заполнения заливкой, для который применяется указанный цвет заливки. Заливка осуществляется во всех направлениях, начиная с указанной точки с координатами XY (для выполнения некоторых из этих функций требуется версия gd 2.0.1 или более поздняя)
Функции для работы с текстом ImageString(), ImageLoadFont() Функция ImageString принимает в качестве параметров дескриптор изображения, номер шрифта, координаты X и Y, строку текста и цвет. Если номер шрифта находится в пределах между 1 и 5, то для вывода строки в данном цвете используется один из пяти встроенных шрифтов. С другой стороны, номер шрифта больше 5 указывает на результат загрузки специализированного шрифта с помощью функции ImageLoadFont()
Функции экспорта ImagePng(), ImageJpeg() Преобразовывают внутреннее изображение gd в изображение соответствующего формата, а затем отправляют это изображение в выходной поток. Если задан только один параметр (дескриптор изображения), то выполняется эхо-повтор изображения для пользователя, а при использовании дополнительного параметра, представляющего собой путь к файлу, адресом назначения выходного потока становится файл
Функция уничтожения изображения ImageDestroy() Принимает в качестве параметра дескриптор изображения и освобождает все ресурсы, связанные с изображением

Поддержка средств передачи изображений в протоколе HTTP

Для того чтобы изображение могло быть представлено должным образом в браузере пользователя, необходимо указать, откуда должно поступить изображение и каков его формат. Поэтому, к сожалению, невозможно просто внедрить, например, вызов функции imageToPng() в создаваемый файл HTML и тем самым решить задачу вывода изображения. По сути, приходится чередовать код вывода изображений с кодом HTML, формируемым в сценарии PHP, и для этого можно воспользоваться одним из трех описанных ниже вариантов.

Создание полностраничных изображений

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

Преимущество данного подхода состоит в том, что для передачи указаний о составе будущего изображения можно применять любую информацию, включая параметры POST. А его недостаток заключается в том, что результирующая страница не может содержать какого-либо обычного кода HTML. В действительности приходится даже следить за тем, чтобы перед заголовком и изображением в сценариях не передавался какой-либо текстовый вывод, поскольку такая ситуация равносильна преждевременной отправке информационного наполнения. В этом случае появляется сообщение об ошибке «Headers already sent. «.

Внедрение изображений, хранящихся в файлах

Прежде всего отметим, что в языке HTML поддерживается дескриптор , который позволяет внедрить изображение, указывая путь к файлу изображения или URL, как в следующем примере:

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

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

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

Внедрение изображений, формируемых в сценариях

Наконец, нет таких причин, по которым нельзя было бы предусмотреть автономный сценарий формирования изображения, а затем внедрять полученное изображение в динамическую страницу, создаваемую с помощью другого сценария, задавая в дескрипторе URL этого сценария. При этом единственная сложность состоит в выборе способа передачи необходимых данных на зависимую страницу. Например, дескриптор с указанием внедренного изображения может иметь такой вид:

В этом случае сценарий ballpage.php возвращает изображения PNG цветных шаров, находящихся в различных позициях рисунка.

Но при использовании указанного подхода могут возникать нарушения в работе, поскольку веб-серверы и браузеры иногда проверяют суффиксы обрабатываемых файлов и, получив результаты проверки, реагируют на них по-разному. Например, сценарию формирования изображения ballpage может потребоваться присвоить расширение .php для того, чтобы сервер Apache мог определить, что данный серверный код должен интерпретироваться как код PHP (хотя необходимый режим обработки может быть задан и с помощью файлов конфигурации).

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

Ниже рассматриваются примеры применения библиотеки gd для создания изображений.

Пример использования библиотеки gd: создание простых фигур

В следующем примере мы покажем как с использованием библиотеки gd сгенерировать рисунок содержащий простые геометрические фигуры:

Пример использования библиотеки gd: фрактальные изображения

Уже сложилась замечательная традиция украшать изложение темы вычерчивания линий, которая в принципе может показаться неинтересной, используя в качестве примера фракталы. Рассматриваемый ниже пример не только показывает, как создать сложное изображение программным путем, но и служит хорошей демонстрацией возможностей языка PHP. Дело в том, что массивы и нестрого заданные типы данных этого языка позволяют очень легко создавать сложные структуры данных, соответствующие фрактальным изображениям, не применяя большого количества объявлений.

Фрактал представляет собой геометрическую форму, подобную самой себе. Это означает, что части фрактала имеют форму, подобную всему фракталу, части этих частей также имеют подобную форму, и т.д.

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

Пример изображения такого типа, которое мы попытаемся создать, приведен на рисунке ниже:

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

Наша задача состоит в том, чтобы вычислить координаты конечных точек всех этих отрезков прямых, а затем представить все отрезки должным образом в виде изображения PNG. Мы могли бы просто собрать один фрагмент фрактального изображения, но решили поставить перед собой более сложную задачу — не только обеспечить вывод изображения фрактала, но и сформировать небольшую инфраструктуру, позволяющую легко варьировать параметры фрактала и создавать изображения новых типов.

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

  • точка в системе координат задается парой чисел;
  • путь представляется в виде списка точек.

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

Теперь рассмотрим вопрос о том, как должны быть представлены точки и ломаные линии. Проще всего списки объектов можно представить в языке PHP с использованием массивов. Поэтому возьмем за основу то, что точка — это массив, который включает два числа, а ломаная линия — массив, который включает ряд точек. В результате реализации этого подхода должны быть созданы структуры, представляющие собой многомерные массивы PHP, но если нам удастся определить конструктор и функции доступа с легко запоминающимися именами, то можно забыть о том, насколько сложны эти структуры, и просто разрабатывать код, используя такие операции, как если бы эти структуры представляли собой настоящие типы данных.

Код создания изображения, показанного на рисунке выше, приведен ниже. В нем типы данных определяются в терминах функций их создания (имена которых начинаются с префикса make), функций, предназначенных для доступа к компонентам структур данных, и функций, обеспечивающих вывод изображения на основе данных (имена этих функции начинаются с префикса display). При использовании этого подхода вывод точек на экран не предусматривается, поэтому для них не предусмотрены функции вывода, а ломаные линии вычерчиваются путем вычерчивания отрезков прямых между следующими друг за другом парами точек.

Функция transform_path() принимает в качестве первого параметра исходное определение ломаной линии, а в качестве второго параметра — имя функции, которая, в свою очередь, принимает в качестве параметра определение ломаной линии и возвращает в качестве результата определение трансформированной ломаной линии. Третьим параметром функции transform_path() является значение кратности последовательного применения этой функции преобразования одной ломаной линии в другую для создания новой ломаной линии. Причина, по которой оказалось целесообразным введение подобной функции второго порядка, состоит в том, что в противном случае могло бы потребоваться создавать все новую и новую функцию циклической обработки каждый раз, когда потребовалось бы сформировать новый фрактал. Использование такого подхода позволяет увязывать различные части кода формирования фрактала в отдельную функцию, которую можно передать в функцию transform_path() и избежать дублирования работы.

Функция spike принимает в качестве параметра определение ломаной линии и возвращает другое определение ломаной линии, в котором каждый отрезок прямой, проходящий через две точки, заменяется ломаной линией, проходящей через пять точек, в середине которых изображен пик. А функция top-hat выполняет примерно аналогичное действие, за исключением того, что результирующая ломаная линия проходит через шесть точек и формируемый пик имеет прямоугольную форму. Кроме того, в этот пример включено еще несколько функций для создания ломаных линий со стандартными размерами, в которых углы между отрезками являются прямыми; эти функции предназначены для использования в качестве типичных образцов.

После загрузки определений всех функций из включаемых файлов в этом коде создается изображение gd с заданной высотой и шириной, а затем в этом изображении распределяются цвета. (Фон имеет белый цвет, а отрезки прямых — черный.)

Выполнение кода формирования фрактального изображения начинается с создания стандартной замкнутой ломаной линии прямоугольной формы, проходящей через пять точек и поэтому включающей четыре (неявно заданных) отрезка прямых. Затем это определение ломаной линии передается в функцию transform_path() в виде вызова этой функции с параметрами, которые указывают, что должно быть возвращено определение ломаной линии, ставшей результатом четырехкратного применения функции spike() к заданному прямоугольнику. Трансформация замкнутой ломаной линии прямоугольной формы начинается с обработки четырех отрезков прямых, и каждый отрезок заменяется четырьмя отрезками. Поэтому в результате четырех последовательных итераций формируются соответственно 16, 64, 256 и 1024 отрезка.

После этого остается только вывести сформированную сложную замкнутую ломаную линию на экран. Для вычерчивания всех отрезков прямых на изображении вызывается определенная в этом коде функция display_path(), передается заголовок HTTP, указывающий, что далее следует изображение PNG, вызывается функция imagepng() для преобразования и вывода, а затем внутреннее определение изображения gd уничтожается:

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

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

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

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

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

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

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

Смотрите также:


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

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

Гляньте, установлена ли у вас графическая библиотека GD2. Например в localhost/phpinfo.php.

Установлена. Уже разобрался, все рисует

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

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

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

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

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

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

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

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

Думаю на скорую руку избавиться от этого нотиса можно поставив @ перед вероятно пустой переменной.

Трехосные легко нагугливаются так 3d graphics php. Найдутся php-классы, реализующие например такие картинки:

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

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

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

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

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

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 значения, но почему они начинаются не с самого начала?

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

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

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

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

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

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

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

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

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

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

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

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

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

Создание диаграмм, используя библиотеку FusionCharts

Дата публикации: 2015-03-09

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

Установка библиотеки

Первым делом установим библиотеку FusionCharts, для этого переходим на официальный сайт http://www.fusioncharts.com/ и кликаем по ссылке Download Free Trial:

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Тем самым переходим на страницу скачивания версии Trial.

Библиотека распространятся в двух версиях – это платная и бесплатная Trial версия. Версия Trial предназначена для некоммерческого использования, и не имеет ни каких ограничений (как временных, так и по функционалу) по сравнению с платной версией. За исключением того, что в бесплатной версии, на всех диаграммах, присутствует логотип компании создателя данной библиотеки. Далее вводим имя и адрес электронной почты и получаем возможность скачать данную библиотеку. После скачивания необходимо подключить библиотеку к Вашему сайту.

Для сегодняшнего урока мы будем базу данных fusion, с единственной таблицей rash, в которой хранятся данные о расходах компании за текущий год (в таблице нас интересуют поля month и summa):


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

Проблема генерации динамической круговой диаграммы GD PHP

Я создал динамическую круговую диаграмму с расширением GD, используя функцию дуги, заполненную изображением. Я перехожу к этому script, через переменные HTTP GET, до 11 значений. первое значение, n, — это число следующих значений. n1, n2, n3 и т.д. являются самими данными. Это целые преваленты. Цель состоит в том, чтобы составить график, который будет показывать проценты в круговой диаграмме в графической форме.

Когда я запускаю это как:

piechart.php п = 2 &? N1 = 20 & п2 = 80

Я получаю только черный ящик. Есть идеи? Любые вопросы, пожалуйста, спросите — спасибо!

Вот где это происходит:

В PHP вы не можете сравнивать значения с NULL с помощью $var == NULL, вы должны использовать функцию is_null:

Что это такое — получить значение $darkColorR [$ i] и проверить, является ли оно NULL. Я думаю, что в вашем случае вы пытаетесь проверить, имеет ли массив запись для этого конкретного индекса, что совсем другое. Вы можете использовать функцию isset, чтобы проверить, имеет ли массив запись с заданным индексом:

Объединяя это вместе, вы получите следующий код:

ничего общего с вашей проблемой, но вы можете заглянуть в API Google Chart, было бы проще создать диаграмму с ней.

Создание круговой диаграммы средствами библиотеки GD на PHP

Загрузить модуль GD можно по адресу www.boutell.com/gd. Для его подключения необходимо убрать знак комментария в строке extension=php_gd.dll (для сервера с ОС Windows; в случае Unix-систем расширение файла может быть другим) в php.ini и перезапустить веб-сервер. Различные версии GD могут работать с разными форматами графических файлов. Так, при использовании библиотеки версии 1.6 и ниже можно создавать изображения в форматах JPEG, GIF и SWF, но не PNG. Более новые версии позволяют использовать PNG, но отказываются поддерживать формат GIF из лицензионных соображений. Все приведенные ниже примеры будут работать при использовании GD версии 2.0.1 или выше.

Создание графического счетчика посещений

Важная особенность работы с модулем GD заключается в том, что скрипт, формирующий новый рисунок, не должен выводить что-либо кроме самого рисунка (то есть в нем не должно быть вызовов echo, printf и подобных им функций). Впоследствии изображение, сформированное PHP-скриптом, выводится браузером методом указания URL этого скрипта в качестве источника данных, например, .

Создание нового рисунка в PHP начинается либо с создания новой чистой «страницы» (canvas) для рисования, либо с загрузки и модификации уже существующего изображения. Но перед тем как начать процесс вывода графической информации, необходимо выбрать его формат (тип MIME) посредством вызова функции header(str). Например, для формата PNG необходимо использовать следующий код:

Далее для создания области для рисования необходимо вызвать функцию int imagecreate (int x_size, int y_size), которой передать в качестве параметров x_size и y_size, соответственно, ширину и высоту (в пикселах) формируемой картинки; при этом функция вернет идентификатор созданной области для рисования. Если же мы хотим взять за основу уже имеющуюся картинку, то, в зависимости от ее формата, нужно вызвать функцию imagepng, или imagejpeg, или imagegif, передав в качестве параметра имя файла-картинки. Для вывода текста существует функция int imagestring(int im, int font, int x, int y, string s, int col), которой нужно передать: идентификатор области рисования, размер шрифта (1-5), координату X начала текста, координату Y начала текста, сам текст и цвет текста соответственно. Для определения цвета используется конструкция вида

$white=ImageColorAllocate($im, 255, 255, 255)

Последние три числовых параметра — RGB-составляющие требуемого цвета. Но поскольку каждый раз указывать их несколько нерационально, следует создать include-файл с определениями основных цветов colors.inc:

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

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

JpGraph. Динамическая графика — это просто

Архив номеров / 2005 / Выпуск №1 (26) / JpGraph. Динамическая графика — это просто

Динамическая графика – это просто

Ещё каких-то лет пять назад человек, занимающийся разработкой сайтов, мог гордо именовать себя веб-мастером, не вызывая при этом иронических усмешек у коллег. В это понятие входили дизайн, вёрстка, веб-программирование, и в объявлениях о приёме на работу часто мирно уживались требования по знанию Perl и Photoshop. Теперь, разумеется, многое изменилось, и в резюме веб-программиста считается дурным тоном упоминать навыки работы с графическими пакетами, даже если таковые и присутствуют. Тем не менее если вы работаете в небольшом проекте, в бюджете которого не предусмотрен многочисленный штат сотрудников, то время от времени у вас может возникнуть необходимость в самостоятельном создании кое-какой графики – кнопочек, маркеров, пиктограмм, фоновых изображений, которые нужны для любого веб-интерфейса. В общем случае такие задачи решаются использованием готовой библиотеки изображений или приглашением знакомого дизайнера (как правило, за солидный гонорар – две, а то и три бутылки пива). Проблема, решение которой изложено ниже, не так стандартна и немного сложнее, хотя встречается не так уж редко.

Итак, представим, что вы разрабатываете/ведёте биллинг, или складскую систему, или… в общем, приложение, использующее базу данных и несущее достаточно сложную логику. Представим также (хотя это и сложнее), что никаких особых проблем у вас нет – приложение работает корректно, новая функциональность добавляется относительно легко, небольшие корректировки много времени не отнимают. В целом вы довольны, но кроме вас в офисе трудятся менеджеры, бухгалтеры, начальство, и вот у последнего возникают довольно своеобразные требования. В частности, шефа не устраивают ваши отчёты, генерирующиеся в виде аккуратных HTML-таблиц, ему нужны графики, причём графики красивые и ежедневно (ежечасно?!) обновляющиеся. Не рисовать же их руками?

К счастью, PHP-разработчик может воспользоваться таким мощным инструментом, как графическая библиотека GD, включаемая по умолчанию в дистрибутив, начиная с версии 4.0.1. Возможность попиксельной прорисовки и обработки изображения, манипуляции с размером картинки и текстом, наличие примитивов позволяют генерировать достаточно сложную графику. Проблема заключается в том, что на построение качественного графика или диаграммы уйдет довольно много времени, а наша задача в данном случае – справиться с поручением в сжатые сроки и с минимальным количеством кода. Существует некоторое количество готовых библиотек для разработки графиков, например, автор этих строк в своё время использовал довольно удачную разработку – phplot (http://www.phplot.com), но безусловным лидером в этом отношении является объектно-ориентированная библиотека JpGraph.

Среди её преимуществ можно выделить возможность построения множества видов графиков, неограниченного числа графиков одного типа в одном изображении, сглаживание линий, заполнение фонов диаграмм и гистограмм градиентной заливкой, генерация карт-изображений и кэширование рисунков. Стандартная версия библиотеки бесплатна (существует и коммерческая версия pro, в которой доступны некоторые дополнительные возможности, в частности, построение штрих-кодов). В статье речь пойдет о стандартной версии, о возможностях коммерческой читатель может ознакомиться на сайте производителя – http://www.aditus.nu/jpgraph/jpg_proversion.php. Ещё одним достоинством этого продукта является прекрасная документация, идущая вместе с дистрибутивом. На самом деле подробность документации ставит под сомнение необходимость чтения этой статьи, но автор этих строк, как наверняка и кто-нибудь из вас, попадал в ситуацию, когда времени на обстоятельное изучение руководства просто нет, и я попытался изложить этот материал для того, чтобы программист по его прочтении мог немедленно приступить к работе.

Для примера возьмём вполне реальную проблему из практики небольшого интернет-провайдера. Необходимо написать скрипт, строящий график распределения входящего трафика по дням за определённый период (скажем, за последние десять дней). Естественно, график должен строиться динамически и генерироваться по запросу на внутреннем веб-сайте компании. Будем считать, что веб-сервер с поддержкой PHP уже установлен.

Все нижеописанные действия проводились на веб-сервере Apache версии 1.3.31 (Win32), работающем под управлением Windows 2000 Server. Версия интерпретатора PHP – 4.3.9 с поддержкой библиотеки GD2, версии 2.0.28. PHP был установлен как модуль.

В целом установка библиотеки JpGraph никаких сложностей не вызовет. Нужно просто скачать архив с библиотекой, расположенный по адресу http://www.aditus.nu/jpgraph.php, и распаковать его в папку документов вашего веб-сервера. До установки следует убедиться, что PHP у вас версии не ниже 4.01 (рекомендуется 4.3х) и скомпилирован с поддержкой библиотеки GD (для доступа к последним возможностям JpGraph, GD2).

Графические форматы, с которыми работает библиотека, определяются возможностями установленной GD и автоматически выбираются JpGraph в следующем порядке: «PNG», «GIF», «JPG».

Для проверки установки GD руководство по JpGraph рекомендует следующий простой сценарий:

$im = ImageCreate (50, 100)

or die («Cannot create a new GD image.»);

$background_color = ImageColorAllocate ($im, 255, 255, 255);

$text_color = ImageColorAllocate ($im, 233, 14, 91);

ImageString ($im, 1, 5, 5, «A Simple Text String», $text_color);

header («Content-type: image/png»);

Если тест прошёл удачно и изображение было создано, можно устанавливать библиотеку и начинать работу, но для реализации поставленной задачи необходимо выполнить ещё несколько действий. Прежде всего вы должны обеспечить поддержку TTF-шрифтов (они нам обязательно понадобятся, об этом далее). Для этого PHP должен быть собран с поддержкой TTF, а также с FreeType 1 или FreeType 2 библиотеками, и несколько (как минимум два) шрифтов установлены в системе.

Следующий этап – настройка нелатинских шрифтов. Понятно, что в данном случае необходимости в китайских символах у нас нет, а для использования кириллицы необходимо отредактировать файл jpg-config.inc. В нём имеются следующие настройки:

$im = ImageCreate (50, 100)

or die («Cannot create a new GD image.»);


$background_color = ImageColorAllocate ($im, 255, 255, 255);

$text_color = ImageColorAllocate ($im, 233, 14, 91);

ImageString ($im, 1, 5, 5, «A Simple Text String», $text_color);

header («Content-type: image/png»);

После установки значений обоих параметров в true необходимо убедиться, что на сервере имеются стандартные юникодные шрифты (обычно они лежат в директории типа /usr/X11R6/lib/X11/fonts/TTF/) и проверить, поддерживают ли они кириллицу. В случае их отсутствия шрифты следует установить, например с Windows-машины (должен заметить, что при установке под Windows проблем с кириллицей вообще не возникает). После этого в том же файле jpg-config.inc следует прописать путь к шрифтам:

Теперь всё готово. Для проверки и ознакомления с возможностями инструмента раскроем в браузере файл src/examples/testsuit.php из дистрибутива библиотеки. Мы увидим около трёхсот графиков диаграмм и рисунков, кликнув по каждому из которых, можно увидеть исходный код примера. Самый лёгкий способ начать работу с библиотекой – взять наиболее подходящий пример и методом «научного тыка» подогнать его под свои нужды. Когда передо мной встала необходимость быстро построить график, я так и сделал, но, разумеется, для полноценной работы с библиотекой необходимо разобраться в её свойствах и методах, поэтому далее мы будем строить график «с нуля».

Приступаем к работе (простой график)

Прежде всего определимся с исходными данными. Разумеется, в реальных условиях они будут извлекаться из базы данных, но чтобы не усложнять задачу, мы просто создадим два массива, первый из которых будет состоять из чисел месяца, а второй – из соответствующих им показателей входящего трафика.

$traff = array(350, 280, 450, 615, 588,755, 547, 320, 380, 810); // трафик (Мб)

$days = array (9, 10, 11, 12, 13, 14, 15, 16, 17, 18); // даты

Для построения графика используем следующий код:

$graph = new Graph(450, 200,»auto»);

$lineplot =new LinePlot($traff);

Если всё установлено правильно, в результате должна получиться картинка, показанная на рис. 1 (пример дан в предположении, что ваш скрипт test.php расположен в папке src/examples/, если это не так, отредактируйте пути к библиотеке).

Конечно, это ещё довольно далеко от желаемого результата, но давайте сначала разберёмся в том, что мы уже сделали.

В первых двух строчках кода мы подключаем базовую библиотеку jpgraph.php и один из модулей (plot extensions), в данном случае это jpgraph_line.php, необходимый для построения линейных графиков. Затем создаём объект класса Graph, задав его размеры, и выбираем масштаб оси X (метод SetScale()). Потом создается объект класса plot (график), параметры которого задаются созданным нами ранее массивом, сохранённым в переменной $traff. В последних двух строчках график добавляется в объект Graph и методом Stroke() Graph выводится в браузер.

Данные по оси X должны соответствовать реальным датам. Для этого добавим строчку:

Теперь добавим заголовок и подписи к осям (для чего нам понадобится устанавливать шрифты).

Задача в первом приближении выполнена.

Теперь осталось добавить удобочитаемость. Выполняем следующие действия.

Устанавливаем отступы и поля для подписи к оси Y (поскольку с ней проблемы):

Добавляем маркеры и подписи к ним:

$lineplot->mark->SetType(MARK_IMG_DIAMOND, «blue», 0.3);

$lineplot->value->SetFormat(» %01.0f Mb»);

«Раскрашиваем» график, добавляем фон и тень:

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

Полный код, генерирующий эту картинку, приведен на сайте журнала http://www.samag.ru/source.

Всё, что осталось сделать, – это сохранить весь код в файле (например, my_graph.php) и в нужном месте веб-страницы вставить тег рисунка с указанием на этот файл (

Теперь давайте разберёмся с внутренним устройством библиотеки. Как уже было упомянуто, для построения любого изображения необходимо включить в сценарий основной модуль – файл jpgraph.php и один или несколько модулей, ответственных за построение изображения требуемого типа. Все они содержатся в папке src, хотя могут быть перенесены оттуда в любое удобное для вас место. (При этом, разумеется надо соблюдать некоторые зависимости. Так, внутренний модуль jpgraph_gradient.php никогда явно не подключается к сценарию, но используется другими модулями и без него не обойтись при генерации любого изображения, использующего градиентную заливку.) Ниже перечислены основные модули.

  • jpgraph_line.php – уже знакомое нам расширение для построения линейных графиков.
  • jpgraph_bar.php – модуль для построения баров (гистограмм).
  • jpgraph_log.php – модуль для отображения логарифмических зависимостей.
  • jpgraph_error.php – модуль для вывода графических сообщений об ошибках (для чего это нужно – далее).
  • jpgraph_pie.php – модуль для построения плоских диаграмм.
  • jpgraph_pie3d.php – модуль для построения 3D-диаграмм.
  • jpgraph_gantt.php – модуль для построения графиков Ганта.
  • jpgraph_radar.php, jpgraph_polar.php – модули позволяют строить «центростремительную графику».
  • jpgraph_regstat.php – модуль для построения сглаженных графиков.
  • jpgraph_scatter.php – модуль для отображения распределенных по плоскости элементов и векторов.
  • jpgraph_iconplot.php – модуль для работы с иконками, которые могут быть добавлены к графикам.
  • jpgraph_plotband.php – модуль для работы с группами данных на графиках.
  • jpgraph_canvas.php – модуль для возможности построения произвольных графиков.
  • jpgraph_canvtools.php – модуль для возможности построения произвольных форм.

С полным списком подключаемых модулей вы можете ознакомиться в соответствующем разделе документации.

В коммерческую версию библиотеки входят ещё несколько модулей, а именно:

  • jpgraph_windrose.php – модуль для построения розы ветров.
  • jpgraph_odo.php – модуль для отображения одометрических данных.
  • jpgraph_barcode.php – модуль для построения линейных штрих-кодов.
  • jpgraph_pdf417.php – модуль для построения штрих-кодов PDF417 2D.

Теперь, используя полученную информацию, посмотрим, на что ещё способна библиотека JpGraph.

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

Сначала представим исходные данные:

$traff = array(810,480, 550, 715, 688, 785, 847,902, 350, 280, 450, 615, 588,755, 547,320, 380); // трафик (Мб)

$days = array (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17); // даты

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

$spline = new Spline($days,$traff);

$g = new Graph(300,200);

$lplot = new LinePlot($newy,$newx);


Общая схема та же, что и в случае с простым графиком, но в данном случае мы создаём объект Spline(), описанный в модуле jpgraph_regstat.php. Быть может, результат не очень впечатляет, но довести его до приличного вида большого труда не составит.

Добавим на график маркеры, соответствующие точным значениям трафика, и нарисуем координатную сетку. Сначала подключим ещё один модуль:

Теперь расставляем маркеры:

$splot = new ScatterPlot($traff, $days);

И координатную сетку:

Указанное в заголовке представление данных было бы как раз наиболее уместным в предыдущем случае, но мы, следуя наказам менеджмента, используем эту визуализацию несколько для другого – для отображения количества подключённых клиентов. Опять берём два массива:

$pepl = array(8, 16, 10, 7, 4,12, 7,15, 11, 22); // количество подключений

$days = array (9, 10, 11, 12, 13, 14, 15, 16, 17, 18); // даты

И строим простую гистограмму:

$graph = new Graph($width,$height,»auto»);

$bplot = new BarPlot($pepl);

Собственно, это и всё. Немногим отличается от предыдущих примеров. Всего несколько строк кода, а результат уже почти годен к употреблению. Сделаем его пригодным окончательно.

Сначала добавим подписи к столбцам и заголовки:

Теперь сделаем картинку немножко привлекательней:

Я не думаю, что данный код требует каких-либо объяснений. Всё вполне интуитивно понятно.

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

Для демонстрации этой возможности также не будем далеко уходить от реальности. Пусть на круговой диаграмме необходимо отобразить распределение потребляемого трафика. Допустим, что трафик, израсходованный физическими лицами за текущий месяц, составил 54.36 Гб, юридическими – 64.57 Гб, и, наконец, 6.75 Гб ушли на внутренние нужды провайдера. Следующими несколькими строчками кода (обратившись к расширению PieGraph) рисуем простую круговую диаграмму:

$data = array(54.36, 64.57, 6.75);

$graph = new PieGraph(300,200);

$p1 = new PiePlot($data);

Результат показан на рис. 8. Как видите, проценты реализации библиотека вычисляет сама (мелочь, а приятно).

Добавляем заголовок и для пояснения создаем легенду (пояснения к диаграмме или карте, иначе говоря «условные обозначения»). Легенду можно добавить практически ко всем объектам JpGraph, она представляет собой самостоятельный объект:

$legends = array(«Физ лица»,»Юр Лица»,»Служебный»);

Результат вполне информативен (рис. 9), но, как и в предыдущих примерах, для красоты придадим диаграмме объем и выделим служебный трафик.

Нужно заметить, что для работы следующего кода необходима вторая версия библиотеки GD, но так как в дистрибутив PHP в настоящее время входит расширение GD2, это обстоятельство проблем создать не должно.

Для начала подключаем ещё один модуль:

Заменяем вид диаграммы:

//$p1 = new PiePlot($data);

$p1 = new PiePlot3D($data);

Выделяем служебный трафик:

Изменяем цвета по умолчанию:

Наконец, убираем совершенно неуместную в данном случае рамку:

Полученный результат, думается, годится для представления.

Любой программист, работавший с библиотекой GD, знает, как сильно генерация изображений потребляет системные ресурсы. Если подобный график требуется создавать раз в сутки – ничего страшного, но если в вашем офисе десяткам менеджеров требуются эти данные ежеминутно, создание графиков на лету порождает серьёзные проблемы с производительностью. Поэтому нельзя переоценить ещё одну впечатляющую возможность JpGraph – управляемое кэширование изображений. Под этим термином здесь подразумевается сохранение созданного изображения на сервере, на заранее заданный период времени. В самом деле, данные по ежедневному трафику обновляются раз в сутки, соответственно более одного раза за 24 часа создавать изображение не имеет смысла. Для этого в объявлении нового класса указываем (кроме размеров графа) имя файла, в котором будет сохранено изображение, и период актуальности данного кэша в минутах:

$graph = new Graph(450, 200, «traf”, 1464, true);

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

Сообщения об ошибках

Если при обращении к какому-либо объекту или методу библиотеки была допущена ошибка, в браузер вместо изображения отправляется графическое сообщение об ошибке, аналогичное показанному на рис. 10.

Для чего это нужно? Всё просто. Основной способ передачи изображений, созданных JpGraph, – использование тега . Если бы не этот механизм, в случае возникновения вышеописанной ошибки в браузер выводилось бы не привычное для разработчика сообщение, а рамка отсутствующего рисунка, которая, разумеется, жизнь программисту никак не облегчает. Более того, при работе с библиотекой имеет смысл писать свои обработчики ошибок с графическим выводом (благо её возможности это вполне позволяют) к таким распространённым сбоям, как неудачный запрос к базе данных или неполадки при работе с файловой системой.

Что в перспективе

Библиотека JpGraph живёт и развивается, обрастая новыми модулями. Неожиданное препятствие на пути её использования возникло в связи с переходом разработчиков на пятую версию языка PHP с совершенно другой объектной моделью. Это общая проблема любых ОО-библиотек, заточенных под PHP 4. Язык обрёл новые возможности, но, как это нередко бывает, потерял частично обратную совместимость.

Так, уже первый пример из скрипта tessuit.php на новом движке выдаёт ошибку. Что делать? Можно, конечно, подправить код библиотеки (причём, скорее всего, отказавшись от некоторых возможностей), но можно и немного подождать. Создатели JpGraph держат руку на пульсе прогресса, и уже доступна альфа-версия библиотеки JpGraph 2, ориентированная на пятую версию PHP (вернее, на новую объектную модель). Мне кажется, что внесенные изменения не будут препятствовать разработчикам, а напротив, помогут освоить новые горизонты.

Конечно, в этой статье я осветил лишь небольшую часть воз-можностей JpGraph. За кадром остались использование карт-изображений (image-map), генерация текста, работа с готовой графикой, с фоновыми изображениями и многое другое. Изучить их несложно.

Как уже упоминалось, JpGraph – не единственное средство для работы с графикой на PHP. Широко распространены такие инструменты, как мощнейший по возможностям, но, к сожалению, коммерческий пакет для работы с деловой графикой ChartDirector, или библиотека по работе с готовыми изображениями ImageMagic.

Наличие таких средств обработки графики, конечно, ещё не повод исключить из процесса «сайтостроительства» дизайнера, но возможность иногда обойтись кодом без участия дорогостоящих графических пакетов весьма приятна.

Илон Маск рекомендует:  ShortDayNames - Переменная Delphi
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Рубрика: Программирование / Анализ данных