Лекция 1.6. Графвиз

Материал из Wiki
Версия от 09:15, 15 июня 2009; Admin (обсуждение | вклад) (Цвета и черно-белая печать)
Перейти к:навигация, поиск

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

Для использования Графвиз требуется использовать примитивный язык описания графов dgl. Основные понятия:

  • граф,
  • вершина графа -- элемент множества,
  • ребро графа, соединяющее вершину N с вершиной M

Простейший граф

<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" - нет (Все формы)
  • Ярлык ребра [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-сайта:

<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 позволяет создавать многосекционные узлы при это каждая секция может быть поименована, и тогда ребра можно продоводить между секциями и узлами.

Для включения режима многосекционности устанавливается атрибут узла 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>


Версии для печати

Как известно, трудно добиться хорошего результата одновременно на экране и на принтере, в силу разных разрешений. Картинка экранного разрешения будет плохо (с «зазубринами») выглядеть на принтере, а картинка печатного разрешения, будет очень плохо выглядеть на экране (к сожалению, современные броузеры выполняют очень примитивный ресайзинг картинок при показе), и будет достаточно много «весить». Все соображения о печатных картинках также относятся к случаю, когда вы переносите (например, копируя вебстраницу из броузера через клипборд) содержимое 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>

Полученные картинки являются компромиссом, между весом, читаемостью на экране и читаемостью на бумаге. Желательно не использовать для совершенно тривиальных графов, или графов, которых вы не собираетесь печатать.

Задание для самостоятельной работы

Используя графвиз отобразите сферу ваших интересов и увлечений.