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

Идея простая. Есть конфиг (файл .gv), с помощью которого дается описание графа. Конфиг этот примерно такого содержания:

digraph G {
«A» -> «B»;
«B» -> «C»;
«A» -> «C»;
}

Graphviz принимает такой конфиг на входе, а на выходе дает png|jpg|gif|svg файл с изображением графа. При желании можно дать более подробное описание графа. Например, указать форму и цвет вершин, толщину и направленность рёбер и так далее. Останавливаться на этом я не буду, в man-pages все детально расписано.

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

dot — filter for drawing directed graphs
neato — filter for drawing undirected graphs
twopi — filter for radial layouts of graphs
circo — filter for circular layout of graphs
fdp — filter for drawing undirected graphs
sfdp — filter for drawing large undirected graphs

Примеры графов, нарисованных с их помощью, вы можете посмотреть на официальном сайте программы.

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

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

Вот скрипт, генерирующий .gv файл:

#!/usr/bin/perl

# gen-graph.pl
# (c) Alexandr A Alexeev 2010, http://remontka.com/

use strict ;
use List :: Util qw/max shuffle/ ;
use List :: MoreUtils qw/uniq/ ;
use DBI ;
use constant MIN_PERCENT => 5 ;

my %data ; # {from}{to} = cnt
my @sources ;

# генерируем легко различимые и не слишком темные цвета
my @colors ;
for my $c ( qw/8 D A 9 F 6/ ) {
for my $m ( qw/FF0000 00FF00 00FFFF FF00FF FFFF00/ ) {
my $t = $m ;
$t =~ s/F/$c/g ;
push @colors , $t ;
}
}

# забираем данные из БД
my $db = DBI -> connect (
«dbi:mysql:database:localhost» , «user» , «password» ,
{ PrintError => 0 , RaiseError => 0 }
) or die «ERROR: $! n » ;

my $query = qq {
select `from` , `to` , `count` from logs
where month = ‘201009’ ;
} ;

my $res = $db -> prepare ( $query ) ;
$res -> execute ( ) or die «Query failed: n n $query» ;

# начало описания графа
print «digraph G { n » ;
print qq {
nodesep = 2 ;
mindist = 2 ;
} ;
print » n » ;

# максимум клиентов перешло
my $max_cnt = 1 ;

# плюс и минус число клиентов для компании
my %plus ;
my %minus ;

while ( my ( $from , $to , $cnt ) = $res -> fetchrow_array ( ) ) {
$data { $from } { $to } = $cnt ;
$plus { $to } += $cnt ;
$minus { $from } += $cnt ;
$max_cnt = $cnt > $max_cnt ? $cnt : $max_cnt ;
push @sources , $from ;
push @sources , $to ;
}

# shuffle для того, чтобы можно было
# перерисовать граф немного по-другому
@sources = shuffle uniq @sources ;

my $i ;
for my $src ( @sources ) {
# отсекаем компании с небольшой «текучестью клиентов»
next if ( max ( $plus { $src } , $minus { $src } ) < $max_cnt *MIN_PERCENT / 100 ) ;

# берем очередной цвет
my $color = $colors [ $i ++ ] ;
my $delta = $plus { $src } $minus { $src } ;
# описание вершины графа, соответствующей компании
print » » $src «» [label= «» $src \ n+»» . int ( $plus { $src } ) . «»-«» . int ( $minus { $src } ) . «»delta: $delta «» style= «» filled «»

admin

Share
Published by
admin

Recent Posts

После включения диагностического запуска не удается войти в Windows — как исправить?

Некоторые пользователи, экспериментируя с конфигурацией системы в окне msconfig могут столкнуться с ситуацией, когда после…

1 неделя ago

WinScript — очистка и настройка Windows 11 и 10

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

1 неделя ago

Предварительный просмотр накопительного обновления не устанавливается — решение

При установке некоторых обновлений Windows 11, имеющих в названии «Предварительный просмотр накопительного обновления», многие пользователи…

1 неделя ago

FixExec — восстановление ассоциаций .exe, .bat и .com файлов

Некоторые пользователи Windows 11, 10 и предыдущих версий системы могут столкнуться с ситуацией, когда исполняемые…

1 неделя ago

Ошибка 0x800705b4 при обновлении Windows 11 и 10 — как исправить?

При установке обновлений Windows 11/10 некоторые пользователи могут столкнуться с ошибкой с кодом 0x800705b4 и…

1 неделя ago

Обслуживание вашей версии Windows 11 окончено — что делать?

Пользователи Windows 11 могут столкнуться с сообщением «Обслуживание вашей версии Windows окончено» (Your version of…

1 неделя ago