![Знайомство з graphviz (більше) Знайомство з graphviz](https://images-on-off.com/images/150/znakomstvosgraphviz-ce1053c8.jpg)
Є в Юнікс така потрібна утиліта під назвою 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 файл:
use strict;
use List :: Util qw / max shuffle /;
use List :: MoreUtils qw / uniq /;
use DBI;
use constant MIN_PERCENT => 5;
# Генеруємо просто помітні і не дуже чорні кольори
my @colors;
for my $ c (qw / 8 D A Дев'ять F 6 /) for my $ m (qw / FF0000 00FF00 00FFFF FF00FF FFFF00 /) my $ t = $ m;
$ T =
# Забираємо дані з БД
my $ db = DBI-> connect (
"Dbi: mysql: database: localhost", "user", "password",
) Or die "ERROR: $! \ N";
my $ res = $ db-> prepare ($ query);
$ Res-> execute () or die "Query failed: \ n \ n $ query";
# Початок опису графа
![Знайомство з graphviz (graph) Знайомство з graphviz](https://images-on-off.com/images/150/znakomstvosgraphviz-6621b3a5.jpg)
print "digraph G 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 = $ cnt;
$ Plus + = $ cnt;
$ Minus + = $ cnt;
$ Max_cnt = $ cnt> $ max_cnt. $ Cnt. $ Max_cnt;
push @sources, $ from;
push @sources, $ to;
>
# Shuffle для того, щоб можна було
# Перемалювати граф незначно по-іншому
@sources = shuffle uniq @sources;
![Знайомство з graphviz ({
& Amp; nbsp & amp; nbsp) Знайомство з graphviz](https://images-on-off.com/images/150/znakomstvosgraphviz-d484a950.jpg)
for my $ src (@sources) # відкидаємо компанії з маленькою "плинністю клієнтів"
next if (max ($ plus, $ minus) <$max_cnt*MIN_PERCENT/100);
# Беремо черговий колір
my $ color = $ colors [$ i ++];
my $ delta = $ plus - $ minus;
# Опис верхівки графа, відповідної компанії
print "" $ src "[label =" $ src \\ n + ". int ($ plus).", - ". int ($ minus).", delta: $ delta ", style =" filled ", fontcolor = "# 111111", color = "# $ color", ".
# Для тих, кому більше подобаються прямокутники :)
# "Shape =" box ", width = 4, height = 1,".
"Fontsize = 16]; \ n";
for my $ to (keys%>) my $ cnt = $ data;
my $ percents = $ cnt * 100 / $ max_cnt;
# Дуже "тонкі" дуги не виводиться
if ($ percents> MIN_PERCENT) # виводимо опис дуги
print "" $ src "->" $ to "[label =" $ cnt ", fontcolor =" # $ color ", color =" # $ color ", penwidth =". int (Один + $ percents * 12/100). ", Fontsize =". Int (12 + $ percents * 12/100). "]; \ N";
>
>
>
# Кінець опису графа
print "\ n> \ n";
Приклад gv-файлу, зробленого за допомогою цього скрипта, можна подивитися тут. Зрозуміло, що всі дані в ньому не справжні. Перетвориться GV в SVG наступним чином:
circo graph-fake.gv -Tsvg -o fake.svg
Тут можна завантажити придбаний граф. А кому лінь качати (або раптом у когось SVG не розкривається), ось картина набагато менше:
![Знайомство з graphviz (опису) Знайомство з graphviz](https://images-on-off.com/images/150/znakomstvosgraphviz-a94d2976.jpg)
Більшості пішли клієнтів відповідають більш товсті смуги. Крім того, кожній компанії відповідає власний колір.
Можна було б ще поміняти розмір вершин залежно від того, скільки всього нових клієнтів отримала компанія, але у мене щось не вийшло зробити це прекрасно. Може, у вас краще вийде.
Не так давно мені надійшов ще один лист від 1-го з читачів блогу. Творець листи нарікав, що на кафедрі, на якій він навчається, мало уваги приділяється програмування, також цікавився, чи не зн.
Найближчим часом я пару раз згадував про те, що ні зовсім розумію, як на Haskell можна розробляти справжні, величезні проекти. Тому було кілька причин, але головним чином мене турбує.
Найближчим часом я практично перестав грати в комп'ютерні ігри. Але іноді, коли необхідно знищити час, потреба в них з'являється. Є трохи ігор під UNIX, які мені справді подобається.
Redis (REmote DIctionary Server) - це нереляційних високопродуктивна СУБД. Redis зберігає всі дані в пам'яті, доступ до даних здійснюється по ключу. Опціонально копія даних може хранітьс.
Трохи раніше мені захотілося дуже звичайний речі - щоб при отриманні новітньої електронної пошти подекуди в кутку екрану виникало повідомлення про це. Притому мені потрібні були лише сповіщення.