Лекция 1.6. Графвиз — различия между версиями
Admin (обсуждение | вклад) (→Свойства графа) |
Admin (обсуждение | вклад) (→Сложный граф) |
||
Строка 284: | Строка 284: | ||
'''Graphviz''' — это разработанный специалистами лаборатории AT&T пакет утилит по автоматической визуализации графов, заданных в виде текстового описания. Пакет распространяется с открытыми исходными файлами и работает на всех операционных системах, включая Windows, Linux/Unix, Mac OS. Самой интересной программой пакета является «dot», автоматический визуализатор направленных графов, который принимает на вход текстовый файл со структурой графа, а на выходе формирует граф в виде графического, векторного или текстового файла. | '''Graphviz''' — это разработанный специалистами лаборатории AT&T пакет утилит по автоматической визуализации графов, заданных в виде текстового описания. Пакет распространяется с открытыми исходными файлами и работает на всех операционных системах, включая Windows, Linux/Unix, Mac OS. Самой интересной программой пакета является «dot», автоматический визуализатор направленных графов, который принимает на вход текстовый файл со структурой графа, а на выходе формирует граф в виде графического, векторного или текстового файла. | ||
− | + | ||
= Быстрый старт = | = Быстрый старт = | ||
<graphviz> | <graphviz> |
Версия 09:11, 15 июня 2009
Графвиз - набор утилит для графического представления данных. Программа принимает описания отношений и элементов множеств, на которых определяется граф, и "добавляет" к этим лишенным всяких геометрических атрибутов описаниям дополнительную информацию, позволяющую "нарисовать" картинку графа.
Для использования Графвиз требуется использовать примитивный язык описания графов dgl. Основные понятия:
- граф,
- вершина графа -- элемент множества,
- ребро графа, соединяющее вершину N с вершиной M
Содержание
- 1 Простейший граф
- 2 Свойства графа
- 3 Гипертекстовые ссылки на страницы
- 4 Использование групп подграфа
- 5 Сложный граф
- 6 Быстрый старт
- 7 Внешний вид графа
- 8 Уровни в графах
- 9 Многосекционный узлы
- 10 Гиперссылки на графах
- 11 Кластеры в графах
- 12 Цвета и черно-белая печать
- 13 Формы вершин
- 14 Окончания ребер
- 15 Неориентированные графы
- 16 Версии для печати
- 17 Задание для самостоятельной работы
Простейший граф
<graphviz>digraph G {rankdir=LR ;Привет -> Читатель ;}</graphviz>
Программа сама распознает все связи графа и упорядочит его таким образом, чтобы было наименьшее количество пересечений.
<graphviz>digraph G{rankdir=LR ;Привет -> Читатель ;}</graphviz>
Свойства графа
Для того, граф было удобнее просматривать, можно настроить следующие свойства. Например:
- Направленность графа:
- rankdir=LR - слева-направо
- rankdir=TB - сверху вниз
- ratio=auto - отношение = авто;
- Цвет фона графа - graph [bgcolor=Snow2] - окрашивает фон в цвет - "серый снег"
- Свойства (node) узлов - node[color="Pink",fontsize=10, style=filled, fontcolor="blue", shape="none"] (Сочетание двух и более слов записывается в кавычки - "Нижний Новгород")
- color="Pink" - цвет = розовый (Цвета в Вики)
- fontsize=8 - размер шрифта = 8
- style=filled - стиль = заполненный (без неё узел прозрачен)
- fontcolor="blue" - цвет шрифта = голубой
- shape="none" - форма = "без формы"
- Формы узла [shape=?] - invtriangle - треугольник вершиной вниз; box - прямоугольник; ellipse - эллипс; invtrapezium - перевёрнутая трапеция; triangle - треугольник; trapezium - трапеция; record - ; doubleoctagon - двойной восьмиугольник ; octagon - восьмиугольник; tripleoctagon - тройной восьмиугольник (Все формы)
- Ярославль [shape=Mdiamond] - узлу Ярославль придаётся форма ромба(алмаз)
- Сызрань [shape=Msquare] - узлу Сызрань придаётся форма квадрата
- Кострома [shape=circle] - узлу Кострома придаётся форма круга
- "Нижний Новгород" [shape=doublecircle] - узлу "Нижний Новгород" придаётся форма двойного круга
- Казань [shape=hexagon,color=green] - узлу Казань придаётся форма шестиугольника и зелёный цвет
- Управление положением узлов - {rank=same; Елабуга Дзержинск Сызрань ;} - узлам Елабуга, Дзержинск, Сызрань предан разряд = тот же самый; ranksep=3 - расстояние между разрядами;
- Свойства(edge)ребер - edge[color="blue",fontcolor="Green",fontsize=12]
- color="Brown" - цвет = коричневый
- color="Green:blue:red" - трёхцветие (возможно любое количество)
- dir=both - направление стрелки в две стороны
- fontsize=8 - размер шрифта = 8
- fontcolor="blue" - цвет шрифта = зелёный
- style=dotted - стиль = пунктирная линия
- arrowhead="dot" - голова стрелки = "точка", "none" - нет (Все формы)
- color="Brown" - цвет = коричневый
- Ярлык ребра [label="Волга"] - все связи Ярославль -> ... -> Сызрань будут помечены меткой Волга.
<graphviz> digraph G{ graph [bgcolor=Snow2]; rankdir=LR ; // направление графа слева направо node[color="Pink",fontsize=8, fontcolor="blue",style=filled, shape="none"] ; edge[color="Brown",fontcolor="Green",fontsize=8] ; Ярославль -> Кострома -> "Нижний Новгород" -> Казань -> Сызрань [dir=both, label="Волга"]; "Нижний Новгород" -> Дзержинск [style=dotted, label="Ока",arrowhead="dot" ] ; Казань -> Елабуга [label="Кама", color="Green:blue:red"] ; Ярославль [shape=Mdiamond], Сызрань [shape=Msquare], Кострома [shape=circle]; "Нижний Новгород" [shape = doublecircle],Казань[shape=hexagon,color=green] {rank=same; Елабуга Дзержинск Сызрань ;} } </graphviz>
<graphviz>
digraph G{ graph [bgcolor=Snow2]; rankdir=LR ; node[color="Pink",fontsize=8, fontcolor="blue",style=filled, shape="none"] ; edge[color="Brown",fontcolor="Green",fontsize=8] ; Ярославль -> Кострома -> "Нижний Новгород" -> Казань -> Сызрань [dir=both, label="Волга"]; "Нижний Новгород" -> Дзержинск [style=dotted, label="Ока",arrowhead="dot" ] ; Казань -> Елабуга [label="Кама", color="Green:blue:red"] ; Ярославль [shape=Mdiamond], Сызрань [shape=Msquare], Кострома [shape=circle]; "Нижний Новгород" [shape = doublecircle],Казань[shape=hexagon,color=green] {rank=same; Елабуга Дзержинск Сызрань ;}
}
</graphviz>
Гипертекстовые ссылки на страницы
Ссылки на внутренние страницы устанавливаются прямым связыванием:
- ПскоВики - [URL=ПскоВики]
Кроме того, мы можем в начале графа указать, что все элементы поименованные в графе должны ссылаться на страницы с соответстующим названием. node [URL="/index.php/\N"] ;
После этого можно просто указывать имена узлов, а гипертекстовые ссылки добавятся к ним автоматически.
Для того, чтобы имя заметки на ребре так же становилось ссылкой на страницу, необходимо дополнить метку ссылкой [label="ПскоВики", URL="ПскоВики"]. В графе, который представлен ниже все узлы и метки являются гиперссылками.
<graphviz> digraph G{ rankdir=LR ; node[color="Green",fontsize=9, fontcolor="blue"] ; edge[color="Green",fontcolor="blue",fontsize=8] ; node [URL="/index.php/\N"] ; Категории -> "Категория:Тьюторы" -> "Категория:Участник" -> "Категория:Учитель" [label="ПскоВики",URL="ПскоВики"] ; } </graphviz>
<graphviz>
digraph G{
rankdir=LR ;
node[color="Green",fontsize=9, fontcolor="blue"] ;
edge[color="Green",fontcolor="blue",fontsize=8] ;
node [URL="/index.php/\N"] ;
Категории -> "Категория:Тьюторы" -> "Категория:Участник" -> "Категория:Учитель" [label="ПскоВики",URL="ПскоВики"] ;
}
</graphviz>
Ссылки на внешние источники устанавливаются прямым связыванием с адресом web-сайта:
- ПскоВики [URL="http://wiki.pskovedu.ru/index.php/Заглавная_страница"]
<graphviz> digraph G{ rankdir=LR ; node[color="red",fontsize=9, fontcolor="blue", shape="none"] ; edge[color="red",fontcolor="blue",fontsize=8] ; node [URL="/index.php/\N"] ; Тест -> Проект [style=dotted, label="ПскоВики", URL="http://wiki.pskovedu.ru/index.php/ Заглавная_страница"] ; } </graphviz>
<graphviz> digraph G{ rankdir=LR ; node[color="red",fontsize=9, fontcolor="blue", shape="none"] ; edge[color="red",fontcolor="blue",fontsize=8] ; node [URL="/index.php/\N"] ; Тест -> Проект [style=dotted, label="ПскоВики", URL="http://wiki.pskovedu.ru/index.php/Заглавная_страница"] ; } </graphviz>
Использование групп подграфа
В структуре графа можно образовать несколько групп использую дополнение - subgraph cluster_0 {}
<graphviz> digraph G { subgraph cluster0 { style=filled; color=DeepSkyBlue; node [style=filled,color=white]; "Учебные проекты" -> "Сообщество школ" -> "Сетевые проекты" -> "Участники сообщества"; label = "Летописи.ру"; } subgraph cluster1 { node [style=filled]; Проекты -> школы -> тьюторы -> учителя; label = "ПскоВики"; color=blue "Учебные проекты" -> Проекты учителя -> "Участники сообщества" Проекты -> "Сетевые проекты" } }</graphviz>
<graphviz> digraph G {
subgraph cluster0 { style=filled; color=DeepSkyBlue; node [style=filled,color=white]; "Учебные проекты" -> "Сообщество школ" -> "Сетевые проекты" -> "Участники сообщества"; label = "Летописи.ру"; } subgraph cluster1 { node [style=filled]; Проекты -> школы -> тьюторы -> учителя; label = "ПскоВики"; color=blue "Учебные проекты" -> Проекты учителя -> "Участники сообщества" Проекты -> "Сетевые проекты" }
}</graphviz>
Сложный граф
Пример графа с использование подписи, многоугольных узлов неправильной формы и разнонаправленный.
<graphviz> digraph G { graph [ //подпись под графом fontsize = 26,//размер шрифта label = "Сложный граф", size = "8,8" ];//размер графа node [ shape = polygon,//форма = многоугольник sides = 4,// сторон = 4 distortion = "0.0",//искажение = "0.0" orientation = "0.0",//ориентация = "0.0" skew = "0.0",//уклон "0.0" color = white,//цвет = белый style = filled,//стиль = заполненный fontname = "Helvetica-Outline" ];//Название(имя) шрифта = "Helvetica-Outline" // формирование узлов графа "Псковская область" [sides=9, distortion="0.936354", orientation=28, skew="-0.126818", color=salmon2]; "Города" [sides=5, distortion="0.238792", orientation=11, skew="0.995935", color=deepskyblue]; "Районы" [sides=8, distortion="0.019636", orientation=79, skew="-0.440424", color=goldenrod2]; "Псков" [sides=7, distortion="0.265084", orientation=26, skew="0.403659", color=gold1]; "Великие Луки" [distortion="0.039386", orientation=2, skew="-0.461120", color=greenyellow]; Порхов [sides=5, distortion="0.228564", orientation=63, skew="-0.062846", color=darkseagreen]; Невель [distortion="0.624013", orientation=56, skew="0.101396", color=dodgerblue1]; "РЦДО" [sides=8, distortion="0.731383", orientation=43, skew="-0.824612", color=thistle2]; "РРЦ" [sides=6, distortion="0.592100", orientation=34, skew="-0.719269", color=darkolivegreen3]; "Великолукский" [sides=7, distortion="0.640971", orientation=84, skew="-0.768455", color=cyan]; "Псковский" [distortion="0.758942", orientation=42, skew="0.039886", color=blue]; "Псковская область" -> "Города"[color=red];//формирование направлений графа "Псковская область" -> "Районы"[color=red];//цвет ребра = красный "Города" -> "Псков"[color=green]; "Города" -> "Великие Луки"[color=green]; "Города" -> Порхов[color=green]; "Города" -> Невель[color=green]; Невель -> РРЦ; Порхов -> РРЦ; Великолукский -> РРЦ; Псковский -> РРЦ; РРЦ -> РЦДО "Великие Луки" -> РЦДО; Псков -> РЦДО; "Районы" -> "Великолукский"; "Районы" -> "Псковский"; }</graphviz>
<graphviz> digraph G { graph [ //подпись под графом
fontsize = 26,//размер шрифта label = "Сложный граф",
size = "8,8" ];//размер графа node [ shape = polygon,//форма = многоугольник sides = 4,// сторон = 4 distortion = "0.0",//искажение = "0.0" orientation = "0.0",//ориентация = "0.0" skew = "0.0",//уклон "0.0" color = white,//цвет = белый style = filled,//стиль = заполненный fontname = "Helvetica-Outline" ];//Название(имя) шрифта = "Helvetica-Outline" "Псковская область" [sides=9, distortion="0.936354", orientation=28, skew="-0.126818", color=salmon2];// формирование узлов графа "Города" [sides=5, distortion="0.238792", orientation=11, skew="0.995935", color=deepskyblue]; "Районы" [sides=8, distortion="0.019636", orientation=79, skew="-0.440424", color=goldenrod2]; "Псков" [sides=7, distortion="0.265084", orientation=26, skew="0.403659", color=gold1]; "Великие Луки" [distortion="0.039386", orientation=2, skew="-0.461120", color=greenyellow]; Порхов [sides=5, distortion="0.228564", orientation=63, skew="-0.062846", color=darkseagreen]; Невель [distortion="0.624013", orientation=56, skew="0.101396", color=dodgerblue1]; "РЦДО" [sides=8, distortion="0.731383", orientation=43, skew="-0.824612", color=thistle2]; "РРЦ" [sides=6, distortion="0.592100", orientation=34, skew="-0.719269", color=darkolivegreen3];
"Великолукский" [sides=7, distortion="0.640971", orientation=84, skew="-0.768455", color=cyan]; "Псковский" [distortion="0.758942", orientation=42, skew="0.039886", color=blue]; "Псковская область" -> "Города"[color=red];//формирование направлений графа "Псковская область" -> "Районы"[color=red];//цвет ребра = красный "Города" -> "Псков"[color=green]; "Города" -> "Великие Луки"[color=green]; "Города" -> Порхов[color=green]; "Города" -> Невель[color=green]; Невель -> РРЦ; Порхов -> РРЦ;
Великолукский -> РРЦ; Псковский -> РРЦ; РРЦ -> РЦДО
"Великие Луки" -> РЦДО; Псков -> РЦДО; "Районы" -> "Великолукский"; "Районы" -> "Псковский";
}</graphviz> <graphviz> digraph G{ graph [bgcolor=darkseagreen1]; //Цвет фона ratio=auto; //Отношение равно авто. Граф просматривается из центра в разные стороны node[color="darkorange2",fontsize=10,fontcolor="gray0",style=filled,shape="octagon"]; //Характеристики центра edge[color="darkgreen"]; //Цвет стрелок "Симметрия" -> "Биология"[dir=both]; "Симметрия" -> "Математика"[dir=both]; "Симметрия" -> "Физика"[dir=both]; "Симметрия" -> "Химия"[dir=both]; "Симметрия" -> "География"[dir=both]; "Симметрия" -> "Музыка"[dir=both]; "Симметрия" -> "Архитектура"[dir=both]; "Симметрия" -> "Религия"[dir=both]; "Симметрия" -> "Астрономия"[dir=both]; "Симметрия" -> "..."[dir=both]; "Биология"[shape=ellipse,color=gold],"Математика"[shape=ellipse,color=gold],"Физика"[shape=ellipse,color=gold],"Химия"[shape=ellipse,color=gold],"География"[shape=ellipse,color=gold],"Музыка"[shape=ellipse,color=gold],"Архитектура"[shape=ellipse,color=gold],"Религия"[shape=ellipse,color=gold],"Астрономия"[shape=ellipse,color=gold],"..."[shape=ellipse,color=gold]; } </graphviz>
Graphviz — это разработанный специалистами лаборатории AT&T пакет утилит по автоматической визуализации графов, заданных в виде текстового описания. Пакет распространяется с открытыми исходными файлами и работает на всех операционных системах, включая Windows, Linux/Unix, Mac OS. Самой интересной программой пакета является «dot», автоматический визуализатор направленных графов, который принимает на вход текстовый файл со структурой графа, а на выходе формирует граф в виде графического, векторного или текстового файла.
Быстрый старт
<graphviz> digraph G{ "Коржуков Валентин Григорьевич" -> "Коржуков Максим Валентинович" [label="отец"]; "Миронова Татьяна Рудольфовна" -> "Коржуков Максим Валентинович" [label="мать"]; } </graphviz>
Входной файл для программы «DOT» является обычным текстовым файлом на специальном языке разметки графа. Структура файла очень простая, например,
digraph G{ Рождение->Юность->Зрелость->Старость->Смерть; Юность->Смерть; Зрелость->Смерть; }
на выходе будет
<graphviz> digraph G{ Рождение->Юность->Зрелость->Старость->Смерть; Юность->Смерть; Зрелость->Смерть; } </graphviz>
Программа «Dot» сама распознает все связи графа и упорядочит его таким образом, чтобы было наименьшее количество пересечений.
Чтобы использовать «dot»-графы в Wiki, используйте следующий синтаксис:
<graph> digraph G{ Рождение->Юность->Зрелость->Старость->Смерть; Юность->Смерть; Зрелость->Смерть; } </graph>
Если у вас узлы поименованы словосочетаниями, заключите их в кавычки, т. е.
<graph> digraph G{ "Полет фантазии"->"Расход горючего"; } </graph>
Поздравляем! Теперь вы способны рисовать графы в Wiki. Остальной текст будет посвящен некоторым тонкостям использования Graphviz.
Внешний вид графа
«Dot» позволяет изменять внешний вид графа. Например, можно изменять форму фигур (прямоугольники, овалы, круги, параллелограммы, многоугольники), цвет и шрифт текста, цвет фона фигур, стиль стрелок и рамок фигур, подписи стрелок и т. д. Итак, основные объектами являются узлы («node») и ребра («edge»). Для того, чтобы настроить свойства всех узлов или ребер нужно вначале использовать команды
node[свойство1="значение1",свойство2="значение2",...] edge[свойство1="значение1",свойство2="значение2",...]
Также (в квадратных скобках после описания объекта) можно изменять настройки конкретного узла или ребра. Параметры графа, просто задаются в виде параметр=значение. Полезно запомнить параметр «rankdir», он может быть «TB» (top->bottom, параметр по умолчанию), или «LR» (left->right), и определяет, сверху-вниз, или справа-налево, нужно располагать узлы графа. Вот пестрый пример:
digraph G{ rankdir=LR; node[color="red",fontsize=14]; edge[color="darkgreen",fontcolor="blue",fontsize=12]; OPEN[shape="rectangle",style="filled",fillcolor="lightgrey"]; CLOSED[shape="octagon",label="Финиш"]; VERIFIED[shape="rectangle",style="rounded"]; OPEN->RESOLVED->VERIFIED->CLOSED; OPEN->CLOSED[style="bold"]; VERIFIED->OPEN[label="обнаружены ошибки",style="dashed",arrowhead="dot"]; }
на выходе будет
<graphviz> digraph G{ rankdir=LR; node[color="red",fontsize=14]; edge[color="darkgreen",fontcolor="blue",fontsize=12]; OPEN[shape="rectangle",style="filled",fillcolor="lightgrey"]; CLOSED[shape="octagon",label="Финиш"]; VERIFIED[shape="rectangle",style="rounded"]; OPEN->RESOLVED->VERIFIED->CLOSED; OPEN->CLOSED[style="bold"]; VERIFIED->OPEN[label="обнаружены ошибки",style="dashed",arrowhead="dot"]; } </graphviz>
Если предполагается, что граф будут не только просматривать через IE, но и печатать, то необходимо установить ширину картинки, иначе при печати картинка будет обрезана. Для этого следует задать внутри описания
size="6.7,15";
Существенна только первая цифра. Число 6.7 подобрано эмпирически, оно обеспечивает печать полной картинки при настройках IE по умолчанию.
Уровни в графах
В «Dot» присутствует возможность связать узлы графа не только стрелками, но и уровнями отображения, что позволяет создавать шкалу и располагать узлы графа соответственно данной шкале. Для связывания используется следующая конструкция:
{ rank = same; "элемент уровня"; "элемент для привязки 1"; "элемент для привязки 2"; ..}
Например, при использовании следующей конструкции:
<graph> digraph G{ node[fontsize=9]; { /* шкала месяцев*/ node[shape=plaintext]; /* что бы не было видно рамок */ edge[color=white] /* что бы не было видно стрелок */ "март" -> "июнь" -> "сентябрь" -> "декабрь"; } { rank = same; "март"; "весна"; "a"; } { rank = same; "июнь"; "лето";} { rank = same; "сентябрь"; "осень"; "d"; } { rank = same; "декабрь"; "зима"; "e"} "весна" -> "лето" -> "осень" -> "зима" -> "весна" "a" -> "b" -> "c" -> "d" -> "e" ; } </graph>
на выходе получается: <graphviz> digraph G{ node[fontsize=9]; { /* шкала месяцев*/ node[shape=plaintext]; /* что бы не было видно рамок */ edge[color=white] /* что бы не было видно стрелок */ "март" -> "июнь" -> "сентябрь" -> "декабрь"; } { rank = same; "март"; "весна"; "a"; } { rank = same; "июнь"; "лето";} { rank = same; "сентябрь"; "осень"; "d"; } { rank = same; "декабрь"; "зима"; "e"} "весна" -> "лето" -> "осень" -> "зима" -> "весна" "a" -> "b" -> "c" -> "d" -> "e" ; } </graphviz>
Многосекционный узлы
Dot позволяет создавать многосекционные узлы при это каждая секция может быть поименована, и тогда ребра можно продоводить между секциями и узлами.
Для включения режима многосекционности устанавливается атрибут узла shape.
shape=record;
Секции описываются в атрибуте label узла, с помощью разделителя «|». Для именования секции ее имя указывается в <>. При описание ребра, исходящего или входящего в секцию, секция именуется следующим образом:
элемент:<имя_секции>
Например, из такого описания:
digraph structs { rankdir=HR; first [shape=record,label=" x1\n all | { x21 | <f0> x22| x23} | x3" ]; second [shape=record,label=" x22_1 | x22_2 | x22_3"]; first:<f0> -> second; }
Получается следующее:
<graphviz>
digraph structs { rankdir=HR; first [shape=record,label=" x1\n all | { x21 | <f0> x22| x23} | x3" ]; second [shape=record,label=" x22_1 | x22_2 | x22_3"]; first:<f0> -> second; }
</graphviz>
Гиперссылки на графах
Можно использовать атрибут «URL», задавая относительные или абсолютные гиперссылки для узлов и ребер. Например
<graph> digraph G { rankdir=LR; SGML [URL="SGML"]; HTML [URL="HTML"]; XML [URL="XML"]; XHTML [URL="http://www.w3schools.com/xhtml/"]; SGML->HTML; SGML->XML; HTML->XHTML; XML->XHTML; SGML->XHTML[color="red",fontcolor="blue",label="ссылка на Google",URL="http://www.google.com"]; } </graph>
<graphviz>
digraph G { rankdir=LR; SGML [URL="SGML"]; HTML [URL="HTML"]; XML [URL="XML"]; XHTML [URL="http://www.w3schools.com/xhtml/"]; SGML->HTML; SGML->XML; HTML->XHTML; XML->XHTML; SGML->XHTML[color="red",fontcolor="blue",label="ссылка на Google",URL="http://www.google.com"];
} </graphviz>
Кластеры в графах
Программа «Dot» позволяет объединять узлы графов в кластеры для подчеркивания общности.
Кластер описывается следующим синтаксисом:
subgraph имя{ свойство1 = "значение1",свойство2="значение2",... узел1; узел2; ... }
При этом имя подграфа должно начинаться с префикса cluster, иначе подграф не позволяет себя отобразить на экран(раскраска, контур, подпись, .. ).
Например:
digraph G { rankdir=LR; subgraph cluster0 { node [style=filled,color=white]; style=filled; color=lightgrey; a0; a1 label = "process #1"; } subgraph cluster1 { node [style=filled]; b0; label = "process #2"; color=blue } start -> a0; start -> b0; a0 -> a1 -> end; b0 -> end; }
<graphviz>
digraph G { rankdir=LR; subgraph cluster0 { node [style=filled,color=white]; style=filled; color=lightgrey; a0; a1 label = "process #1"; } subgraph cluster1 { node [style=filled]; b0; label = "process #2"; color=blue } start -> a0; start -> b0; a0 -> a1 -> end; b0 -> end; }
</graphviz>
Цвета и черно-белая печать
Graphviz позволяет использовать широкую цветовую палитру, однако, стоит не забывать, что контрастно выглядящие на цветном мониторе цвета, могут быть совершенно неразличимы после черно-белой печати. После проделанных экспериментов (Шаблон:Bug), можно рекомендовать следующие палитры цветов (иллюстрированы на цвете ребер графа):
<graph-print> digraph G{ rankdir=TB; size="7,6";
Палитра1->goldenrod1 [color=goldenrod1] Палитра1->green [color=green] Палитра1->sienna4 [color=sienna4] Палитра1->red1 [color=red1] Палитра1->blue2 [color=blue2]
Палитра2->lightcyan2 [color=lightcyan2] Палитра2->pink2 [color=pink2] Палитра2->green [color=green] Палитра2->sienna4 [color=sienna4] Палитра2->red2 [color=red2] Палитра2->black1 [color=black1] }
</graph-print>
Формы вершин
Перечислим палитру возможных форм вершин (узлов).
<neato> digraph G{
edge [arrowtail="none"] node [style=filled, colorscheme="brbg9"]; "box" [shape="box" fillcolor="1"]; "polygon" [shape="polygon" fillcolor="2"]; "ellipse" [shape="ellipse" fillcolor="3"]; "circle" [shape="circle" fillcolor="4"]; "point" [shape="point" fillcolor="black"]; "egg" [shape="egg" fillcolor="6"]; "triangle" [shape="triangle" fillcolor="7"]; "plaintext" [shape="plaintext" fillcolor="8"]; "diamond" [shape="diamond" fillcolor="9"]; "trapezium" [shape="trapezium" fillcolor="1"]; "parallelogram" [shape="parallelogram" fillcolor="2"]; "house" [shape="house" fillcolor="3"]; "pentagon" [shape="pentagon" fillcolor="4"]; "hexagon" [shape="hexagon" fillcolor="5"]; "septagon" [shape="septagon" fillcolor="6"]; "octagon" [shape="octagon" fillcolor="7"]; "doublecircle" [shape="doublecircle" fillcolor="8"]; "doubleoctagon" [shape="doubleoctagon" fillcolor="9"]; "tripleoctagon" [shape="tripleoctagon" fillcolor="1"]; "invtriangle" [shape="invtriangle" fillcolor="1"]; "invtrapezium" [shape="invtrapezium" fillcolor="2"]; "invhouse" [shape="invhouse" fillcolor="3"]; "Mdiamond" [shape="Mdiamond" fillcolor="4"]; "Msquare" [shape="Msquare" fillcolor="5"]; "Mcircle" [shape="Mcircle" fillcolor="6"]; "rect/rectangle" [shape="rect" fillcolor="7"]; "none" [shape="none" fillcolor="8"]; "note" [shape="note" fillcolor="9"]; "tab" [shape="tab" fillcolor="1"]; "folder" [shape="folder" fillcolor="2"]; "box3d" [shape="box3d" fillcolor="3"]; "component" [shape="component" fillcolor="4"];
} </neato>
Окончания ребер
Можно задавать стиль офомления начала («arrowtail») и конца («arrowhead») дуг (ребер):
<circo> digraph G{
edge [arrowtail="none"] A [label="Arrowhead" style=filled fillcolor="yellow"]; A->"normal" [arrowhead="normal"]; A->"dot" [arrowhead="dot"]; A->"odot" [arrowhead="odot"]; A->"none" [arrowhead="none"]; A->"empty" [arrowhead="empty"]; A->"diamond" [arrowhead="diamond"]; A->"ediamond" [arrowhead="ediamond"]; A->"box" [arrowhead="box"]; A->"open" [arrowhead="open"]; A->"vee" [arrowhead="vee"]; A->"inv" [arrowhead="inv"]; A->"invdot" [arrowhead="invdot"]; A->"invodot" [arrowhead="invodot"]; A->"tee" [arrowhead="tee"]; A->"invempty" [arrowhead="invempty"]; A->"odiamond" [arrowhead="odiamond"]; A->"crow" [arrowhead="crow"]; A->"obox" [arrowhead="obox"]; A->"halfopen" [arrowhead="halfopen"];
} </circo>
Неориентированные графы
Наряду с рисованием ориентированных графов, есть несколько методов для автоматического рисования неориентированных графов (будем рассматривать их на примере несложной ER-диаграммы).
В отличие от автоматического рисования направленных («directed») графов, основанных на ранговой модели, есть несколько подходов к раскладке ненаправленных графов.
Graph
Ненаправленный граф можно нарисовать с помощью рангового подхода (несмотря на ненаправленность ребер) — будет использоваться программа «dot». Как это будет выглядеть для простой ER-диаграммы, можно увидеть ниже. <graph> graph ER {
node [fontsize=12]; node [shape=box]; course; institute; student; node [shape=ellipse]; {node [label="name"] name0; name1; name2;} code; grade; number; node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I"; name0 -- course; code -- course; course -- "C-I" [label="n",len=1.00]; "C-I" -- institute [label="1",len=1.00]; institute -- name1; institute -- "S-I" [label="1",len=1.00]; "S-I" -- student [label="n",len=1.00]; student -- grade; student -- name2; student -- number; student -- "S-C" [label="m",len=1.00]; "S-C" -- course [label="n",len=1.00]; label = "\n\nEntity Relation Diagram\ndrawn by DOT";
} </graph>
Очевидна неоптимальность такого подхода для неориентированных графов.
Neato
Метод «neato» использует «энергетическую» (spring) модель, по сути, близкую к методу искуственного отжига — начиная с некоторого состояния вершины перемещаются, чтобы минимизировать некую потенциальную энергию. Рекомендуем для ненаправленных графов общего вида.
<neato> graph ER {
node [fontsize=12]; node [shape=box]; course; institute; student; node [shape=ellipse]; {node [label="name"] name0; name1; name2;} code; grade; number; node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I"; name0 -- course; code -- course; course -- "C-I" [label="n",len=1.00]; "C-I" -- institute [label="1",len=1.00]; institute -- name1; institute -- "S-I" [label="1",len=1.00]; "S-I" -- student [label="n",len=1.00]; student -- grade; student -- name2; student -- number; student -- "S-C" [label="m",len=1.00]; "S-C" -- course [label="n",len=1.00]; label = "\n\nEntity Relation Diagram\ndrawn by NEATO";
} </neato>
FDP
Метод «fdp» по сути, близок к методу «neato», и использует другую разновидность «энергетического» («spring») подхода. Также рекомендуется для ненаправленных графов общего типа.
<fdp> graph ER {
node [fontsize=12]; node [shape=box]; course; institute; student; node [shape=ellipse]; {node [label="name"] name0; name1; name2;} code; grade; number; node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I"; name0 -- course; code -- course; course -- "C-I" [label="n",len=1.00]; "C-I" -- institute [label="1",len=1.00]; institute -- name1; institute -- "S-I" [label="1",len=1.00]; "S-I" -- student [label="n",len=1.00]; student -- grade; student -- name2; student -- number; student -- "S-C" [label="m",len=1.00]; "S-C" -- course [label="n",len=1.00]; label = "\n\nEntity Relation Diagram\ndrawn by FDP";
} </fdp>
Twopi
Метод «twopi» рисует графы с радиальной раскладкой. По сути одна вершина выбирается центральной, и помещается в центр, а остальные размещаются на последовательности концентрических орбит, вокруг этой вершины. Т.е. все вершины на расстоянии в «одно ребро» от центра, лежат на первой орбите, «в два ребра» — на второй и т. д.
<twopi> graph ER {
node [fontsize=12]; node [shape=box]; course; institute; student; node [shape=ellipse]; {node [label="name"] name0; name1; name2;} code; grade; number; node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I"; name0 -- course; code -- course; course -- "C-I" [label="n",len=1.00]; "C-I" -- institute [label="1",len=1.00]; institute -- name1; institute -- "S-I" [label="1",len=1.00]; "S-I" -- student [label="n",len=1.00]; student -- grade; student -- name2; student -- number; student -- "S-C" [label="m",len=1.00]; "S-C" -- course [label="n",len=1.00]; label = "\n\nEntity Relation Diagram\ndrawn by TWOPI";
} </twopi>
CIRCO
Метод «circo» использует «circular layout». Выделяются двусвязные компоненты (каждая вершина имеет по крайней мере два ребра) и вершины этих компонент рисуются на некотором круге. «Дополнительные» ребра рисуются радиально и далее процесс повторяется. Пересечение ребер внутри круга минимизируется максимально возможным выносом ребер с круга за его периметр.
<circo> graph ER {
node [fontsize=12]; node [shape=box]; course; institute; student; node [shape=ellipse]; {node [label="name"] name0; name1; name2;} code; grade; number; node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I"; name0 -- course; code -- course; course -- "C-I" [label="n",len=1.00]; "C-I" -- institute [label="1",len=1.00]; institute -- name1; institute -- "S-I" [label="1",len=1.00]; "S-I" -- student [label="n",len=1.00]; student -- grade; student -- name2; student -- number; student -- "S-C" [label="m",len=1.00]; "S-C" -- course [label="n",len=1.00]; label = "\n\nEntity Relation Diagram\ndrawn by CIRCO";
} </circo>
Версии для печати
Как известно, трудно добиться хорошего результата одновременно на экране и на принтере, в силу разных разрешений. Картинка экранного разрешения будет плохо (с «зазубринами») выглядеть на принтере, а картинка печатного разрешения, будет очень плохо выглядеть на экране (к сожалению, современные броузеры выполняют очень примитивный ресайзинг картинок при показе), и будет достаточно много «весить». Все соображения о печатных картинках также относятся к случаю, когда вы переносите (например, копируя вебстраницу из броузера через клипборд) содержимое MediaWiki-статьи в MS Word или другой текстовый редактор. Для такого, «печатного» случая (т. е. если у вас не примитивные графы, и вы собираетесь их печатать или переносить в другую систему верстки), мы сделали «печатную версию» всех перечисленных графов, с разрешением около 200 DPI. Для этого надо использовать те же самые тэги с постфиксом «-print», например «graph-print»,«neato-print», и т.п.:
<graph-print> digraph G{
rankdir=LR; node[color="red",fontsize=14]; edge[color="darkgreen",fontcolor="blue",fontsize=12]; OPEN[shape="rectangle",style="filled",fillcolor="lightgrey"]; CLOSED[shape="octagon",label="Финиш"]; VERIFIED[shape="rectangle",style="rounded"]; OPEN->RESOLVED->VERIFIED->CLOSED; OPEN->CLOSED[style="bold"]; VERIFIED->OPEN[label="обнаружены ошибки",style="dashed",arrowhead="dot"]; }
</graph-print>
Полученные картинки являются компромиссом, между весом, читаемостью на экране и читаемостью на бумаге. Желательно не использовать для совершенно тривиальных графов, или графов, которых вы не собираетесь печатать.
Задание для самостоятельной работы
Используя графвиз отобразите сферу ваших интересов и увлечений.