Использование HTML-таблиц для вывода диаграммВведениеПри разработке некоторых видов скриптов, в частности - скриптов голосований, бывает желательно организовать в них наглядный вывод тех или иных статистических данных в виде диаграммы. Обычно "графический" вывод CGI-скрипта организуется путем формирования скриптом рисунка в одном из форматов веб-графики (чаще всего GIF или PNG) и вставки ссылки на этот рисунок <IMG src="..."> на выводимую HTML-страничку. Однако написание программного кода по формированию рисунков представляет значительные трудности, особенно для начинающих программистов, т.к. это предполагает либо доскональное изучение довольно сложных форматов графических файлов, либо использование библиотек для работы с графикой, написанных другими. Все это осложняется еще и тем, что алгоритм сжатия данных LZW, используемый в GIF, является в настоящее время патентованным и небесплатным для использования. Иными словами, разработчики "железа" и ПО, которые используют данный алгоритм, должны платить патентные отчисления фирме-держателю патента. А поскольку такой порядок вещей совершенно неприемлем для разработчиков бесплатного ПО, то разработанные графические библиотеки либо вовсе не поддерживают формат GIF, либо поддерживают только формирование "несжатых" GIF-файлов. Однако обязательно ли для вывода диаграмм на HTML-странице использовать "настоящую" графику? Нет ли "альтернативных способов"? И вообще, является ли использование графики лучшим и оптимальным путем вывода диаграмм? В этой статье я предлагаю "альтернативный способ" вывода столбчатых (линейных) диаграмм, основанный на HTML-таблицах. Этот способ, по моему мнению, отличается сравнительной (а по сравнению с формированием графики - значительной) простотой реализации и хорошим качеством "результата".
ТеорияКак известно, язык HTML позволяет управлять практически всеми параметрами таблиц. Суть предлагаемого метода заключается в том, что HTML-таблицу можно "сформировать" таким образом, что она будет выглядеть как вполне приличная диаграмма. Например, так:
При этом разработчик ценой минимальных усилий может придать диаграмме практически любой вид - изменить цвета столбцов (или даже залить их рисунком), их ширину, расстояние между ними и т.д. Можно даже написать на столбцах текст. Причем все это делается только лишь изменением параметров и содержимого ячеек выводимой таблицы, а вся "техническая" нагрузка по формированию на экране пользователя таблицы нужного вида ложится на "плечи" броузера. Выводимая диаграмма может быть горизонтальной или вертикальной. Далее мы в этой статье будем рассматривать горизонтальные диаграммы как наиболее простые и более наглядно иллюстрирующие идею. Поскольку в горизонтальной диаграмме каждый столбец диаграммы представлен строкой таблицы, то далее, чтобы не внести путаницы, столбец таблицы я буду называть "столбец", а столбец диаграммы - "столбик". :-) Вывод CGI-скрипта, формирующего такую диаграмму, может быть вставлен в страницу с помощью SSI или IFRAME. При этом надо иметь в виду, что диаграмма, вставленная на страницу через SSI, является частью самой страницы и, следовательно, сохраняется/отображается/кэшируется вместе с ней. В одних случаях это преимущество, в других - недостаток. Еще одним недостатком этого метода (на практике - не очень существенным) является то, что таблицу, в отличие от рисунка, нельзя масштабировать.
От теории к практикеИтак, как же нужно сделать таблицу, чтобы она выглядела как диаграмма? В простейшем случае в качестве диаграммы можно построить таблицу с двумя ячейками в каждой строке. Первая ячейка будет собственно столбиком диаграммы (она видима и отображается нужным цветом или background-ом), а вторая - невидимая. Как известно, броузер отображает только те ячейки таблицы, у которых есть содержимое (непустые). Поэтому для того, чтобы сделать видимой первую ячейку-"столбик", в нее нужно поместить, по крайней мере, символ Общая ширина этих двух ячеек для каждой строки должна быть одинакова (ширина таблицы), а количество строк соответствует количеству столбиков диаграммы (числу отображаемых значений). И тут начинаются наши первые "подводные камни" на светлом пути к великой цели :-). Дело в том, что броузер не может "просто так", без ухищрений, построить таблицу, у которой в каждой строчке значения ширины столбцов разные! Для каждой выводимой таблицы броузер вычисляет ширины столбцов (одинаковые для каждой строки) и высоты строк (одинаковые для каждого столбца). Из этого положения есть два выхода:
Во втором случае необходимо построить таблицу, у которой ширины столбцов соответствуют разности между соседними по величине отображаемыми значениями, а нужную ширину видимой ячейки-"столбика" в каждой строке получать "распространением" первой ячейки на нужное количество столбцов. Пример: для отображения диаграммы со столбиками 100, 300 и 400 пикселей нам нужно построить таблицу с ширинами столбцов 100, 200 и 100. Первый столбик диаграммы "займет" один столбец таблицы, второй - два и третий - три. Соответственно, вторая, невидимая ячейка займет столько столбцов, сколько осталось. Соответственно, программный код по формированию "таблицы-диаграммы" должен включать в себя алгоритм сортировки отображаемых значений и вычисления нужных ширин столбцов таблицы.
Пример скрипта
А теперь рассмотрим практический пример скрипта для "табличного"
вывода диаграммы.
Т.к. приведенный здесь программный код в качестве исходных данных использует уже "готовые" значения в пикселах (а не собственно выводимые величины в их исходном виде), то перед его использованием необходимо преобразовать выводимые величины (скажем, проценты) в количества пикселей с учетом желаемой ширины диаграммы.
Допустим, нам надо вывести результаты голосования, которые передаются
в переменных $za, $prot, $vozd в значениях процентов.
Управление толщиной столбцовВ ряде случаев Вам может понадобиться явно задать толщину столбиков диаграммы, т.е. высоту строк таблицы. И здесь Вам встретится еще один "подводный камень" данного решения. Дело в том, что параметры width и height тэга <TD> задают не однозначные, а минимальные значения ширины и высоты ячейки таблицы. Т.е. если "по содержимому" ячейка меньше, чем указано в параметрах width и height, то она "растягивается" до нужных размеров. Наш пример вообще не задает в тэгах <TD> параметр height, поэтому высота ячеек таблицы определяется размерами шрифта, которым "написан" символ в видимой ячейке (несмотря на то, что это символ пробела, он, как и любой другой символ, имеет свою высоту) и отступом между "абзацем" и границами ячейки. Соответственно, если не принять дополнительных мер, то на разных страницах и у разных посетителей выглядеть несколько по-разному. "Общим видом решения" этой задачи является минимизация собственной высоты ячейки и задание ее высоты с помощью параметра height тэга <TD>. Самым "радикальным" способом уменьшения высоты является помещение в видимую ячейку вместо & нетекстового содержимого, скажем, картинки размером 1x1 пиксель: <IMG width=1 height=1 src="trans.gif"> а в trans.gif поместить прозрачное изображение в 1 пиксель. Тогда "собственная" высота ячеек получится очень мала (несколько пикселей) и параметром height и Вы сможете однозначно задавать высоту ячеек таблицы-диаграммы, а следовательно, и толщину столбиков. Еще одним способ уменьшить "собственную" высоту ячеек - максимально уменьшить размер шрифта в "видимой" ячейке.
© Андрей Черный, 2005 |