Лекция 1.6. Графвиз — различия между версиями

Материал из Wiki
Перейти к:навигация, поиск
 
(не показаны 94 промежуточные версии 4 участников)
Строка 1: Строка 1:
на выходе будет
+
'''Graphviz''' - набор утилит для графического представления данных.
 +
Программа  принимает описания отношений и элементов множеств, на которых определяется граф, и "добавляет" к этим лишенным всяких геометрических атрибутов описаниям дополнительную информацию, позволяющую "нарисовать" картинку графа.
  
<graph>
+
Для использования Графвиз требуется использовать примитивный язык описания графов dgl.
digraph G{
+
Основные понятия:
Рождение->Юность->Зрелость->Старость->Смерть;
+
* граф,
Юность->Смерть;
+
* вершина графа -- элемент множества,
Зрелость->Смерть;
+
* ребро графа, соединяющее вершину N с вершиной M
}
 
</graph>
 
  
 
+
== Быстрый старт ==
'''Graphviz''' — это разработанный специалистами лаборатории AT&T пакет утилит по автоматической визуализации графов, заданных в виде текстового описания. Пакет распространяется с открытыми исходными файлами и работает на всех операционных системах, включая Windows, Linux/Unix, Mac OS. Самой интересной программой пакета является «dot», автоматический визуализатор направленных графов, который принимает на вход текстовый файл со структурой графа, а на выходе формирует граф в виде графического, векторного или текстового файла.
 
 
= Быстрый старт =
 
<graph>
 
 
 
digraph G{
 
 
 
"Коржуков Валентин Григорьевич" -> "Коржуков Максим Валентинович" [label="отец"];
 
 
 
"Миронова Татьяна Рудольфовна" -> "Коржуков Максим Валентинович" [label="мать"];
 
 
 
}
 
 
 
</graph>
 
  
 
Входной файл для программы «DOT» является обычным текстовым файлом на специальном языке разметки графа. Структура файла очень простая, например,
 
Входной файл для программы «DOT» является обычным текстовым файлом на специальном языке разметки графа. Структура файла очень простая, например,
  
  digraph G{
+
  <nowiki> <graphviz>  
  Рождение->Юность->Зрелость->Старость->Смерть;
 
  Юность->Смерть;
 
  Зрелость->Смерть;
 
}
 
 
 
на выходе будет
 
 
 
<graph>  
 
 
  digraph G{
 
  digraph G{
      Рождение->Юность->Зрелость->Старость->Смерть;
+
Рождение->Юность->Зрелость->Старость->Смерть;
      Юность->Смерть;
+
Юность->Смерть;
      Зрелость->Смерть;
+
  Зрелость->Смерть;
  }
 
</graph>
 
 
 
Программа «Dot» сама распознает все связи графа и упорядочит его таким образом, чтобы было наименьшее количество пересечений.
 
 
 
Чтобы использовать «dot»-графы в [[{{SITENAME}}]], используйте следующий синтаксис:
 
 
 
  <nowiki><graph>
 
digraph G{
 
  Рождение->Юность->Зрелость->Старость->Смерть;
 
  Юность->Смерть;
 
  Зрелость->Смерть;
 
 
  }
 
  }
  </graph></nowiki>
+
  </graphviz></nowiki>
  
Если у вас узлы поименованы словосочетаниями, заключите их в кавычки, т. е.
+
на выходе будет:
  
<nowiki><graph>
+
<graphviz>  
 
digraph G{
 
digraph G{
  "Полет фантазии"->"Расход горючего";
+
Рождение->Юность->Зрелость->Старость->Смерть;
}
+
Юность->Смерть;
</graph></nowiki>
+
Зрелость->Смерть;
 +
}
 +
</graphviz>
  
Поздравляем! Теперь вы способны рисовать графы в [[{{SITENAME}}]]. Остальной текст будет посвящен некоторым тонкостям использования [[Graphviz]].
+
Программа «Dot» сама распознает все связи графа и упорядочит его таким образом, чтобы было наименьшее количество пересечений.
  
= Внешний вид графа =
+
Если у вас узлы поименованы словосочетаниями, заключите их в кавычки, например:
«Dot» позволяет изменять внешний вид графа. Например, можно изменять форму фигур (прямоугольники, овалы, круги, параллелограммы, многоугольники), цвет и шрифт текста, цвет фона фигур, стиль стрелок и рамок фигур, подписи стрелок и т. д.
 
