Использование HTML-таблиц для вывода диаграмм

Автор: Topol Суббота, Август 11th, 2012 Нет комментариев

Рубрика: Perl

Введение

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

Обычно «графический» вывод CGI-скрипта организуется путем формирования скриптом рисунка в одном из форматов веб-графики (чаще всего GIF или PNG) и вставки ссылки на этот рисунок <IMG src=»…»> на выводимую HTML-страничку.

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

Все это осложняется еще и тем, что алгоритм сжатия данных LZW, используемый в GIF, является в настоящее время патентованным и небесплатным для использования. Иными словами, разработчики «железа» и ПО, которые используют данный алгоритм, должны платить патентные отчисления фирме-держателю патента. А поскольку такой порядок вещей совершенно неприемлем для разработчиков бесплатного ПО, то разработанные графические библиотеки либо вовсе не поддерживают формат GIF, либо поддерживают только формирование «несжатых» GIF-файлов.

Однако обязательно ли для вывода диаграмм на HTML-странице использовать «настоящую» графику? Нет ли «альтернативных способов»? И вообще, является ли использование графики лучшим и оптимальным путем вывода диаграмм?

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

Теория

Как известно, язык HTML позволяет управлять практически всеми параметрами таблиц. Суть предлагаемого метода заключается в том, что HTML-таблицу можно «сформировать» таким образом, что она будет выглядеть как вполне приличная диаграмма.

Например, так:

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

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

Поскольку в горизонтальной диаграмме каждый столбец диаграммы представлен строкой таблицы, то далее, чтобы не внести путаницы, столбец таблицы я буду называть «столбец», а столбец диаграммы — «столбик». :-)

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

От теории к практике

Итак, как же нужно сделать таблицу, чтобы она выглядела как диаграмма?

В простейшем случае в качестве диаграммы можно построить таблицу с двумя ячейками в каждой строке. Первая ячейка будет собственно столбиком диаграммы (она видима и отображается нужным цветом или background-ом), а вторая — невидимая. Как известно, броузер отображает только те ячейки таблицы, у которых есть содержимое (непустые). Поэтому для того, чтобы сделать видимой первую ячейку-»столбик», в нее нужно поместить, по крайней мере, символ &nbsp;

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

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

Из этого положения есть два выхода:

  • Использовать для разных столбиков диаграммы разные таблицы, каждая из одной строки.
  • Использовать возможность объединения ячеек: для каждой ячейки HTML-таблицы можно задать, на сколько строк и/или на сколько столбцов она «распространяется» (параметры rowspan и colspan тэга <TD>соответственно).

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

Пример: для отображения диаграммы со столбиками 100, 300 и 400 пикселей нам нужно построить таблицу с ширинами столбцов 100, 200 и 100. Первый столбик диаграммы «займет» один столбец таблицы, второй — два и третий — три. Соответственно, вторая, невидимая ячейка займет столько столбцов, сколько осталось.

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

Пример скрипта

А теперь рассмотрим практический пример скрипта для «табличного» вывода диаграммы.

