Иногда хочется странного... Посадить дерево, построить дом.... ой, то есть граф! В случае, когда граф нужен простенький, никаких проблем с оным не возникает, берем любой Visio, ArgoUML, ну или хотя бы Microsoft Word, или что там еще, в зубы, и строим. Но что делать, если граф руками строить долго, а все необходимые данные для его построения есть в электронном виде?
На помощь может придти такая замечательная утилита, как dot. На самом деле это лишь одна из утилит, входящих в пакет GraphViz (средство для построения графов). Что это такое и с чем ее едят - в продолжении статьи.
Еще про построение графиков и графов можно почитать в этом блоге: Сравнение 9 программ для построения графиков
Практическое использование dot. Построение графов.
Для начала расскажу, как построить простой граф при помощи dot вручную. Предположим, строим семейное древо семейства гермафродитов :-) Создаем файл familytree.dot следующего содержания:
digraph G { Дедушка -> Папа Папа -> Я Я -> "Мой сын Андрей" Я -> "Моя дочь Маша" Я -> "Мой сын Саша" }
Далее выполняем команду
dot familytree.dot -O -Tpng
Результат - примерно вот такой:
Если не все в порядке с русским (Linux):
Самый простой способ сделать, чтобы все было в порядке, убедиться в следующем:
- В системе установлена библиотека gd версии более 2
- В системе установлена библиотека fontconfig
- fc-match находит шрифты:
-
baron@localhost ~/Desktop/zk/ex $ fc-match "Times-Roman" timR12-ISO8859-1.pcf.gz: "Times" "Regular" baron@localhost ~/Desktop/zk/ex $ fc-match "Times Roman" DejaVuSans.ttf: "DejaVu Sans" "Book" baron@localhost ~/Desktop/zk/ex $ fc-match "Arial" arial.ttf: "Arial" "Normal"
После того, как поставятся все необходимые библиотеки, можно пересобрать graphviz, и все заработает :-)
Теперь об автоматизации. В моем случае, входные данные имели такой формат:
номер нода, номер родителя, 'текст нода'
В формат .dot их преобразовывал простенький скрипт на perl:
#!/usr/bin/perl # Author: Ruslan N. Balkin use strict; our %idhash; print "digraph G {\n"; while (<STDIN>) { chomp; if (/(\d+), (\-?\d+), \'(.*?)\'/) { my ($uid, $parent, $nick) = ($1, $2, $3); $idhash{$uid} = $nick; my $parentnick = $idhash{$parent}; print "\t\"$nick\" -> \"$parentnick\"\n" if defined($parentnick); } } print "}\n";
Вкратце, как оно работает: сначала считываем данные в переменные $uid, $parent, $nick. Записываем в $idhash данные в формате "идентификатор нода" => "ник". Потом добавляем запись вида "Ник" -> "Ник родителя". И, собственно, все.
Вызываем: perl html2dot.pl < out.html > out.dot
Далее: dot -v out.dot -T png -O
И имеем готовый к использованию файл out.dot.png, с которым работать проще и нагляднее :-).
Ну, это все для личных нужд, - а для работы, например, кому-то может быть полезен вот этот линк (там рассказывается про создание графов с помощью dot из 1С): www.mista.ru/dot/
Сайт проекта graphviz (там можно скачать dot): www.graphviz.org/