Итак, основные объектами являются узлы («node») и ребра («edge»). Для того, чтобы настроить свойства всех узлов или ребер нужно вначале использовать команды
 
node[свойство1="значение1",свойство2="значение2",...]
 
edge[свойство1="значение1",свойство2="значение2",...]
 
Также (в квадратных скобках после описания объекта) можно изменять настройки конкретного узла или ребра. Параметры графа, просто задаются в виде <tt>параметр=значение</tt>.
 
Полезно запомнить параметр «rankdir», он может быть «TB» (top->bottom, параметр по умолчанию), или «LR» (left->right), и определяет, сверху-вниз, или справа-налево, нужно располагать узлы графа. Вот пестрый пример:
 
  
 +
<nowiki> <graphviz>
 
  digraph G{
 
  digraph G{
  rankdir=LR;
+
"Сидоров Пётр Фёдорович" -> "Сидоров Иван Петрович" [label="отец"];
  node[color="red",fontsize=14];
+
"Сидорова Анна Павловна " -> "Сидоров Иван Петрович" [label="мать"];
  edge[color="darkgreen",fontcolor="blue",fontsize=12];
+
  }  
  OPEN[shape="rectangle",style="filled",fillcolor="lightgrey"];
+
</graphviz></nowiki>
  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>
 
<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"; ..}
 
 
 
Например, при использовании следующей конструкции:
 
<nowiki><graph>
 
 
  digraph G{
 
  digraph G{
  node[fontsize=9];
+
  "Сидоров Пётр Фёдорович" -> "Сидоров Иван Петрович" [label="отец"];
  { /* шкала месяцев*/
+
"Сидорова Анна Павловна " -> "Сидоров Иван Петрович" [label="мать"];
    node[shape=plaintext]; /* что бы не было видно рамок */
+
  }  
    edge[color=white] /* что бы не было видно стрелок */
+
  </graphviz>
    "март" -> "июнь" -> "сентябрь" -> "декабрь";
 
  }
 
  { rank = same; "март"; "весна"; "a"; }
 
  { rank = same; "июнь"; "лето";}
 
  { rank = same; "сентябрь"; "осень"; "d"; }
 
  { rank = same; "декабрь"; "зима"; "e"}
 
  "весна" -> "лето" -> "осень" -> "зима" -> "весна"
 
  "a" -> "b" -> "c" -> "d" -> "e" ;
 
  }
 
  </graph></nowiki>
 
  
на выходе получается:
+
==Свойства графа==
<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>
 
  
= Многосекционный узлы =
+
Для того, граф было удобнее просматривать, можно настроить следующие  свойства. Например:
 +
* Направленность графа:
 +
**'''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''' - трапеция; '''octagon''' - восьмиугольник; '''tripleoctagon''' - тройной восьмиугольник ([http://www.graphviz.org/doc/info/shapes.html Все формы])
 +
** '''Ярославль [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" - нет ([http://www.graphviz.org/doc/info/arrows.html Все формы])
 +
* '''Ярлык ребра''' [label="Волга"] - все связи  '''Ярославль -> ... -> Сызрань'''  будут помечены меткой Волга. 
  
Dot позволяет создавать многосекционные узлы при это каждая секция может быть поименована, и тогда ребра можно продоводить между секциями и узлами.
 
  
Для включения режима многосекционности устанавливается атрибут узла shape.
 
shape=record;
 
  
Секции описываются в атрибуте label узла,  с помощью разделителя «|». Для именования секции ее имя указывается в <>. При описание ребра, исходящего или входящего в секцию, секция именуется следующим образом:
+
'''''Пример:'''''
  
  элемент:<имя_секции>
+
  <nowiki><graphviz>
 
+
  digraph G{
Например, из такого описания:
+
graph [bgcolor=Snow2];
 
+
rankdir=LR ; // направление графа слева направо
  digraph structs {
+
node[color="Pink",fontsize=8, fontcolor="blue",style=filled, shape="none"] ;
  rankdir=HR;
+
edge[color="Brown",fontcolor="Green",fontsize=8] ;
  first [shape=record,label="  x1\n all | { x21 | <f0> x22| x23} | x3" ];
+
  Ярославль -> Кострома -> "Нижний Новгород" -> Казань -> Сызрань [dir=both, label="Волга"];
  second [shape=record,label=" x22_1 | x22_2 | x22_3"];
+
"Нижний Новгород" -> Дзержинск [style=dotted, label="Ока",arrowhead="dot" ] ;
  first:<f0> -> second;
+
Казань -> Елабуга [label="Кама", color="Green:blue:red"] ;
 +
Ярославль [shape=Mdiamond], Сызрань [shape=Msquare], Кострома [shape=circle];
 +
"Нижний Новгород" [shape = doublecircle],Казань[shape=hexagon,color=green]
 +
{rank=same; Елабуга Дзержинск Сызрань ;}
 
  }
 
  }
 +
</graphviz></nowiki>
  
Получается следующее:
+
'''''Результат:'''''
  
<graph>
+
<graphviz>
  digraph structs {
+
  digraph G{
  rankdir=HR;
+
graph [bgcolor=Snow2];
  first [shape=record,label=" x1\n all | { x21 | <f0> x22| x23} | x3" ];
+
rankdir=LR ;  
  second [shape=record,label=" x22_1 | x22_2 | x22_3"];
+
node[color="Pink",fontsize=8, fontcolor="blue",style=filled, shape="none"] ;
  first:<f0> -> second;
+
edge[color="Brown",fontcolor="Green",fontsize=8] ;
}
+
Ярославль -> Кострома -> "Нижний Новгород" -> Казань -> Сызрань [dir=both, label="Волга"];
</graph>
+
"Нижний Новгород" -> Дзержинск [style=dotted, label="Ока",arrowhead="dot" ] ;
 
+
  Казань -> Елабуга [label="Кама", color="Green:blue:red"] ;
= Гиперссылки на графах =
+
Ярославль [shape=Mdiamond], Сызрань [shape=Msquare], Кострома [shape=circle];
 
+
"Нижний Новгород" [shape = doublecircle],Казань[shape=hexagon,color=green]
Можно использовать атрибут «URL», задавая относительные или абсолютные гиперссылки для узлов и ребер. Например
+
{rank=same; Елабуга Дзержинск Сызрань ;}
 
 
<nowiki><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></nowiki>
 
 
 
 
 
<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>
 
 
= Кластеры в графах =
 
 
 
Программа «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;
 
  }
 
 
 
<graph>
 
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;
 
  }
 
</graph>
 
 
 
= Цвета и черно-белая печать=
 
Graphviz позволяет использовать широкую цветовую палитру, однако, стоит не забывать, что контрастно выглядящие на цветном мониторе цвета, могут быть совершенно неразличимы после черно-белой печати. После проделанных экспериментов ({{Bug|11015}}), можно рекомендовать следующие палитры цветов (иллюстрированы на цвете ребер графа):
 
 
 
<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>
 
 
 
Полученные картинки являются компромиссом, между весом, читаемостью на экране и читаемостью на бумаге.
 
Желательно не использовать для совершенно тривиальных графов, или графов, которых вы не собираетесь печатать.
 
 
 
 
 
 
 
  
 +
== [http://lib.custis.ru/index.php/Graphviz Побробнее о Graphviz] ==
  
[[Категория:Семинар]]
+
[[Категория:Веб 2.0]]

Текущая версия на 10:00, 19 февраля 2015

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

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

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

Быстрый старт

Входной файл для программы «DOT» является обычным текстовым файлом на специальном языке разметки графа. Структура файла очень простая, например,

 <graphviz> 
 digraph G{
 Рождение->Юность->Зрелость->Старость->Смерть;
 Юность->Смерть;
 Зрелость->Смерть;
 }
 </graphviz>

на выходе будет:

<graphviz> digraph G{ Рождение->Юность->Зрелость->Старость->Смерть; Юность->Смерть; Зрелость->Смерть; } </graphviz>

Программа «Dot» сама распознает все связи графа и упорядочит его таким образом, чтобы было наименьшее количество пересечений.

Если у вас узлы поименованы словосочетаниями, заключите их в кавычки, например:

 <graphviz>
 digraph G{
 "Сидоров Пётр Фёдорович" -> "Сидоров Иван Петрович" [label="отец"];
 "Сидорова Анна Павловна " -> "Сидоров Иван Петрович" [label="мать"];
 } 
 </graphviz>

<graphviz>

digraph G{
"Сидоров Пётр Фёдорович" -> "Сидоров Иван Петрович" [label="отец"];
"Сидорова Анна Павловна " -> "Сидоров Иван Петрович" [label="мать"];
} 
</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 - трапеция; 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>

Побробнее о Graphviz