Последние статьи
Дефицит идей.На данный момент в сайтостроении, да и как везде, в общем то, наблюдается некий застой в решениях. Для сайтов...
Yandex с блекждеком и шлюхами.Как то размышляя о способах монетизации различных веб-проектов, я увидел некоторую нестыковку на...
Flash: построение графика с динамическим обновлением данных.До того, как я открыл для себя такие веши как Munin и прочие утилиты для отслеживания состояния серверов - я...
Защита комментариев от спама.Все люди, которые вели, ведут или собираются вести блоги, форумы или гостевые книги сталкиваются с...
Nginx и Bitrix. Использование их без использования апача. Встала тут задача поднять сервер, исключительно под сайты, написанные на базе CMS Bitrix (в силу...
Eval - наше все!Казалось бы, весь интернет напичкан статьями и рекомендациями к программистам, в которых говориться, что eval...
Кризис. Пожуем эту тему еще разок ? Бредоглава 0 (мы же программисты, у нас обязана быть нулевая глава :). Введение . О мировом экономическом...
Дизайн ЯндексаЯндекс в своем  желании заработать как можно больше демонстрирует просто потрясяющую способность...

Flash: построение графика с динамическим обновлением данных.

До того, как я открыл для себя такие веши как Munin и прочие утилиты для отслеживания состояния серверов - я начал изобретать велосипед. Для начала, я захотел сделать монитор load average и написав простейшего демона, который регулярно парсил результат вывода комманды uptime и клал в базу, задумался над тем, как же визуализировать все это накопленное богатство. Несмотря на то, что есть такой замечательный модуль под PHP как GD, и куча других средств для рисования картинок, я решил, что это как то слишком скучно, да и перегружать постоянно картинку, чтобы увидеть изменения в загрузке системы - было как то неприкольно.

Сначала, я решил сделать рисовалку на JS+SVG+AJAX, но потом понял, что по хорошему, для полной кроссброузерности надо использовать JS+SVG+Canvas+VML, и меня заломало. Поскольку иногда я в своей работе использовал Flash, то я решил, что даже в изобретении велоспидов должны быть разумные пределы, и начал делать рисовалку графиков на нем. Чтобы рисовалка графиков была по настоящему универсальной (ну или хотя бы стремилась быть таковой), было принято решение, что все данные о том, что мы рисуем, как часто обновляем данные и все остальное (типа цвета линий), мы должны получать с сервера, не были намертво зашиты в swf.

Поэтому, полученный результат можно было бы использовать не только для отслеживания ситуации на сервере, но и для других задач, где требуется регулярное обновление данных с течением времени (к примеру, колебания курсов валют, акций и вообще всего того, что может колебаться со временем). Для этого был создан конфигурационный файл, название которого, опять таки для большей универсальности, нужно задавать в качестве парамета GET в URL-е загрузки SWF файла. То есть вызов выглядел примерно так:

<embed src="graph.swf?w=1500&h=200&cfg=server.xml" quality="high" scale="noscale" salign="lt" bgcolor="#ffff99" width="1521" height="206" name="graph" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />  

В результате можно будет увидеть примерно следующее:
График load average

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

Размеры флешки с графиком, как вы поняли, тоже задаются в виде GET параметров (w - ширина в пикселях, h - высота, опять таки в пикселяъ). Сам конфиг выглядит следующим образом:
<config>
<colors>
        <bg_color>0xf0f0f0</bg_color>
        <border_color>0x000000</border_color>
        <line_color>0xd0d0d0</line_color>
</colors>
<info>
        <min_value>0</min_value>
        <max_value>5</max_value>
        <x_label_step>30</x_label_step>
        <y_rule_title>LA</y_rule_title>
        <x_rule_title>Time</x_rule_title>
</info>
<legend>
        <value color="0xff0000">Load Average 1min</value>
        <value color="0x00ff00">Load Average 5min</value>
        <value color="0x0000ff">Load Average 15min</value>
</legend>
<load data="data.php" update="update.php" />
</config>


Секция colors определяет цвета самого полотна для рисования. То есть:
bg_color - цвет фона, в нашем случае светлосерый,
border_color - цвет рамки по периметру графика,
line_color - цвет линий масштаба.

В секции info содержится информация уже о том, что же, и в каких пределах мы отображаем:
min_value - минимальное значение, отображаемое на графике
max_value - максимальное значение, отображаемое на графике

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

x_label_step - это интервал, заданных в строках данных, через которые на горизонтальной оси появляются метки. То есть, если у нас с сервера получено 500 записей за последние 5 часов, то горизонтальные метки будут рисоваться не у каждой точки (иначе получилась бы нечитабельная каша из меток), а у каждой 30 (в нашем случае), то есть метка была бы у первой точки, потом у 30-той, потом у 60-той и т.д. Поскольку, все у нас универсально - метки передаются вместе с данными, в моем случае это дата и время, но вообще, это может быть что угодно - день недели, название месяца, год и еще какие то попугаи, в которых мы решили измерять интервал. Поэтому подбирайте интервал таким образом, чтобы даже самое длинное название метки не налезало на другие.

y_rule_title и x_rule_title - это названия осей, по оси Y и по оси X соответсвенно.

Секция legeng - содержимое должно быть в принципе понятно из названия. То есть мы указываем по порядку, что мы должны отобразить на графике и как эти данные будут называться. В файле с данными, данные должны идти в том же порядке что и в этой секции, то есть если мы указали в легенде, что первый параметр - это load average 1min, то и в файле данных, будьте добры, передайте его первым.
Легенда (то есть расшифровка линий), идет по вертикали, а поскольку высоту области под график вы указываете изначально - то флешка сама расчитывает, сколько у нее остается места под сам график за вычетом места под легенду, поэтому если данных на графике много - выглядеть это будет не очень красиво, и на высоту скупиться будет нельзя.

Ну и наконец, самый главный параметр - load. Он содержит два аттрибута:
data - это название файла с первоначальными данными. Поскольку при запуске флешке - смотреть на пустое пространство без данных не очень интересно, то для заполнения графика нужны данные за какой то период времени. К примеру, у вас разрешение монитора - 1680 точек по горизонтали,  за вычетом всяких полей броузера и т.д. допустим, вы решили рисовать график шириной в 1500 точек. Для читабельности графика одна строка данных у меня отображается в шагом в 2 точки. Таким образом, чтобы полностью заполнить весь график вам надо будет одномоментно предоставить флешке порядка 750 строк данных.

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

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

<div style="width:100%" id="load_average">
</div>
<script type="text/javascript">
function show_graph(id,cfg,h) {
    var oid=document.getElementById(id);
    var w=oid.offsetWidth;
    var rw=w-21;
    var rh=h-6;
    var str='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="'+w+'" height="'+h+'" id="graph" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="movie" value="/stat/graph.swf?cfg='+cfg+'&w='+rw+'&h='+rh+'" /><param name="quality" value="high" /><param name="scale" value="noscale" /><param name="salign" value="lt" /><embed src="/stat/graph.swf?w='+rw+'&h='+rh+'&cfg='+cfg+'" quality="high" scale="noscale" salign="lt" bgcolor="#ffff99" width="'+w+'" height="'+h+'" name="graph" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /></object>';
    oid.innerHTML=str;
}
show_graph('load_average','/stat/server2.xml',206);
</script>

Ничего сложного, просто удобней.

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

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


вернуться в список статей