#!/usr/bin/perl #Исходные данные для вывода диаграммы #массив $data - данные для вывода (уже в пикселях). #$val - количество выводимых столбцов (соотв количеству элементов $data). $data[1]=200; $color[1]="#FF0000"; $data[2]=100; $color[2]="#00FF00"; $data[3]=150; $color[3]="#0000FF"; $data[4]=400; $color[4]="#00FFFF"; $data[5]=500; $color[5]="#FF00FF"; $data[6]=600; $color[6]="#FFFF00"; $val=6; #Ниже расположен код сортировки выводимых на диаграмме значений #В процессе его работы на основе массива @data создается отсортированный #массив @stp и хэш %lvl с количеством столбцов таблицы для каждого #столбика диаграммы $rows=1; $stp[0]=0; $stp[1]=$data[1]; $lvl{$data[1]}=1; $i=2; while($i<=$val){ $p=0; $x=1; while($x<=$rows && $p==0) { if ($data[$i]==$stp[$x]){$p=1;$lvl{$data[$i]}=$x;goto a1;}; if ($data[$i]<$stp[$x]){ #Вставка нового значения "в середину" массива @stp for ($y=$rows+1;$y>=$x;$y=$y-1){$stp[$y+1]=$stp[$y];}; $stp[$x]=$data[$i]; #Корректируем хэш %lvl с учетом "сдвига" @stp foreach $itm(keys %lvl){if ($lvl{$itm}>=$x){$lvl{$itm}=$lvl{$itm}+1;};}; $lvl{$data[$i]}=$x; $rows=$rows+1; $p=1; }; $x++; }; if ($p==0){$rows=$rows+1;$stp[$rows]=$data[$i]; $lvl{$data[$i]}=$rows}; $i++; }; #А здесь мы, собственно, выводим таблицу print "Content-Type: text/htmlnn"; print "<TABLE border=0>n<TR>"; #Выводим первую строку таблицы, задающую броузеру нужные ширины ячеек #Она не будет отображаться, т.к. ячейки пустые for ($k=1;$k<=$rows;$k=$k+1){ $w=$stp[$k]-$stp[$k-1]; print "<TD width=$w></TD>"; }; print "</TR>n"; #Выводим строки, содержащие диаграмму for ($v=1;$v<=$val;$v=$v+1){ $tl=$lvl{$data[$v]}; $rst=$rows-$tl; print "<TR>"; #Если видимая ячейка есть (выводимое значение не 0: $tl>0), #то выводим ее: if ($tl>0) {print "<TD bgcolor=$color[$v] colspan=$tl> </TD>";}; #Если невидимая ячейка есть (выводимое значение не равно максимальному), #то выводим ее: if ($rst>0) {print "<TD colspan=$rst></TD>";}; print "</TR>n"; }; print "</TR></TABLE>";

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

Допустим, нам надо вывести результаты голосования, которые передаются в переменных $za, $prot, $vozd в значениях процентов.

$width=400; #Желаемая ширина диаграммы $data[1]=($za/100)*$width; $data[2]=($prot/100)*$width; $data[3]=($vozd/100)*$width; $val=3;

 

Управление толщиной столбцов

В ряде случаев Вам может понадобиться явно задать толщину столбиков диаграммы, т.е. высоту строк таблицы. И здесь Вам встретится еще один «подводный камень» данного решения. Дело в том, что параметры width и height тэга <TD> задают не однозначные, а минимальные значения ширины и высоты ячейки таблицы. Т.е. если «по содержимому» ячейка меньше, чем указано в параметрах width и height, то она «растягивается» до нужных размеров.

Наш пример вообще не задает в тэгах <TD> параметр height, поэтому высота ячеек таблицы определяется размерами шрифта, которым «написан» символ &nbsp; в видимой ячейке (несмотря на то, что это символ пробела, он, как и любой другой символ, имеет свою высоту) и отступом между «абзацем» и границами ячейки. Соответственно, если не принять дополнительных мер, то на разных страницах и у разных посетителей выглядеть несколько по-разному.

«Общим видом решения» этой задачи является минимизация собственной высоты ячейки и задание ее высоты с помощью параметра height тэга <TD>.

Самым «радикальным» способом уменьшения высоты является помещение в видимую ячейку вместо & нетекстового содержимого, скажем, картинки размером 1×1 пиксель:

<IMG width=1 height=1 src="trans.gif">

а в trans.gif поместить прозрачное изображение в 1 пиксель.

Тогда «собственная» высота ячеек получится очень мала (несколько пикселей) и параметром height и Вы сможете однозначно задавать высоту ячеек таблицы-диаграммы, а следовательно, и толщину столбиков.

Еще одним способ уменьшить «собственную» высоту ячеек — максимально уменьшить размер шрифта в «видимой» ячейке.

Источник:  internet-technologies.ru

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

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты